文档库 最新最全的文档下载
当前位置:文档库 › Delphi5学习笔记之一

Delphi5学习笔记之一

Delphi5学习笔记之一

1.圆括号:对于函数或过程,在调用它们时,如果函数或过程无参数,那么在调用它们时,可以加圆括号也可以不加。如:form1.Show;和form1.Show();是一样的。
2.在Delphi2中引入了可以在全局变量定义时给其初始化。如:
var
i: Integer = 1;
s: String = 'hello';


3.声明变量或常量时使用的编译期间函数:Ord()、Chr()、Trunc()、Round()、High()、Low()和SizeOf()等。如:
type
A = array[1..2] of Integer;
const
w: Word = SizeOf(Byte);
var
i: Integer = 8;
j: SmallInt = Ord('a');
l: LongInt = Trunc(3.1415926);
x: ShortInt = Round(2.71828);
b1: Byte = High(A);
b2: Byte = Low(A);
c: Char = Chr(46);
4.浮点数除和整数除及取模分别为:/、div、mod。注意不能用/来除整数,不能用div除浮点数。否则会引起编译错误。

5.数据类型
8位有符号整数ShortInt
8位无符号整数Byte
1 6位有符号整数SmallInt
1 6位无符号整数Word
3 2位有符号整数Integer,Longint
3 2位无符号整数Cardinal,LongWord
6 4位有符号整数Int64
4字节浮点数Single
6字节浮点数Real48
8字节浮点数Double
1 0字节浮点数Extnded
6 4位货币值currency无
8字节日期/时间TDateTime
1 6字节variantVariant,OleVariant,TVarData
1字节字符Char
2字节字符WideChar
固定长度字节的字符串ShortString
动态字符串AnsiString
以Null结束的字符串PChar
以Null结束的宽字符串PWideChar
动态2字节字符串WideString
1字节布尔值Boolean,ByteBool
2字节布尔值WordBool
4字节布尔值BOOL,LongBool

6.在字符串String类型变量被初始化前,变量的长度是不确定的,也就是说在未初始化该变量前并未给该
字符串变量分配内存。可以使用SetLength为字符串分配内存空间大小。如:
var s: string;
SetLength(s,5);//这也就是说可以像使用数组那样使用字符串变量。

7.PChar和String类型的字符串都是以NULL结尾的,而ShortString没有以NULL结尾,可以这样将ShortString类型的字符串变成以NULL的字符串,如下所示:
var
S: ShortString;
if Length(S) = High(S) then Dec(S[0]);//如果S太长,就截取一部分
S[Ord(Length(S)) + 1] := #0;
这样做之后,ShortString类型的变量S就以NULL结尾了。
8.Variant类型:Pascal可以在运行期或编译期识别Variant类型。引入Variant类型的目的:在运行期动态改变类型。

9.Variant变量中VType的两个特殊值:varEmpty和varNull,其中varEmpty表示这个Variant变量还没有被赋值,而varNull表示一个数值null,而不是没有值。

10.Variant类型的数组:可以使用下面的两个函数来创建Variant类型的数组,
function VarArrayCreate(const Bounds: array of Integer;VarType: Integer): Variant;
参数说明:Bounds是数组边界,VarType是数组类型
下面举例说明:
var
v: Variant;
begin
v := VarArra

yCreate([1,3],varInteger);
v[1] := 1;
v[2] := 2;
v[3] := 3;
end;
function VarArrayOf(Const values: array of Variant): Variant;
举例说明:
v := VarArrayOf([1,'Delphi5',2.5]);//通过该函数创建一个具有三个元素的数组,数组中的元素分别为整型、字符串和浮点数。
这些函数都在System.pas中。

