子类化——谁可以给我详细的讲解啊,看书看不懂。。。。。。(100分)

  • 主题发起人 主题发起人 长发
  • 开始时间 开始时间

长发

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;<br>interface<br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls;<br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure FormDestroy(Sender: TObject);<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; OldWndProc : Pointer;<br>&nbsp; &nbsp; WndProcPtr : Pointer;<br>&nbsp; &nbsp; Procedure WndMethod(var Msg : TMessage);<br>&nbsp; &nbsp; Procedure HandleAppMessage(var Msg : TMsg;var Handled : Boolean);<br>&nbsp; public<br>&nbsp; end;<br>var<br>&nbsp; Form1: TForm1;<br>implementation<br>uses unit2;<br>{$R *.dfm}<br>{ TForm1 }<br>procedure TForm1.HandleAppMessage(var Msg: TMsg; var Handled: Boolean);<br>begin<br>&nbsp; if Msg.message = DDGM_FOOMSG then<br>&nbsp; &nbsp; showmessage(Format('Message seen by OnMessage! value is: $%x',[Msg.message]));<br>end;<br>procedure TForm1.WndMethod(var Msg: TMessage);<br>begin<br>&nbsp; if Msg.Msg = DDGM_FOOMSG then<br>&nbsp; &nbsp; showmessage(Format('Message seen by WndMethod! value is: $%x',[Msg.Msg]));<br>&nbsp; with Msg do<br>&nbsp; &nbsp; Result := callwindowProc(OldWndProc,Application.Handle,Msg,WParam,LParam);<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; Application.OnMessage := HandleAppMessage;//set OnMessage handler<br>&nbsp; WndProcPtr := MakeObjectInstance(WndMethod); //make window &nbsp;Proc<br>&nbsp; OldWndProc := Pointer(SetWindowLong(Application.Handle,gwl_wndProc,Integer(WndProcPtr)));<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br>&nbsp; SetWindowLong(Application.Handle,GWL_WNDPROC,Longint(OldWndProc));<br>&nbsp; FreeObjectInstance(WndProcPtr);<br>end;<br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; SendMessage(Application.Handle,DDGM_FOOMSG,0,0);<br>end;<br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp; PostMessage(Application.Handle,DDGM_FOOMSG,0,0);<br>end;<br>end.<br><br>unit Unit2;<br>interface<br>uses Forms,Messages;<br>const<br>&nbsp; DDGM_FOOMSG = WM_USER;<br>implementation<br>uses Windows,SysUtils,Dialogs;<br>var<br>&nbsp; WProc : Pointer;<br>Function NewWndProc(Handle : hWnd; Msg,WParam,LParam : LongInt):LongInt;stdcall;<br>begin<br>&nbsp; if Msg = DDGM_FOOMSG then<br>&nbsp; &nbsp; showmessage(Format('Message seen by WndProc! value is: $%x',[Msg]));<br>&nbsp; Result := CallWindowProc(WProc,Handle,Msg,WParam,LParam);<br>end;<br>initialization<br>{set window procedure of application window}<br>&nbsp; WProc := pointer(SetWindowLong(Application.Handle,gwl_wndProc,integer(@NewWndProc)));<br>end.<br><br>这是书上的例子 但我老是不明白其中的每步的意思和他的原理 那位GG可以给我详细讲解一下
 
