如何将类作为参数在函数中传递,譬如参数为Tform,可传递Tform1或者Tform2等,然后在函数中实例化。。多谢!

xiaoxuan777 2003-08-21 11:59:25
同上。
...全文
48 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
baguli 2003-08-21
  • 打赏
  • 举报
回复
我写了一个API,应该可以满足你的要求:

function CreateAndShowForm(const AOwner: TComponent; const TfrmClass: TCustomFormClass): TModalResult;
begin
with TfrmClass.Create(AOwner) do
try
Name := ClassName + IntToStr(Handle); //万一需要多次创建,保证窗口名称唯一
Result := ShowModal;
finally
Free;
end;
end;

其中,TCustomFormClass声明如下:
type
TCustomFormClass = class of TCustomForm;
目录 : 第0章 认识Delphi 0-1 前言 0-2 Delphi简介 0-3 进入Delphi7 0-4 退出Delphi 第1章 常用的窗口工具 1-1 窗体(Form) 1-2 代码编辑器(Code Editor) 1-3 代码浏览器(Code Explorer) 1-4 组件面板(Componet Palette) 1-5 对象检视器(Object Inspector) 1-6 快捷工具栏(Speed Menu) 1-7 项目管理器(Project Manager) 1-8 桌面工具栏(Desktops Tollbar) 1-9 图像编辑器(Image Editor) 1-10 对象浏览器(Object TreeView) 1-11 关联选项卡(Digram Page) 第2章 常用的菜单 2-1 File菜单 2-2 Edit菜单 2-3 Search菜单 2-4 View菜单 2-5 Project菜单 2-6 Run菜单 2-7 Tools菜单 2-8 Windows菜单 第3章 集成开发环境的改变 3-1 Delphi集成开民环境介绍 3-2 操作菜单方面的改进 3-2-1 外面方面的改变 3-2-2 内容方面的改变 3-3 对象检视器方面的改进 3-4 组件面板的改进 3-5 代码编辑器的改进 3-6 设计陈列室的改进 3-7 编译信息的显示 3-8 调试器方面的改进 3-8-1 Watch List改进 3-8-2 Debugger选项的改进 3-8-3 Run Parameters对话框的改进 第4章 Delphi Object Pascal的初步印象 4-1 面向对象程序概论 4-1-1 类 4-1-2 对象 4-1-3 继承 4-1-4 封装 4-1-5 信息 4-2 Delphi项目结构及窗体的建立 4-2-1 GUI模式的项目 4-2-2 Console模式的项目 4-3 Object Pascal程序结构 4-3-1 项目程序(Program)的结构 4-3-2 单元程序(Unit)的结构 4-4 如何完成一个简单的窗体程序 第5章 简单的常用指令介绍 5-1 TLabel类对象 5-1-1 Caption属性 5-2 TButton类对象 5-2-1 Caption属笥 5-2-2 OnClick事件 5-3 TEdit类对象 5-4 TCanvas类对象 5-5 Showmessage函数 5-6 InputBox函数 5-7 MessageDlg函灵敏 第6章 Delphi与Object Pascal程序的基本概念 6-1 Object Pascal Program程序结构与Delphi项目结构的关系 6-1-1 标头(Heading) 6-1-2 Uses子句 6-1-3 编译指令(Compiler directive) 6-1-4 源代码区(begin end) 6-2 Unit程序结构与窗体的关系 6-2-1 Unit代码结构 6-2-2 语句(Statement) 6-2-3 Unit间Use的状况 6-3 数据类型与定义变量 6-3-1 数据类型概论 6-3-2 不需要使用type声明的数据类型 6-3-3 必须使用type声明的数据类型 6-3-4 定义变量 6-3-5 变量的作用域 6-3-6 定义常量 6-3-7 变量的类型转换(Typecast) 6-4 Object Pascal的运算符(Operator) 6-4-1 设置运算符(assign Operator) 6-4-2 算数运算符(Arithmetic Operator) 6-4-3 关系运算符(Relational Operator) 6-4-4 布尔运算符 6-4-5 集合运算符 6-4-6 字符串运算符 6-4-7 位逻辑运算符 6-4-8 运算符优先级 6-5 流程控制 6-5-1 语句的基本概念 6-5-2 表达式语句(Expression-Statement) 6-5-3 流程控制语句 6-5-4 可视化程序与嵌套程序 6-6 数组与指针 6-6-1 数组类型 6-6-2 指针类型 6-6-3 浅谈指针与数据结构 6-7 程序与函数(Procedures and Functions) 6-7-1 函数的意义与优点 6-7-2 函数的分类与效用 6-7-3 自定义函数使用方法概述 6-7-4 函数的声明、定义及其实现 6-7-5 参数传递方式 6-7-6 声明修饰字 6-7-7 常用的内建函数 第7章 Object Pascal面向对象设计 7-1 类和对象 7-1-1 类(Class)与对象(Object)的基本概念 7-1-2 对象的构造与类的关系 7-2 类的声明与对象的定义 7-2-1 类的声明与对象的实现 7-2-2 对象的构造与析构 7-3 类成员的封装等级与可见度 7-3-1 封装的意义 7-3-2 Object Pascal类成员的封装等级 7-3-3 以实例说明类成员封装等级的可见度 7-3-4 开头不加保留字的类成员 7-3-5 成员封装等级的变更法则 7-4 类成员的定义与实现 7-4-1 字段(Field)与对象引用(Object Reference)的实现 7-4-2 方法(Method) 7-4-3 属性(Property) 7-5 类的继承 7-5-1 继承的意义与优点 7-5-2 子类成员的存在方式 7-6 成员函数的Override及 Overload 7-6-1 Override 适用的情况——Virtual与 Dynamic的成员函数 7-6-2 Override成员函数的定义语法 7-6-3 Virtual成员函数与动态绑定(Dynamic Binding) 7-6-4 覆盖(Overriding)与隐藏(Hiding)的差别 7-6-5 Override与OVerload的差别 7-7 Abstract成员函数与多态(Polymorphic) 7-7-1 一般纯虚函数的多态实现概念 7-7-2 纯虚函数的定义语法及实现 7-8 Self、AS、is、Sender、Parent、owner、inerited 7-8-1 Self变量 7-8-2 AS运算符 7-8-3 is运算符 7-8-4 Sender 7-8-5 Parent 7-8-6 owner 7-8-7 inerited保留字 7-9 静态成员方法——Class Methods 第8章 异常处理 8-1 异常处理存在的目的 8-2 Object Pascal异常的种类 8-2-1 Delphi内建的异常类 8-2-2 自定义异常类 8-3 触发异常的方法 8-3-1 由程序系统自动触发 8-3-2 使用Raise指令触发 8-4 处理异常情况 8-4-1 try…finally…end语法说明 8-4-2 ty…except…end语法说明 第9章 Delphi用户接口设计详述 9-1 基本概念 9-2 TForm的属性 9-2-1 由TComponent继承而来的属性 9-2-2 由TControl继承而来的属性 9-2-3 由TWinControl继承而来的属性 9-2-4 由TScrollingWindControl继承而来的属性 9-2-5 由TCustomForm继承而来的属性 9-3 TForm的方法 9-3-1 由TObject继承而来的属性 9-3-2 由TPersistent继承而来的属性 9-3-3 由TComponent继承而来的属性 9-3-4 由TControl继承而来的属性 9-3-5 由WinControl继承而来的属性 9-3-6 由TScrollingWinControl继承而来的属性 9-3-7 由TCustomForm继承而来的属性 9-3-8 由TForm继承而来的属性 9-4 TForm的事件 9-4-1 由TControl继承而来的属性 9-4-2 由TWinControl继承而来的属性 9-4-3 由TCustomForm继承而来的属性 9-5 TLabel的类成员 9-5-1 TLabel的属性 9-5-2 TLabel的方法 第10章 标准组件介绍及实作范例 10-1 Frames组件 10-2 MainMenu组件 10-3 PopuMenu组件 10-4 Label组件 10-5 Edit组件 10-6 Memo组件 10-7 Button组件 10-8 CheckBox组件 10-9 RadioButton组件 10-10 ListBox组件 10-11 ComboBox组件 10-12 ScrollBar组件 10-13 GroupBox组件 10-14 RadioGroup组件 10-15 Panel组件 10-16 ActionList组件 第11章 TApplication与TScreen类介绍及应用 11-1 TApplication类 11-1-1 TApplication类对象常用的属性 11-1-2 TApplication类对象常用的方法 11-2 TScreen类 第12章 高级组件介绍 12-1 Additional选项卡的常用组件 12-1-1 TBitBtn组件 12-1-2 TMaskEdit组件 12-1-3 TImage组件 12-1-4 TShape组件 12-2 Win32选项卡的常用组件 12-2-1 TPageControl组件 12-2-2 TImageList组件 12-2-3 TRichEdit组件 12-2-4 TDateTimePicker组件 12-2-5 TStatusBar组件 12-3 System选项卡的常用组件 12-3-1 TTimer组件 12-4 Dialogs选项卡的常用组件 12-4-1 TOpenDialog组件 12-4-2 FTontDialog组件 12-4-3 TColorDialog组件 第13章 封装Delphi7开发的应用程序 13-1 安装Borland的InstallShiled程序 13-2 利用InstallShield封装 Delphi7开发的程序 13-2-1 InstallShield环境界面简介 13-2-2 封装一个简单的Delphi项目 第14章 数据库概念及SQL指令介绍 14-1 数据库基本概念 14-1-1 数据库结构 14-1-2 开放数据库连接协议(ODBC) 14-1-3 SQL Explorer 14-2 结构化查询语言SQL 14-2-1 CREATE语句 14-2-2 ALTER TABLE语句 14-2-3 DROP语句 14-2-4 SELECT语句 14-2-5 INSERT、UPDATE语句 14-2-6 DELETE语句 14-3 SQL指令高级使用 14-3-1 UNION运算 14-3-2 JOIN运算 14-3-3 特殊运算符 14-3-4 子查询(Sub Query) 第15章 Delphi数据库程序基础 15-1 Delphi各种数据库连接设置 15-1-1 建立dBase、Paradox连接 15-1-2 建立Access连接 15-1-3 建立MSSQL连接 15-1-4 建立MySQL连接 15-2 Delphi的Database Desktop使用方法 15-2-1 字段定义 15-2-2 输入数据 15-2-3 设置BDE数据库别名与连接数据库 第16章 Delphi数据库程序设计——使用BDE组件 16-1 TDataSet组件 16-1-1 TDataSet组件常用的属性 16-1-2 TDataSet组件常用的方法 16-1-3 TDataSet组件常用的事件 16-2 TTable组件 16-2-1 TTable组件常用的属性 16-2-2 TTable组件常用的方法 16-3 TQuery组件 16-3-1 TQuery组件常用的属性 16-3-2 TQuery组件常用的方法 16-4 TDataModule组件 16-5 TDatabase组件 16-5-1 TDatabase组件常用的属性 16-5-2 TDatabase组件常用的方法 16-5-3 TDatabase组件常用的事件 16-6 综合范例 16-6-1 员工管理系统——使用TTable组件 16-6-2 员工管理系统——使用TQuery组件 16-6-3 订单管理系统——使用TTable组件 16-6-4 订单系统——使用TQuery组件 第17章 数据程序设计——使用Delphi组件 17-1 TADOConnection组件 17-1-1 TADOConnection组件常用的属性 17-1-2 TADOConnection组件常用的方法 17-1-3 TADOConnection组件常用的事件 17-2 TADOCommand组件 17-2-1 TADOCommand组件常用的属性 17-2-2 TADOCommand组件常用的方法 17-3 TADODataSet组件 17-3-1 TADODataSet组件常用的属性 17-3-2 TADODataSet组件常用的方法 17-3-3 TADODataSet组件常用的事件 17-4 TADOTable组件 17-4-1 TADOTable组件常用的属性 17-4-2 TADOTable组件常用的方法 17-5 TADOQuery组件 17-6 综合范例 17-6-1 客户管理系统——使用TADODataSet组件 17-6-2 客户管理系统——使用TADOTable组件 17-6-3 客户管理系统——使用TADOQuery组件 17-6-4 订单管理系统——使用TADOTable组件 17-6-5 订单系统——使用TADOQuery组件 第18章 数据感知组件 18-1 TDBText组件 18-2 TDBEdit组件 18-3 TDBMemo组件 18-4 TDBImage组件 18-5 TDBListBox组件 18-6 TDBComboBox组件 18-7 TDBLookupListBox与TDBLookupComboBox组件 18-8 TDBNavigator组件 18-9 TDBGrid组件 第19章 设计Delphi数据库报表 19-1 设计报表的基本观念 19-1-1 报表的组成 19-1-2 报表的主体组件——TquickRep 19-1-3 建立第一个报表程序 19-2 QuickReport可打印出组件 19-2-1 TQR系列组件介绍 19-2-2 TQRDB系列组件介绍 19-3 综合范例 19-3-1 一般表达报表范例 19-3-2 标签式报表范例 19-3-3 主/明细报表范例 19-3-4 一般表达式附图片报表范例 19-3-5 分组式报表范例——打印多色报表 19-3-6 报表输出及输出范例
您查询的关键词是:delphi 同步 数据 。如果打开速度慢,可以尝试快速版;如果想保存快照,可以添加到搜藏。 (百度和网页http://blog.csdn.net/mygodsos/archive/2008/10/19/3097921.aspx的作者无关,不对其内容负责。百度快照谨为网络故障时之索引,不代表被搜索网站的即时页面。) -------------------------------------------------------------------------------- 发呆茶馆 登录 注册 欢迎 退出 我的博客 配置 写文章 文章管理 博客首页 全站 当前博客 空间 博客 好友 相册 留言 用户操作 [发私信] [加为好友] mygodsos 订阅我的博客 mygodsos的公告 文章分类 Delphi Delphi学习--多线程 Delphi学习--自创的常用函数 期货大事记 生活感悟 投资理财 编程学习 万一的Delphi博客 存档 2009年05月(3) 2008年11月(13) 2008年10月(8) 2008年09月(3) ◆Delphi多线程编程之三 同步读写全局数据 ◆(乌龙哈里2008-10-12) 收藏 ◆Delphi多线程编程之三同步读写全局数据 ◆(乌龙哈里2008-10-12) (调试环境:Delphi2007+WinXPsp3 例程:Tst_Thread3.dpr) 开始研究最重要的多线程读写全局数据了,结合书上的例子,我修改成下面的情况: unit Tst_Thread3U; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Button2: TButton; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private procedure ThreadsDone(Sender: TObject); end; TMyThread=class(TThread) protected procedure Execute;override; end; var Form1: TForm1; implementation {$R *.dfm} const MaxSize=128; var NextNumber:Integer=0; DoneFlags:Integer=0; GlobalArry:array[1..MaxSize] of Integer; Lock:byte; //1-不同步 2-临界区 3-互斥 CS:TRTLCriticalSection; //临界区 hMutex:THandle; //互斥 function GetNextNumber:Integer; begin Result:=NextNumber; inc(NextNumber); end; procedure TMyThread.Execute; var i:Integer; begin FreeOnTerminate:=True; //终止后自动free OnTerminate:=Form1.ThreadsDone; if Lock3 then //非互斥情况 begin if Lock=2 then EnterCriticalSection(CS); //建立临界区 for i := 1 to MaxSize do begin GlobalArry[i]:=GetNextNumber; Sleep(5); end; if Lock=2 then LeaveCriticalSection(CS);//离开临界区 end else //-------互斥 begin if WaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0 then begin for i := 1 to MaxSize do begin GlobalArry[i]:=GetNextNumber; Sleep(5); end; end; ReleaseMutex(hMutex); //释放 end; end; procedure TForm1.ThreadsDone(Sender: TObject); var i:Integer; begin Inc(DoneFlags); if DoneFlags=2 then begin for i := 1 to MaxSize do Memo1.Lines.Add(inttostr(GlobalArry[i])); if Lock=2 then DeleteCriticalSection(CS); //删除临界区 If Lock=3 then CloseHandle(hMutex); //关闭互斥 end; end; //非同步 procedure TForm1.Button1Click(Sender: TObject); begin Lock:=1; TMyThread.Create(False); TMyThread.Create(False); end; //临界区 procedure TForm1.Button2Click(Sender: TObject); begin Lock:=2; InitializeCriticalSection(CS); //初始化临界区 TMyThread.Create(False); TMyThread.Create(False); end; //互斥 procedure TForm1.Button3Click(Sender: TObject); begin Lock:=3; // 互斥 hMutex:=CreateMutex(0,False,nil); TMyThread.Create(False); TMyThread.Create(False); end; end. 没有临界区和互斥的帮助,两个线程都不断地在Memo1输出,而且数字是乱的。 一、临界区 所谓临界区,就是一次只能由一个线程来执行的一段代码。如果把初始化数组的代码放在临界区内,另一个线程在第一个线程处理完之前是不会被执行的。 使用临界区的步骤: 1、先声明一个全局变量类型为TRTLCriticalSection; 2、在线程Create()前调用InitializeCriticalSection()过程来初始化,该函数定义是: void WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 类型lpCriticalSection即是Delphi封装的TRTLCriticalSection。 3、在线程的需要放入临界区的代码前面使用EnterCriticalSection(lpCriticalSection)过程来开始建立临界区。在代码完成后用LeaveCriticalSection(lpCriticalSection)来标志临界区的结束。 4、在线程执行完后用DeleteCriticalSection(lpCriticalSection)来清除临界区。这个清除过程必须放在线程执行完后的地方,比如FormDesroy事件。上面的例子,若把该过程放在TMyThread.Create(False);后,会产生错误。 二、互斥: 互斥非常类似于临界区,除了两个关键的区别:首先,互斥可用于跨进程的线程同步。其次,互斥能被赋予一个字符串名字,并且通过引用此名字创建现有互斥对象的附加句柄。 提示临界区与事件对象(比如互斥对象)的最大的区别是在性能上。临界区在没有线程冲突时,要用10~15个时间片,而事件对象由于涉及到系统内核要用400~600个时间片。 使用互斥的步骤: 1、声明一个类型为Thandle或Hwnd的全局变量,其实都是Cardinal类型。Hwnd是handle of window,主要用于窗口句柄;而Thandle则没有限制。 2、线程Create()前用CreateMutex()来创建一个互斥量。该函数定义为: HANDLE WINAPI CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName:Pchar); LPSECURITY_ATTRIBUTES参数为一个指向TSecurityAttributtes记录的指针。此参数设为nil,表示访问控制列表默认的安全属性。 bInitalOwner参数表示创建互斥对象的线程是否要成为此互斥对象的拥有者。当此参数为False时,表示互斥对象没有拥有者。 lpName参数指定互斥对象的名称。设为nil表示无命名,如果参数不是设为nil,函数会搜索是否有同名的互斥对象存在。如果有,函数就会返回同名互斥对象的句柄。否则,就新创建一个互斥对象并返回其句柄。 返回值是一handle。当错误发生时,返回null,此时用GetLastError函数可查看错误的信息。 利用CreateMutex()可以防止程序多个实例运行,如下例: Program ABC; Uses Forms,Windows,…; {$R *.res} Var hMutex:Hwnd; Begin Application.Initialize; hMutex:=CreateMutex(nil,False,Pchar(Application.Title)); if GetLastErrorERROR_ALREADY_EXISTS then begin //项目要运行的咚咚 end; ReleaseMutex(hMutex); Application.Run; End; 在本节的例程,我们只是要防止线程进入同步代码区域,所以lpName参数设置为nil。 3、在同步代码前用WaitForSingleObject()函数。该函数使得线程取得互斥对象(同步代码)的拥有权。该函数定义为: DWORD WINAPI WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds); 这个函数可以使当前线程在dwMilliseconds指定的时间内睡眠,直到hHandle参数指定的对象进入发信号状态为止。一个互斥对象不再被线程拥有时,它就进入发信号状态。当一个进程要终止时,它就进入发信号状态。dwMilliseconds参数可以设为0,这意味着只检查hHandle参数指定的对象是否处于发信号状态,而后立即返回。dwMilliseconds参数设为INFINITE,表示如果信号不出现将一直等下去。 这个函数的返回值含义: WAIT_ABANDONED 指定的对象是互斥对象,并且拥有这个互斥对象的线程在没有释放此对象之前就已终止。此时就称互斥对象被抛弃。这种情况下,这个互斥对象归当前线程所有,并把它设为非发信号状态 WAIT_OBJECT_0 指定的对象处于发信号状态 WAIT_TIMEOUT 等待的时间已过,对象仍然是非发信号状态 再次声明,当一个互斥对象不再被一个线程所拥有,它就处于发信号状态。此时首先调用WaitForSingleObject()函数的线程就成为该互斥对象的拥有者,此互斥对象设为不发信号状态。当线程调用ReleaseMutex()函数传递一个互斥对象的句柄作为参数时,这种拥有关系就被解除,互斥对象重新进入发信号状态。 注意除WaitForSingleObject()函数外,你还可以使用WaitForMultipleObject()和MsgWaitForMultipleObject()函数,它们可以等待几个对象变为发信号状态。这两个函数的详细情况请看Win32 API联机文档。 4、在同步代码结束后,使用ReleaseMutex(THandle)函数来标志。该函数只是释放互斥对象和线程的拥有者关系,并不释放互斥对象的句柄。 5、调用CloseHandle(THandle)来关闭互斥对象。请注意例程函数的使用位置。 三、还有一种用信号量对象来管理线程同步的,它是在互斥的基础上建立的,但信号量增加了资源计数的功能,预定数目的线程允许同时进入要同步的代码。有点复杂,想不到在哪可以用,现在就不研究论了。 发表于 @ 2008年10月19日 00:47:00 | 评论( loading... ) | 编辑| 举报| 收藏 旧一篇:◆delphi多线程编程之二 ◆(乌龙哈里2008-10-12) | 新一篇:◆Delphi多线程编程之四 线程安全和VCL ◆(乌龙哈里2008-10-12)Csdn Blog version 3.1a Copyright © mygodsos
一、临界区 所谓临界区,就是一次只能由一个线程来执行的一段代码。如果把初始化数组的代码放在临界区内,另一个线程在第一个线程处理完之前是不会被执行的。 使用临界区的步骤: 1、先声明一个全局变量类型为TRTLCriticalSection; 2、在线程Create()前调用InitializeCriticalSection()过程来初始化,该函数定义是: void WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); 类型lpCriticalSection即是Delphi封装的TRTLCriticalSection。 3、在线程的需要放入临界区的代码前面使用EnterCriticalSection(lpCriticalSection)过程来开始建立临界区。在代码完成后用LeaveCriticalSection(lpCriticalSection)来标志临界区的结束。 4、在线程执行完后用DeleteCriticalSection(lpCriticalSection)来清除临界区。这个清除过程必须放在线程执行完后的地方,比如FormDesroy事件。上面的例子,若把该过程放在TMyThread.Create(False);后,会产生错误。 二、互斥: 互斥非常类似于临界区,除了两个关键的区别:首先,互斥可用于跨进程的线程同步。其次,互斥能被赋予一个字符串名字,并且通过引用此名字创建现有互斥对象的附加句柄。 提示临界区与事件对象(比如互斥对象)的最大的区别是在性能上。临界区在没有线程冲突时,要用10~15个时间片,而事件对象由于涉及到系统内核要用400~600个时间片。 使用互斥的步骤: 1、声明一个类型为Thandle或Hwnd的全局变量,其实都是Cardinal类型。Hwnd是handle of window,主要用于窗口句柄;而Thandle则没有限制。 2、线程Create()前用CreateMutex()来创建一个互斥量。该函数定义为: HANDLE WINAPI CreateMutex( LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCTSTR lpName:Pchar); LPSECURITY_ATTRIBUTES参数为一个指向TSecurityAttributtes记录的指针。此参数设为nil,表示访问控制列表默认的安全属性。 bInitalOwner参数表示创建互斥对象的线程是否要成为此互斥对象的拥有者。当此参数为False时,表示互斥对象没有拥有者。 lpName参数指定互斥对象的名称。设为nil表示无命名,如果参数不是设为nil,函数会搜索是否有同名的互斥对象存在。如果有,函数就会返回同名互斥对象的句柄。否则,就新创建一个互斥对象并返回其句柄。 返回值是一handle。当错误发生时,返回null,此时用GetLastError函数可查看错误的信息。 利用CreateMutex()可以防止程序多个实例运行,如下例: Program ABC; Uses Forms,Windows,…; {$R *.res} Var hMutex:Hwnd; Begin Application.Initialize; hMutex:=CreateMutex(nil,False,Pchar(Application.Title)); if GetLastErrorERROR_ALREADY_EXISTS then begin //项目要运行的咚咚 end; ReleaseMutex(hMutex); Application.Run; End; 在本节的例程,我们只是要防止线程进入同步代码区域,所以lpName参数设置为nil。 3、在同步代码前用WaitForSingleObject()函数。该函数使得线程取得互斥对象(同步代码)的拥有权。该函数定义为: DWORD WINAPI WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds); 这个函数可以使当前线程在dwMilliseconds指定的时间内睡眠,直到hHandle参数指定的对象进入发信号状态为止。一个互斥对象不再被线程拥有时,它就进入发信号状态。当一个进程要终止时,它就进入发信号状态。dwMilliseconds参数可以设为0,这意味着只检查hHandle参数指定的对象是否处于发信号状态,而后立即返回。dwMilliseconds参数设为INFINITE,表示如果信号不出现将一直等下去。 这个函数的返回值含义: WAIT_ABANDONED 指定的对象是互斥对象,并且拥有这个互斥对象的线程在没有释放此对象之前就已终止。此时就称互斥对象被抛弃。这种情况下,这个互斥对象归当前线程所有,并把它设为非发信号状态 WAIT_OBJECT_0 指定的对象处于发信号状态 WAIT_TIMEOUT 等待的时间已过,对象仍然是非发信号状态 再次声明,当一个互斥对象不再被一个线程所拥有,它就处于发信号状态。此时首先调用WaitForSingleObject()函数的线程就成为该互斥对象的拥有者,此互斥对象设为不发信号状态。当线程调用ReleaseMutex()函数传递一个互斥对象的句柄作为参数时,这种拥有关系就被解除,互斥对象重新进入发信号状态。 注意除WaitForSingleObject()函数外,你还可以使用WaitForMultipleObject()和MsgWaitForMultipleObject()函数,它们可以等待几个对象变为发信号状态。这两个函数的详细情况请看Win32 API联机文档。 4、在同步代码结束后,使用ReleaseMutex(THandle)函数来标志。该函数只是释放互斥对象和线程的拥有者关系,并不释放互斥对象的句柄。 5、调用CloseHandle(THandle)来关闭互斥对象。请注意例程函数的使用位置。 三、还有一种用信号量对象来管理线程同步的,它是在互斥的基础上建立的,但信号量增加了资源计数的功能,预定数目的线程允许同时进入要同步的代码。有点复杂,想不到在哪可以用,现在就不研究论了。 unit Tst_Thread3U; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; Memo1: TMemo; Button2: TButton; Button3: TButton; procedure Button1Click(Sender: TObject); procedure Button2Click(Sender: TObject); procedure Button3Click(Sender: TObject); private procedure ThreadsDone(Sender: TObject); end; TMyThread=class(TThread) protected procedure Execute;override; end; var Form1: TForm1; implementation {$R *.dfm} const MaxSize=128; var NextNumber:Integer=0; DoneFlags:Integer=0; GlobalArry:array[1..MaxSize] of Integer; Lock:byte; //1-不同步 2-临界区 3-互斥 CS:TRTLCriticalSection; //临界区 hMutex:THandle; //互斥 function GetNextNumber:Integer; begin Result:=NextNumber; inc(NextNumber); end; procedure TMyThread.Execute; var i:Integer; begin FreeOnTerminate:=True; //终止后自动free OnTerminate:=Form1.ThreadsDone; if Lock3 then //非互斥情况 begin if Lock=2 then EnterCriticalSection(CS); //建立临界区 for i := 1 to MaxSize do begin GlobalArry[i]:=GetNextNumber; Sleep(5); end; if Lock=2 then LeaveCriticalSection(CS);//离开临界区 end else //-------互斥 begin if WaitForSingleObject(hMutex,INFINITE)=WAIT_OBJECT_0 then begin for i := 1 to MaxSize do begin GlobalArry[i]:=GetNextNumber; Sleep(5); end; end; ReleaseMutex(hMutex); //释放 end; end; procedure TForm1.ThreadsDone(Sender: TObject); var i:Integer; begin Inc(DoneFlags); if DoneFlags=2 then begin for i := 1 to MaxSize do Memo1.Lines.Add(inttostr(GlobalArry[i])); if Lock=2 then DeleteCriticalSection(CS); //删除临界区 If Lock=3 then CloseHandle(hMutex); //关闭互斥 end; end; //非同步 procedure TForm1.Button1Click(Sender: TObject); begin Lock:=1; TMyThread.Create(False); TMyThread.Create(False); end; //临界区 procedure TForm1.Button2Click(Sender: TObject); begin Lock:=2; InitializeCriticalSection(CS); //初始化临界区 TMyThread.Create(False); TMyThread.Create(False); end; //互斥 procedure TForm1.Button3Click(Sender: TObject); begin Lock:=3; // 互斥 hMutex:=CreateMutex(0,False,nil); TMyThread.Create(False); TMyThread.Create(False); end; end.
内联函数(Inlining) D7的inline关键字作为保留字并不会对编译器产生实际作用,在2009此关键字起到内嵌到代码起到实际作用。语法如下: function foo: Integer; inline; 内部函数/过程也可以使用,但在D2009测试版,类方法的内部函数使用inline后不认Self指针;类的子过程/子函数,也可以使用inline关键字,但没有实际效果,且虚方法/继承方法(virtual/override)不能使用。 重载运算符(Operator Overloading) 可以重载部分运算符,如+、-、类型转换等,在D2006只支持到record,但从2007开始支持到Class,以下示例修改自官网: TMyClass = class // Addition of two operands of type TMyClass class operator Add(a, b: TMyClass): TMyClass; // Subtraction of type TMyClass class operator Subtract(a, b: TMyClass): TMyclass; // Implicit conversion of an Integer to type TMyClass class operator Implicit(a: Integer): TMyClass; // Implicit conversion of TMyClass to Integer class operator Implicit(a: TMyClass): Integer; // Explicit conversion of a Double to TMyClass class operator Explicit(a: Double): TMyClass; end; class operator TMyClass.Add(a, b: TMyClass): TMyClass; begin //... end; var x, y: TMyClass begin x := 12; // Implicit conversion from an Integer y := x + x; // Calls TMyClass.Add(a, b: TMyClass): TMyClass end; 类助手(Class Helpers) Helper是对原Class的扩展,是我们在不修改原类的基础上增加类方法,并加入原类的空间。在Delphi,对对象的调用实际上采用了两个步骤,首先是把对象地址放入eax寄存器,然后call类方法,所以如果不使用继承类增加数据的话,用父类调用继承类的方法是没问题的,所以其实这样的方法在D7也可以使用,但却很麻烦。所以Class Helper起到的就是这个作用,在Class Helper可以增加的就是与实例无关的内容,所以任何需要增加实例Size的活VMT的功能不能声明,例如变量、虚方法等,但只占用类空间的没关系,如class var。在应用上我们可以通过这种方法方便的给VCL一类控件加上某个属性。 TFoo = class helper for TControl private function GetA: Integer; public class var X: Integer; procedure MSG(var Message: TMessage); message WM_MYMESSAGE; procedure ProcFoo; property A: Integer read GetA; end; // ... procedure TForm1.Foofoo; begin ProcFoo; // TControl -> TWinControl -> TScrollingWinControl-> TCustomForm -> TForm -> TFrom1: Call TFoo.ProcFoo end; strict关键字(Keyword “strict”) 众所周知,在Delphi,类的private和protected域的变量可以被同一单元可以自由的被访问(Delphi的类没有“友元”的概念,但同一个unit可以说自动友元化了),而并非是真正的私有或只能被继承类访问。而strict关键字的作用就是使该内容变成严格OO意义上的private/protected作用域,这点没有什么多说的。语法: strict private // Blah... strict protected // Blah... 结构方法(Records with Methods) 也没什么特别的,就是和class差不多,就一个不用创建和销毁、不能继承、没有作用域之类的类,很容易掌握,所以这里就不多介绍了。但是很有意思的是带参数的constructor可以通过编译,可能是为了初始化的方便吧。 抽象类和固实类(Abstract and Sealed Classes) 这两个概念在OO也并不陌生,抽象类是不应该创建实例的(但D2006起的编译器就不给检查,连个Warning都没有,这还有啥用啊 -.- ),而固实类是不能被继承的。语法: TAnAbstractClass = class abstract // or (TParentClass) // Blah... end; TASealedClass = class sealed(TAnAbstractClass) // or empty // Blah... end; 类常量、类变量、类属性与静态类方法(Class const/var/property and Static Class Methods) 老的Delphi只提供了类方法,而没有提供类变量、类常量和类属性,这真的是很不方便。这里先区分一下我所使用的类(Class)和对象(Object)即类的实例(Instance of Class)。当在Delphi声明一个类的时候,这个类是有实际地址的,该地址记录了许多类的相关信息,比如实例的Size啊、虚方法信息啊一堆东西,而创建一个对象的时候则把类实例化,在堆(Heap)分配一块地址,包括内部数据和VMT之类的东西。在调用实例的时候,首先要知道对象地址,然后才能访问内部变量和调用方法时使用Self指针即实例地址;而在调用类方法的时候,eax的并不是实例的地址而是类的地址,然后再call方法,这时的Self指针并非实例地址而是类地址。所以对于每一个类和继承类来说,包括它和它的继承类的所有实例,类变量、常量都是同一个,这样就存在了一个唯一的可供使用的变量或常量,方便同步并且不需要使用较多的内存(可以参考C#的类,不过C#不允许从实例直接访问类变量、常量、方法)。而静态类方法则是在使用这个类方法的时候不传入class地址,也就是说没有Self指针,这样的类方法的访问开销要小于普通的类方法;这自然也就意味着,该类方法不能被继承(不能virtual/override)。另外,类属性的get/set方法必须使用静态类方法。 TFooClass = class private class procedure SetFoo(const Value: Integer); static; // A Static Class Method protected class var FX : Integer; // class var public const FC: Integer = 10; // class const class procedure VirtualProc; virtual; class property X: Integer read FX write FX; // class property class property Foo: Integer read FC write SetFoo; end; 类内部类型与嵌套类(Class Types and Nested Classes) 可以说现在的Class的域几乎相当于原来的整个unit,以前不能放里面的元素现在都可以放里面了,这个也没什么好多说的,试验一下就很容易明白了。 终方法(Final Methods) 这个也是建立在虚方法的基础上的,在override后使用final关键字,则表示该虚方法不能再被子类继承下去了。 TAClass = class public procedure Foo; virtual; end; TFinalMethodClass = class(TAClass) public procedure Test; override; final; // A Final Method end; For-in循环(For-in Loop) 这个应该是受.Net影响吧,支持遍历一个数组或提供了GetEnumerator函数的类。GetEnumerator要求返回一个类的实例,该类包含有Current属性和MoveNext方法。 procedure Foo(List: TStrings); i : Integer; lst : array[0..100]of Integer; s : string; begin for i in lst do ; for s in List do ; // Support of TStrings.GetEnumerator end;