11.使用函数VarArraylock()和VarArrayunlock()来初始化一个大数组:
下面两个举例说明:
例1:
begin
v := VarArrayCreate([1,10000],VarByte);
for i := 1 to 10000 do
v := A;//A也是一个数组
end;
例2:
begin
v := VarArrayCreate([1,10000],VarByte);
p := VarArrayLock(v);
try
Move(A,P^,10000);//使用Move就可以初始化数组v了,其中A也是一个数组,Move要初始化成数组A的值。
finally
VarArrayUnLock(v);
end;
end;

12.其他一些支持Variant函数:
procedure VarClear(var V: Variant);//清除variant变量并将VType域的值设为VarEmpty
procedure VarCopy(var Dest: Variant; const Source: Variant);//将source复制到Dest。
procedure VarCast(var Dest: Variant; const Source: Variant; VarType: Integer);//将一个Variant类型转换成指定的类型并存储在另一个Variant变量中。
function VarType(const V: Variant): Integer;//返回指定Variant变量的类型
function VarAsType(const V: Variant): Variant;//与VarCast功能相同
function VarIsEmpty(const V: Variant): Boolean;//如果变量V的类型是varEmpty函数就返回True
function VarIsNull(const V: Variant): Boolean;//书中写的是“判断变量V中是否包含null值”,我认为不是
function VarToStr(const V: Variant): String;//
function VarFromDateTime(DateTime: TDateTime): Variant;
function VarToDateTime(const V: Variant): TDateTime;
13.OleVariant与Variant类型相近,只不过OleVariant类型只支持自动化相兼容的类型。

14.使用编译器的内置函数High()和Low()来得到数组的上边界和下边界。举例:
var
A: array[28..30] of Integer;
i: Integer;
begin
for i := Low(A) to High(A) do A := i;
end;

15.动态删除数组的方法:SomeArray := nil;//将数组SomeArray赋值为nil,这样就删除了数组SomeArray

16.数组间赋值:
var
A,B: array of Integer;//声明A,B为两个动态数组
begin
SetLength(A,3);
B := A;
A[0] := 1;
B[0] := 2;
end;
在运行完上面的代码后A[0]等于几?正确答案为2,因为B是数组A的一个引用,这是由于B := A;这个赋值所引起的。如果想把一个数组的全部数据赋值给另一个数组应当使用Copy函数,如下所示:
begin
B := Copy(A);//在执行完该语句后,数组B不是数组A的引用了,而是一个独立的数组,并且数组B与数组A具有相同的数据。
在使用Copy()函数时,可以任意指定数组A中以哪个数据为开始,并可以指定赋给数组B的数据个数。如下所示:
B := Copy(A,1,2);//该表达式表示“从第一个数据开始,到第二个数据结束”,也就是

说将数组A中的第一个和第二个数据赋值给数组B,之后数组B就是一个拥有两个数据的独立数组。
end;

17.定义多维的动态数组:
在声明时对每一维用一个array关键字,如下所示:
var
A: array of array of Integer;
begin
SetLength(A,3,3);//设置二维数组为三行三列的
A[0,2] := 66;//给第一行第三列的数据赋值为66
end;

18.集合:
定义集合使用set of 组合关键字,例如:
A = Set Of Char;
集合用于表示一组有序数、字符或枚举量。
TSomeEnum = {Mon,Tue,Wed,Thr,Friday};
B = Set Of TSomeEnum;
C = Set Of 0..10;
D = Set Of Char;
给集合赋值方法:
C := [0,1];
D := ['a','b'];
操作集合方法:
if 'a' in D then ......
使用Include或Exclude来增加或删除集合元素,而不要使用'+'或'-',因为后者执行慢。
使用*来把两个集合取“交”,例如:if {'a','b','d'}*D then ......

19.强制类型转换:
注意只有当两个变量的数据长度一至时才可以对变量进行强制类型转换。
Double转换Integer要使用Trunc()或Round()函数。

20.循环中的Break()函数:它用于立即跳出循环,也就是说在循环中当某种条件满足时要立即跳出循环是使用Break()函数。