//*************************************************************<br>//这段代码实现的就是拦载自定义消息的功能,Unit2.pas代码是自定义消息的消息号<br>//*************************************************************<br>unit Unit1;<br>interface<br>uses<br>&nbsp; Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br>&nbsp; Dialogs, StdCtrls;<br>type<br>&nbsp; TForm1 = class(TForm)<br>&nbsp; &nbsp; Button1: TButton;<br>&nbsp; &nbsp; Button2: TButton;<br>&nbsp; &nbsp; procedure FormCreate(Sender: TObject);<br>&nbsp; &nbsp; procedure FormDestroy(Sender: TObject);<br>&nbsp; &nbsp; procedure Button1Click(Sender: TObject);<br>&nbsp; &nbsp; procedure Button2Click(Sender: TObject);<br>&nbsp; private<br>&nbsp; &nbsp; //定义指针变量(指向方法)<br>&nbsp; &nbsp; OldWndProc : Pointer;<br>&nbsp; &nbsp; WndProcPtr : Pointer;<br>&nbsp; &nbsp; //当接到DDGM_FOOMSG消息时,显示一个自定义对话框,否则调用WndMethod窗口消息处理过程<br>&nbsp; &nbsp; Procedure WndMethod(var Msg : TMessage);<br>&nbsp; &nbsp; //此方法用来取代Application.OnMessage方法,当接到DDGM_FOOMSG消息时,显示一个自定义对话框<br>&nbsp; &nbsp; Procedure HandleAppMessage(var Msg : TMsg;var Handled : Boolean);<br>&nbsp; public<br>&nbsp; end;<br>var<br>&nbsp; Form1: TForm1;<br>implementation<br>uses unit2;<br>{$R *.dfm}<br>{ TForm1 }<br>procedure TForm1.HandleAppMessage(var Msg: TMsg; var Handled: Boolean);<br>begin<br>&nbsp; if Msg.message = DDGM_FOOMSG then<br>&nbsp; &nbsp; showmessage(Format('Message seen by OnMessage! value is: $%x',[Msg.message]));<br>end;<br><br>procedure TForm1.WndMethod(var Msg: TMessage);<br>begin<br>&nbsp; if Msg.Msg = DDGM_FOOMSG then<br>&nbsp; &nbsp; showmessage(Format('Message seen by WndMethod! value is: $%x',[Msg.Msg]));<br>&nbsp; with Msg do<br>&nbsp; &nbsp; Result := callwindowProc(OldWndProc, Application.Handle, Msg, WParam,LParam);<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br>&nbsp; //设置OnMessage的句柄,当接到消息时,调用HandleAppMessage方法<br>&nbsp; Application.OnMessage := HandleAppMessage;<br>&nbsp; //将WndProcPtr这个指针变量指向WndMethod方法(自定义的)<br>&nbsp; WndProcPtr := MakeObjectInstance(WndMethod);<br>&nbsp; //SetWindowLong(Application.Handle,gwl_wndProc,Integer(WndProcPtr)用来改变窗口属性,返回窗口句柄<br>&nbsp; OldWndProc := Pointer(SetWindowLong(Application.Handle, gwl_wndProc, Integer(WndProcPtr)));<br>end;<br><br>procedure TForm1.FormDestroy(Sender: TObject);<br>begin<br>&nbsp; SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(OldWndProc));<br>&nbsp; //释放WndProcPtr指针变量占用的内存<br>&nbsp; FreeObjectInstance(WndProcPtr);<br>end;<br>procedure TForm1.Button1Click(Sender: TObject);<br>begin<br>&nbsp; SendMessage(Application.Handle,DDGM_FOOMSG,0,0);<br>end;<br>procedure TForm1.Button2Click(Sender: TObject);<br>begin<br>&nbsp; PostMessage(Application.Handle,DDGM_FOOMSG,0,0);<br>end;<br>end.<br>
 
to 林枫,<br>&nbsp; SetWindowLong 这个函数是干什么用的啊?
 
Delphi 里一般用不着自己子类化<br>这是在 C SDK /ASM SDK 中才用的。
 
The SetWindowLong function changes an attribute of the specified window. The function also sets a 32-bit (long) value at the specified offset into the extra window memory of a window. <br>If the function succeeds, the return value is the previous value of the specified 32-bit integer.<br>If the function fails, the return value is zero. To get extended error information, call GetLastError. <br><br><br>就是設置窗口某個attributer的地址。<br>gwl_wndProc:表示SetWindowLong(Application.Handle, gwl_wndProc, Integer(WndProcPtr)設置這個程序的wndproc為自定的那個方法。<br><br>在FormCreate處要把舊的wndproc存起來(就是OldWndProc )<br>在FormDestroy進還原(否則會出事的)。
 
后退
顶部