文名称:Delphi 7完美经典

http://www.huachu.com.cn/photo/2003/BB04672130c.jpg

出版社 : 国铁道出版社
作者  : 江义华/
出版日期: 2003年7月
综合评价:
国标编号:ISBN 7-113-05241-X/TP.931
条形码 :9787113052416
字数  :989千字  
印张  :41.75
印数  :1-5000   
页数  :654
开本  :787*1092 1/16
版别版次:2003年7月第一版第一次印刷
内容简介:
本书特色
层次清晰、语言通俗、语法简练、以实用性为第一位。
深入剖析了Object Pascal程序语言,包括指针、数据结构以及有关Override 和Overload函数的语法等。
对面向对象的观点详述了Delphi VCL组件的属性、方法及事件,且在数据库设计方面辅以应用的范例。
实例配有光盘,快速引导您踏入Delphi程序开发领域。
适合想要深入了解Delphi程序设计的专业设计师,对一开始就想打好Delphi程序设计基础的初学者也非常适用。

目录 :
第0章 认识Delphi

0-1 前言
0-2 Delphi简介
0-3 进入Delphi7
0-4 退出Delphi

第1章 常用的窗口工具

1-1 窗体(Form
1-2 代码编辑器(Code Editor)
1-3 代码浏览器(Code Explorer)
1-4 组件面板(Componet Palette)
1-5 对象检视器(Object Inspector)
1-6 快捷工具栏(Speed Menu)
1-7 项目管理器(Project Manager)
1-8 桌面工具栏(Desktops Tollbar)
1-9 图像编辑器(Image Editor)
1-10 对象浏览器(Object TreeView)
1-11 关联选项卡(Digram Page)

第2章 常用的菜单

2-1 File菜单
2-2 Edit菜单
2-3 Search菜单
2-4 View菜单
2-5 Project菜单
2-6 Run菜单
2-7 Tools菜单
2-8 Windows菜单

第3章 集成开发环境的改变

3-1 Delphi集成开民环境介绍
3-2 操作菜单方面的改进
3-2-1 外面方面的改变
3-2-2 内容方面的改变
3-3 对象检视器方面的改进
3-4 组件面板的改进
3-5 代码编辑器的改进
3-6 设计陈列室的改进
3-7 编译信息的显示
3-8 调试器方面的改进
3-8-1 Watch List改进
3-8-2 Debugger选项的改进
3-8-3 Run Parameters对话框的改进

第4章 Delphi Object Pascal的初步印象

4-1 面向对象程序概论
4-1-1 类
4-1-2 对象
4-1-3 继承
4-1-4 封装
4-1-5 信息
4-2 Delphi项目结构及窗体的建立
4-2-1 GUI模式的项目
4-2-2 Console模式的项目
4-3 Object Pascal程序结构
4-3-1 项目程序(Program)的结构
4-3-2 单元程序(Unit)的结构
4-4 如何完成一个简单的窗体程序

第5章 简单的常用指令介绍

5-1 TLabel类对象
5-1-1 Caption属性
5-2 TButton类对象
5-2-1 Caption属笥
5-2-2 OnClick事件
5-3 TEdit类对象
5-4 TCanvas类对象
5-5 Showmessage函数
5-6 InputBox函数
5-7 MessageDlg函灵敏

第6章 Delphi与Object Pascal程序的基本概念

6-1 Object Pascal Program程序结构与Delphi项目结构的关系
6-1-1 标头(Heading)
6-1-2 Uses子句
6-1-3 编译指令(Compiler directive)
6-1-4 源代码区(begin end)
6-2 Unit程序结构与窗体的关系
6-2-1 Unit代码结构
6-2-2 语句(Statement)
6-2-3 Unit间Use的状况
6-3 数据类型与定义变量
6-3-1 数据类型概论
6-3-2 不需要使用type声明的数据类型
6-3-3 必须使用type声明的数据类型
6-3-4 定义变量
6-3-5 变量的作用域
6-3-6 定义常量
6-3-7 变量的类型转换(Typecast)
6-4 Object Pascal的运算符(Operator)
6-4-1 设置运算符(assign Operator)
6-4-2 算数运算符(Arithmetic Operator)
6-4-3 关系运算符(Relational Operator)
6-4-4 布尔运算符
6-4-5 集合运算符
6-4-6 字符串运算符
6-4-7 位逻辑运算符
6-4-8 运算符优先级
6-5 流程控制
6-5-1 语句的基本概念
6-5-2 表达式语句(Expression-Statement)
6-5-3 流程控制语句
6-5-4 可视化程序与嵌套程序
6-6 数组与指针
6-6-1 数组类型
6-6-2 指针类型
6-6-3 浅谈指针与数据结构
6-7 程序与函数(Procedures and Functions)
6-7-1 函数的意义与优点
6-7-2 函数的分类与效用
6-7-3 自定义函数使用方法概述
6-7-4 函数的声明、定义及其实现
6-7-5 参数传递方式
6-7-6 声明修饰字
6-7-7 常用的内建函数

第7章 Object Pascal面向对象设计

7-1 类和对象
7-1-1 类(Class)与对象(Object)的基本概念
7-1-2 对象的构造与类的关系
7-2 类的声明与对象的定义
7-2-1 类的声明与对象的实现
7-2-2 对象的构造与析构
7-3 类成员的封装等级与可见度
7-3-1 封装的意义
7-3-2 Object Pascal类成员的封装等级
7-3-3 以实例说明类成员封装等级的可见度
7-3-4 开头不加保留字的类成员
7-3-5 成员封装等级的变更法则
7-4 类成员的定义与实现
7-4-1 字段(Field)与对象引用(Object Reference)的实现
7-4-2 方法(Method)
7-4-3 属性(Property)
7-5 类的继承
7-5-1 继承的意义与优点
7-5-2 子类成员的存在方式
7-6 成员函数的Override及 Overload
7-6-1 Override 适用的情况——Virtual与 Dynamic的成员函数
7-6-2 Override成员函数的定义语法
7-6-3 Virtual成员函数与动态绑定(Dynamic Binding)
7-6-4 覆盖(Overriding)与隐藏(Hiding)的差别
7-6-5 Override与OVerload的差别
7-7 Abstract成员函数与多态(Polymorphic)
7-7-1 一般纯虚函数的多态实现概念
7-7-2 纯虚函数的定义语法及实现
7-8 Self、AS、is、Sender、Parent、owner、inerited
7-8-1 Self变量
7-8-2 AS运算符
7-8-3 is运算符
7-8-4 Sender
7-8-5 Parent
7-8-6 owner
7-8-7 inerited保留字
7-9 静态成员方法——Class Methods

第8章 异常处理

8-1 异常处理存在的目的
8-2 Object Pascal异常的种类
8-2-1 Delphi内建的异常类
8-2-2 自定义异常类
8-3 触发异常的方法
8-3-1 由程序系统自动触发
8-3-2 使用Raise指令触发
8-4 处理异常情况
8-4-1 try…finally…end语法说明
8-4-2 ty…except…end语法说明

第9章 Delphi用户接口设计详述

9-1 基本概念
9-2 TForm的属性
9-2-1 由TComponent继承而来的属性
9-2-2 由TControl继承而来的属性
9-2-3 由TWinControl继承而来的属性
9-2-4 由TScrollingWindControl继承而来的属性
9-2-5 由TCustomForm继承而来的属性
9-3 TForm的方法
9-3-1 由TObject继承而来的属性
9-3-2 由TPersistent继承而来的属性
9-3-3 由TComponent继承而来的属性
9-3-4 由TControl继承而来的属性
9-3-5 由WinControl继承而来的属性
9-3-6 由TScrollingWinControl继承而来的属性
9-3-7 由TCustomForm继承而来的属性
9-3-8 由TForm继承而来的属性
9-4 TForm的事件
9-4-1 由TControl继承而来的属性
9-4-2 由TWinControl继承而来的属性
9-4-3 由TCustomForm继承而来的属性
9-5 TLabel的类成员
9-5-1 TLabel的属性
9-5-2 TLabel的方法

第10章 标准组件介绍及实作范例

10-1 Frames组件
10-2 MainMenu组件
10-3 PopuMenu组件
10-4 Label组件
10-5 Edit组件
10-6 Memo组件
10-7 Button组件
10-8 CheckBox组件
10-9 RadioButton组件
10-10 ListBox组件
10-11 ComboBox组件
10-12 ScrollBar组件
10-13 GroupBox组件
10-14 RadioGroup组件
10-15 Panel组件
10-16 ActionList组件

第11章 TApplication与TScreen类介绍及应用

11-1 TApplication类
11-1-1 TApplication类对象常用的属性
11-1-2 TApplication类对象常用的方法
11-2 TScreen类

第12章 高级组件介绍

12-1 Additional选项卡的常用组件
12-1-1 TBitBtn组件
12-1-2 TMaskEdit组件
12-1-3 TImage组件
12-1-4 TShape组件
12-2 Win32选项卡的常用组件
12-2-1 TPageControl组件
12-2-2 TImageList组件
12-2-3 TRichEdit组件
12-2-4 TDateTimePicker组件
12-2-5 TStatusBar组件
12-3 System选项卡的常用组件
12-3-1 TTimer组件
12-4 Dialogs选项卡的常用组件
12-4-1 TOpenDialog组件
12-4-2 FTontDialog组件
12-4-3 TColorDialog组件

第13章 封装Delphi7开发的应用程序

13-1 安装Borland的InstallShiled程序
13-2 利用InstallShield封装 Delphi7开发的程序
13-2-1 InstallShield环境界面简介
13-2-2 封装一个简单的Delphi项目

第14章 数据库概念及SQL指令介绍

14-1 数据库基本概念
14-1-1 数据库结构
14-1-2 开放数据库连接协议(ODBC)
14-1-3 SQL Explorer
14-2 结构化查询语言SQL
14-2-1 CREATE语句
14-2-2 ALTER TABLE语句
14-2-3 DROP语句
14-2-4 SELECT语句
14-2-5 INSERT、UPDATE语句
14-2-6 DELETE语句
14-3 SQL指令高级使用
14-3-1 UNION运算
14-3-2 JOIN运算
14-3-3 特殊运算符
14-3-4 子查询(Sub Query)

第15章 Delphi数据库程序基础

15-1 Delphi各种数据库连接设置
15-1-1 建立dBase、Paradox连接
15-1-2 建立Access连接
15-1-3 建立MSSQL连接
15-1-4 建立MySQL连接
15-2 Delphi的Database Desktop使用方法
15-2-1 字段定义
15-2-2 输入数据
15-2-3 设置BDE数据库别名与连接数据库

第16章 Delphi数据库程序设计——使用BDE组件

16-1 TDataSet组件
16-1-1 TDataSet组件常用的属性
16-1-2 TDataSet组件常用的方法
16-1-3 TDataSet组件常用的事件
16-2 TTable组件
16-2-1 TTable组件常用的属性
16-2-2 TTable组件常用的方法
16-3 TQuery组件
16-3-1 TQuery组件常用的属性
16-3-2 TQuery组件常用的方法
16-4 TDataModule组件
16-5 TDatabase组件
16-5-1 TDatabase组件常用的属性
16-5-2 TDatabase组件常用的方法
16-5-3 TDatabase组件常用的事件
16-6 综合范例
16-6-1 员工管理系统——使用TTable组件
16-6-2 员工管理系统——使用TQuery组件
16-6-3 订单管理系统——使用TTable组件
16-6-4 订单系统——使用TQuery组件

第17章 数据程序设计——使用Delphi组件

17-1 TADOConnection组件
17-1-1 TADOConnection组件常用的属性
17-1-2 TADOConnection组件常用的方法
17-1-3 TADOConnection组件常用的事件
17-2 TADOCommand组件
17-2-1 TADOCommand组件常用的属性
17-2-2 TADOCommand组件常用的方法
17-3 TADODataSet组件
17-3-1 TADODataSet组件常用的属性
17-3-2 TADODataSet组件常用的方法
17-3-3 TADODataSet组件常用的事件
17-4 TADOTable组件
17-4-1 TADOTable组件常用的属性
17-4-2 TADOTable组件常用的方法
17-5 TADOQuery组件
17-6 综合范例
17-6-1 客户管理系统——使用TADODataSet组件
17-6-2 客户管理系统——使用TADOTable组件
17-6-3 客户管理系统——使用TADOQuery组件
17-6-4 订单管理系统——使用TADOTable组件
17-6-5 订单系统——使用TADOQuery组件

第18章 数据感知组件

18-1 TDBText组件
18-2 TDBEdit组件
18-3 TDBMemo组件
18-4 TDBImage组件
18-5 TDBListBox组件
18-6 TDBComboBox组件
18-7 TDBLookupListBox与TDBLookupComboBox组件
18-8 TDBNavigator组件
18-9 TDBGrid组件

第19章 设计Delphi数据库报表

19-1 设计报表的基本观念
19-1-1 报表的组成
19-1-2 报表的主体组件——TquickRep
19-1-3 建立第一个报表程序
19-2 QuickReport可打印出组件
19-2-1 TQR系列组件介绍
19-2-2 TQRDB系列组件介绍
19-3 综合范例
19-3-1 一般表达报表范例
19-3-2 标签式报表范例
19-3-3 主/明细报表范例
19-3-4 一般表达式附图片报表范例
19-3-5 分组式报表范例——打印多色报表
19-3-6 报表输出及输出范例

附录 Kylix程序安装及转换

http://lib.verycd.com/2005/02/07/0000038314.html

5,386

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 开发及应用
社区管理员
  • VCL组件开发及应用社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