21.循环中的Continue()函数:如果想跳过循环中部分代码重新开始下一次循环,就使用Continue函数。

22.与C或C++不同,Pascal在函数中给Result赋完值后,函数并不会结束。

23.过程或函数中的参数:
procedure SomePro(val: Intger);//参数Val是以值的形式创建的,它是被传递值的一个副本
procedure SomePro(var Val: Intger);//此时的参数Val是以引用的形式创建的,它将被赋的值的地址复制给了过程SomePro中的参数Val,这样,如果在过程SomePro中对参数Val改变了,那么被传递的值同时也被改变了,即原值改变了。

24.过程或函数的参数为数组:
procedure SomePro(A: array of integer);
procedure SomePro(A: array of const);//参数A为常量数组,此时过程SomePro可以接收的参数值的数组可以是任何类型的,如第一项是integer,第二个是String等。

25.在单元文件的implementation部分可以添加initialization部分和finalization部分:
Initialization部分,在单元中它放在文件结尾前,它包含了用来初始化单元的代码,它在主程序运行前运行并只运行一次。
Finalization部分,它在单元中它放在initialization和end之间。
注意:如果几个单元都有initalization和finalization部分,则它们的执行顺序与单元在主程序的uses子句中的出现顺序一致。

26.单元文件的循环引用问题,最好不要出现循环引用,如果非要使用循环引用,可以将引用分别放在interface和implementation部分。

27.在Delphi中使用对象时要注意这样一个规定:自己创建的,都需要释放。不过该规定有两个

特例,一、当对象被其它对象拥有时,它将替你释放对象(组件有拥有其他组件的性质,当一个组件拥有其他组件时,则当它被析构时,它负责释放它拥有的组件),二、引用计数的对象,当最后一个引用释放时,它将被析构。

28.对象中方法的类型:
对象的方法能定义成静态(static)、虚拟(virtual)、动态(dynamic)或消息处理(message)。其中消息处理类型的方法可以message后面指定这个方法要响应的消息,用消息处理方法来响应Windows的消息,这样就不用直接来调用这个方法了。

29.方法的重载和覆盖:
重载在方法后加overload,覆盖在方法后加override。

30.方法中的隐含变量Self:
Self是用来调用方法的指向类实例的指针。

31.Pascal中的类实例实际上是指向堆中的类实例数据的32位指针。Pascal只能在堆中为类分配内存。

32.运行期类型信息(RTTI):它是一种语言特征,能使应用程序在运行时得到关于对象的信息。其实也不必了解什么RTTI,只要知道所有的类都是从TObject继承的,那么所有的对象都可以使用TObject类中的方法ClassName()、ClassType()、InheritsFrom()、ClassParent()、InstanceSize()、ClassInfo()来得到对象的相关信息就可以了。至于运算符as和is等使用RTTI能对对象进程比较和强制类型转换中是否使用了RTTI了解不了解都无所为了。

33.全局变量HInstance是进程本身的实例句柄,它在单元SysUitl中定义。如果一个程序编译成包,那么HInstance并不代表应用程序的模块句柄。此时使用MainInstance来访问宿主程序的模块句柄,而HInstance代表代码所在模块的句柄。

34.多任务是指操作系统可以同时运行多个应用程序。其实也就是任务切换,操作系统并没有真正的实现同时运行多个应用程序。它先运行一个应用程序一段时间,再切换到另一个应用程序运行一定时间。操作系统对每一个应用程序都是这样处理的。

35.一个进程真正能访问的内存大小取决于计算机安装了多少物理内存以及磁盘上有多少空间可被页交换文件使用。对于一个进程来说,物理内存和页交换文件是按页来划分使用的。页的大小取决于Win32安装在什么类型的系统上。在Intel的平台上,每页的长度是4KB;在Alpha平台上是8KB等。

35.Delphi中的项目文件dpr:这个文件是主窗体以及其他自动创建的窗体实例化的地方。

36.项目选项文件dof:该文件存储了Project|Options菜单命令所设置的项目选项。

37.桌面设置文件dsk:存储了Tools|Options菜单命令所设置的桌面选项。当保存项目或退出Delphi时会重新生成dsk和dof文件。

38.一个将ShowrtString类型转换成PChar类型的函数:
function ShortStringAsPChar(Var S: ShortString): PChar;
begin
if Le

ngth(S) = High(S) then Dec(S[0]);
S[Ord(Length(S)) + 1] := #0;
Result := @S[1];
end;

39.模式窗体:当打开一个模式窗体后,用户无法与应用程序的其他部分交互,直到用户关闭了这个窗体。
在使用模式窗体时需要注意一点:当赋值给模式窗体的ModalResult属性非零值时,则窗体将关闭,如下面例子所示:
SomeModalform.ModalResult := 99;//在执行完这条语句后,模式窗体SomeModalform将被关闭。

40.无模式窗体的释放问题:
最好在无模式窗体的OnClose事件里将Action赋值为caFree,而在无模式窗体的OnDestroy事件里把无模式窗体的实例赋值为nil。这样做的一个原因是在关闭无模式窗体时一般是通过窗体上的叉来关闭的,而在使用叉来关闭窗体时,无模式窗体实际上并没有从内存中释放,所以要在无模式窗体的OnClose和OnDestroy事件里添加额外代码来控制不让这种情况发生。还有一点,在调用无模式窗体时,一般都是这样子调用:
if not Assigned(Someform) then Someform := TSomeform.Create(Application);
Someform.Show;

41.新建窗体时的Copy、Inherit、Use三个选项的作用:
Copy:在当前项目中新建一个该窗体的副本
Inherit:在当前项目中派生一个该窗体
Use:将该窗体直接加载到项目中,在设计这个窗体时,任何修改都会影响以Inherit方式使用这个窗体的项目。

42.TApplication类型的一些应用:
//输出project2.exe
MessageBox(GetFocus,PChar(ExtractFileName(Application.ExeName)),'',MB_OK);//
//输出D:WorkSpaceMyFilesProjectGroupAndBorderIcon
MessageBox(GetFocus,PChar(ExtractFilePath(Application.ExeName)),'',MB_OK);//
//输出.exe
MessageBox(GetFocus,PChar(ExtractFileExt(Application.ExeName)),'',MB_OK);//
//输出D:WorkSpaceMyFilesProjectGroupAndBorderIconProject2.exe
MessageBox(GetFocus,PChar(Application.ExeName),'',MB_OK);//全路径
Application的属性Mainform是只读属性,要想设置项目的主窗体只能在设计期
通过设置Project|Option|forms页中指定。
TApplication.Owner属性总是nil。
TApplication.SHowHint属性为False时,项目中所有组件的提示将都不能显示。

43.TApplication的方法Createform:
使用该方法创建的窗体有一点需要注意:当项目中没有主窗体时,也就是说在使用Createform创建窗体时,该函数会检查Mainform属性,如果该属性值为nil,那么Createform会把新创建的窗体作为主窗体。

44.TApplication.Run()函数:首先,TApplication.Run()建立一个退出过程,以保证当应用程序退出运行时所有的组件都会得到释放。然后,它就建立一个循环来处理消息,直到应用程序的终止。

45.TApplication.Minimize()用于把应用程序的主窗口最小化。

46.TApplication.Restore()用于把应用程序的主窗口恢复为最大化或最小化之前的大小。

47.TApplication.Term

inate()用于终止应用程序的执行。与Halt()不同的是,Terminate()会隐含调用PostQuitMessage()看看还有什么消息要处理。

48.Halt()立即终止应用程序的执行,但不释放先前创建的对象,也不会返回到调用Halt()的地方。

49.全局变量Screen:
ActiveControl:这是一个只读属性,表明当前屏幕上哪个控件具有焦点。
Activeform:表明屏幕上哪个窗体具有焦点。
Cursor:这个属性用于设置整个应用程序的光标形状。
Cursors:这是一个列表,它列出了屏幕所支持的各种光标。
DataModuleCount:应用程序中数据模块的个数。
DataModules:应用程序数据模块列表。
formCount:应用程序中的窗体数目。
Fonts:这是一个列表,它列出了屏幕所支持的所有字体名称。
Height:屏幕的高度(像素)
Width:屏幕的宽度。

50.使一个窗体变成子窗体的方法:有三件事要做,覆盖窗体的Loaded过程、CreateParams过程,为该窗体指定它的父窗体,如下所示:
type
TChildform = Class(Tform)
private
FAsChild: Boolean;
FTempParent: TWinControl;
protected
procedure CreateParams(var Params: TCreateParams);override;
procedure Loaded;override;
public
constructor Create(AOwner: TComponent;AParent: TWinControl);reintroduce;overload;
end;
implementation
Constructor TChildform.Create(AOwner: TComponent;AParent: TWinControl);
begin
FAsChild := True;
FTempParent := AParent;
inherited Create(AOwner);
end;
procedure TChildform.CreateParams(var Params: TCreateParams);
begin
inherited CreateParams(Params);
if FAsChild then
Params.style := Params.style Or WS_CHILD;
end;
procedure TChildform.Loaded;
begin
inherited;
if FAsChild then begin
align := alClient;
Borderstyle := bsNone;
BorderIcons := [];
Parent := FTempParent;
Position := poDefault;
end;
end;

51.载入资源中图标、光标、位图的方法:
第一步:引入资源,{$R SomeRes.res}
第二步:使用TBitmap.LoadFromResourceName()函数或TBitmap.LoadFromResourceID()
举例子:
imgBitmap: TPicture;
const
crXHair = 1;//声明一个光标常量,注意其值必须是一个正数或不在0到-20之间的数,因为0到-20间是系统定义的默认的光标
imgBitmap.Picture.Bitmap.LoadFromResourceName(HInstance,'SOMEBITMAP');//注意第二个参数必须大写
imgBitmap.Picture.Assign(nil);//清除图像
//下面导入资源中的图标
Application.Icon.Handle := LoadIcon(HInstance,'SOMEICON');//第二个参数必大写
//下面两句用来改变鼠标光标为crXHair
Screen.Cursors[crXHair] := LoadCursor(HInstance,'XHAIR');//首先将资源中的光标加到Cursors数组
Screen.Cursor := crXHair;//指定光标


52.自定义异常:
举例说明
EBadError = Class(Exception);
EVeryBadError = Class(Exception);
ApplicationEvents1: TApplicationEvents;
procedure Tform1.Button1Click(Sender: TObject);
var
Str: String;
begin
if InputQuery(

'标题','请输入a',Str) then
if Str = 'a' then
OnBadError
else if Str = 'b' then
OnVeryBadError;
end;

procedure Tform1.OnBadError;
begin
Raise EBadError.Create('Bad Error!');
end;

procedure Tform1.OnVeryBadError;
begin
Raise EVeryBadError.Create('Very Bad Error!');
end;

procedure Tform1.ApplicationEvents1Exception(Sender: TObject;
E: Exception);
begin
if E is EBadError then begin
if MessageDlg(format('一个%s类型的错误发生了.下面是该异常的信息:"%s"退出吗?',
[E.ClassName,E.Message]),
mtError,[mbYes,mbNo],0) = mrYes then
Application.Terminate;
end else if E is EVeryBadError then begin
if MessageDlg(format('一个%s类型的错误发生了.下面是该异常的信息:"%s"要做什么?',
[E.ClassName,E.Message]),
mtError,[mbYes,mbNo],0) = mrYes then
Application.Terminate;
end else Application.ShowException(E);
end;


53.重新启动Windows的函数:
ExitWindowsEx()函数,这个函数能够注销当前用户、关闭Windows,或者在关闭Windows后重新启动它。举例说明:
Win32Check(ExitWindows(0,0));//退出,然后以另外一个用户身份登录
Win32Check(ExitWindowsEx(EWX_REBOOT,0));//退出并重启
Win32Check(ExitWindowsEx(EWX_SHUTDOWN,0));//退出并关闭系统
Win32Check(ExitWindowsEx(EWX_LOGOFF,0));//退出、注销并以另外一个用户身份登录
注:Win32Check()函数用于调用Win32API函数GetLastError来显示错误信息。使用ExitWindowsEx()函数并不会关闭系统;这需要特殊的权限。必须使用Win32 API函数AdjustTokenPrivleges()授予SE_SHUTDOWN_NAME权限。

54.如何得到Windows要退出的消息:可以使用主窗体的OnCloseQuery事件,如:
procedure TMainform.formCloseQuery(Sender: TObject;var CanClose: Boolean);
begin
if MessageDlg('ShutDown?',mtConfirmation,mbYesNoCancel,0) = mrYes then
CanClose := True else CanClose := False;//把CanClose设置为False表示不允许关闭Windows
end;

55.消息:就是Windows发出的一个通知,告诉应用程序某个事件发生了。如:单击鼠标、按下键盘上的一个键都会使Windows发送一个消息给应用程序。消息本身是作为一个记录传递给应用程序的,这个记录如下所示:
type
TMsg = packed record
hwnd: HWND;//窗口句柄,该句柄可以是窗口、对话框、按钮、编辑框等
message: UINT;//消息常量标识符
wParam: WPARAM;//32位消息的特定附加信息
lParam: LPARAM;//32位消息的特定附加信息
time: DWORD;//消息创建时的时间
pt: TPoint;//消息创建时鼠标的位置
end;
一个消息从产生到被一个窗口响应,其中共五步:
1.系统中发生了某个事件。
2.Windows把这个事件翻译为消息,然后把它放到消息队列中。
3.应用程序从消息队列中接收到这个消息,把它存放在TMsg记录中。
4.应用程序把消息传递给一个适当的窗口的窗口过程。
5.窗口过程响应这个消息并进行处理。

5

6.消息循环的任务就是从消息队列中检索消息,然后把消息传递给适当的窗口。

57.Delphi为每个Windows消息定义了一个特殊的消息记录,这样就不用从wParam或lParam中分解出有关信息了。

58.在Delphi中每一个消息都有各自的过程。

59.用于消息处理的过程必须满足下列3个条件:
1.这个过程必须是一个对象中的方法。
2.这个过程必须有一个var参数,变量的类型是TMessage或其他特殊的消息记录(如:TWMPaint)
3.声明这个过程时,必须使用message指示符,后面跟要处理的消息的常量值。
举例子说明:
procedure WMPaint(var Msg: TWMPaint);message WM_PAINT;

60.对消息记录中Result的赋值问题:
对Result域赋值
当处理某些Windows消息时,Windows希望返回一个值。典型的例子是WM_CTLCOLOR消息。当处理这个消息时,Windows希望返回一个画刷的句柄,Windows用这个画刷来画对话框或控件(Delphi为每个组件提供了Colo r属性,这个例子只是为了说明问题)。要返回一个值,只要在消息处理过程中调用了inherited之后对TMes sage(或其他消息记录)中的Result域赋值。例如,当处理WM_CTLCOLOR消息时,可以这样返回一个画刷的句柄:
procedure Tform1.WMCtlColor(var Msg: TWMCTLCOLOR);
var
BrushHand: HBrush;
begin
Inherited;
//在Inherited后创建一个画刷句柄并赋给BrushHand中
Msg.Result := BrushHand;
end;

61.Application.OnMessage事件将捕获到发送给应用程序的所有消息。这是个非常忙的事件(每秒钟可能有数千个消息)

62.Delphi提供的几种发送消息的函数:Perform()、SendMessage()、PostMessage()分别说明如下:
Perform:它可以向任何一个窗体或控件发送消息,Perform等消息处理完后返回。
SendMessage:它也是等到消息被处理后才返回。
PostMessage:它把消息发送完后立即返回,不管消息是否处理完它都立即返回。

63.通知消息:它是这样一种消息,一个窗口中的子控件发生了一些事情,需要通知父窗口。通知消息只适用于标准的窗口控件如按钮、列表框、组合框、编辑框、树状视图、列表视力等。子控件发生什么事情才会通知父窗口呢?如:单击或双击一个控件、在控件中选择部分文本、操作控件的滚动条都会产生通知消息。要处理通知消息,可以像处理其它消息一样,写一个消息处理过程。下面列举几个Win32中标准Windows控件的通知消息:BN_CLICKED(用户单击了按钮)、BN_DISABLE(按钮被禁止)、BN_PAINT(按钮应当重画)、CBN_CLOSEUP(组合框的列表框被关闭)、CBN_SETFOCUS(组合框获得了输入焦点)、EN_CHANGE(编辑框中的文本已经更新)、EN_UPDATE(编辑框中的文本将要更新)等。

64.VCL内部消息:这类消息一般以CM_(代表component message)开头,它们用于管理VCL的焦

点、颜色、可视性、窗口重建、拖放等。

65.用户自定义消息:用户自定义消息常量的值为WM_USER + 100到$7FFF
1.自定义消息,在应用程序内发送消息基本步骤:
第一步定义消息常量
const
SX_MYMESSAGE = WM_USER + 100;//
第二步发送消息:
Someform.Perform(SX_MYMESSAGE,0,0);
或SendMessage(Someform.Handle,SX_MYMESSAGE,0,0);
或PostMessage(Someform.Handle,SX_MYMESSAGE,0,0);
第三步编写接收消息的处理过程:
procedure SXMyMessage(var Msg: TMessage);message SX_MYMESSAGE;// 注意Msg的类型要为TMessage而不能为SX_MYMESSAGE
2.在应用程序内发送消息举例:
const
SX_MYMESSAGE = WM_USER + 100;
procedure SXMyMessage(var Msg: TMessage);message SX_MYMESSAGE;
procedure Tform1.SXMyMessage(var Msg: TMessage);
begin
MessageBox(GetFocus,'','',MB_OK);
end;
SendMessage(form1.Handle,SX_MYMESSAGE,0,0);//注意里第一个参数必须为窗体的句柄
3.在应用程序间发送消息:
如果要在两个或多个应用程序之间发送消息,那么最好要调用RegisterWindowMessage()函数。这个函数能够确保每个应用程序使用一致的消息编号。RegisterWindowMessage()需要传递一个以null结束的字符串,并返回一个范围从$C000到$FFFF的新的消息常量。这就意味着,在要发送消息的应用程序之间,每个应用程序都必须传递相同的字符串给RegisterWindowMessage()函数。
4.广播消息:
TWinControl的派生对象可以调用Broadcast()来向它的子控件广播一个消息。当需要向一组组件发
送相同的消息时,你要用得这种技术。例如, Panel1可以给它的所有子控件发送一个叫UM_FOO的自定义消息,代码如下:
var
M: TMessage;
begin
with M do begin
Message := UM_FOO;
wParam := 0;
lParam := 0;
Result := 0;
end;
Panel1.Broadcast(M);
end;

66.在Windows发出一个消息后,要经过两步才能达到你的消息处理过程(也可能步骤更少).VCL对象用于接收消息的方法叫MainWndProc,通过MainWndProc可以对消息进行任何特殊的处理,不过一般很少直接用MainWndProc来处理消息,除非不想让消息通过VCL的消息系统处理消息。从函数MainWndProc返回后,消息被传递给对象的WndProc方法,然后进入VCL的派发机制(派发机制也就是Dispatch方法把消息发给一个消息句柄给处理该消息的处理过程)。消息到达处理该消息的处理过程后,经过处理过程的处理和最后的inherited语句,消息来到对象的DefaultHandler方法,这个方法对消息进行最后的处理,然后把消息传递给Windows的DefWindowProc函数或其它默认的窗口程。举例说明:
procedure Tform1.CWMCatchMsg(var Msg: TMessage);//2
begin
MessageDlg('CWMCatchMsg发的消息:' + 'CWM_CATCHMSG',
mtInformation,[mbOK],0);
Inherited;
end;

procedure Tform1.DefaultHandler(var Msg); //3
var
CallInherited: Boolean;
begin
if TMessage

(Msg).Msg = CWM_CATCHMSG then begin
MessageDlg('DefaultHandler发送的:CWM_CATCHMSG',
mtInformation,[mbOK],0);
CallInherited := not rbtCatchMsg.Checked;
end;
if CallInherited then
inherited DefaultHandler(Msg);
end;

procedure Tform1.WndProc(var Msg: TMessage);//1
var
CallInherited: Boolean;
begin
if Msg.Msg = CWM_CATCHMSG then begin
MessageDlg('WndProc发的CWM_CATCHMSG',
mtInformation,[mbOK],0);
CallInherited := not rbtCatchMsg.Checked;
end;
if CallInherited then
inherited WndProc(Msg);
end;

procedure Tform1.Button1Click(Sender: TObject);
begin
SendMessage(HANDLE,CWM_CATCHMSG,0,0);
end;

67.消息与事件之间的关系:大部分的VCL事件都对应着一个WM_XXX消息。例如:OnActivate事件对应着Windows消息WM_ACTIVATE、onClick事件对应着Windows消息WM_XBUTTONDOWN、OnCreate事件对应着Windows消息WM_CREATE等。

68.参数的顺序问题:形参的顺序主要要考虑寄存器调用规则。最常用的参数应当作为第一个参数,按使用率集资从左到右排。输入参数位于输出参数之前。范围大的参数应当放在范围小的参数前。

69.命名冲突问题:当两个单元中含有相同名称的过程时,在该过程被调用时,实际被调用的是在Uses引用排在后面的单元中的过程。避免发生这种情况的方法:在调用该过程时在过程前加上单元名称来区分。

70.全局变量会自动进行零初始化操作。零初始化:将变量初始化为诸如0、nil、Unassigned等空值,零初始化不占用内存。

71.当数据类型只有在运行期才知道时,使用类型:Variant和OleVariant。进行Com编程时使用OleVariant类型,非Com编程用Variant类型。

72.如果要声明一个指向数组类型的指针,则必须声明在类型声明之前,如:
type
PCycleArray = ^TCycleArray;
TCycleArray = array[1..10] of Integer;
同样如果要声明一个指向记录类型的指针,也必须在类型声明之前声明,如:
type
PEmployee = ^TEmployee;
TEmployee = record
EmpName: string;
EmpId: Integer;

73.异常处理主要用于纠正错误和保护资源,这也就是说,凡是分配资源的地方,都必须使用try..finally来保证资源得到释放。

74.除非特别原因,只有主窗体才自动生成。其他所有窗体必须从自动创建的窗体列表中删除。

75.设计期包和运行期包:运行期包中应当只包含所需要的单元。那些属性编辑器和组件编辑器的单元应当放在设计期包中。下载注册单元也应当放在设计期包中。包的命名遵循下列模式:
iiiLibvv.pkg—设计期包
iiiStdvv.pkg—运行期包
其中,iii代表一个3字符的前缀,用于标识公司、个人或其他需要标识的事情。vv代表包的版本号,其中也包含了Delphi的版本号。

76.组件的注册单元放在设计期包。

https://www.wendangku.net/doc/19148194.html,/post/18860/214814

-------------------

---------------------------------------------------

相关文档
相关文档 最新文档