关于使用子类化函数(100分)

  • 主题发起人 主题发起人 charles2002
  • 开始时间 开始时间
C

charles2002

Unregistered / Unconfirmed
GUEST, unregistred user!
在D5开发人员指南的第13章是有一段关于子类化的程序<br><br>procedure TMainForm.HandleAppMessage(var Msg: TMsg; var Handled: Boolean);<br>{ OnMessage handler for Application object. }<br>begin<br>&nbsp;if Msg.Message = DDGM_FOOMSG then<br>&nbsp;ShowMessage(Format('Message seen by OnMessage! Value is: $%x',[Msg.Message]));<br>end;<br><br>procedure TMainForm.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; { Pass message on to old window procedure. }<br>&nbsp; &nbsp; Result := CallWindowProc(OldWndProc, Application.Handle, Msg, wParam,<br>&nbsp; &nbsp; &nbsp; lParam);<br>end;<br><br>procedure TMainForm.SendBtnClick(Sender: TObject);<br>begin<br>&nbsp; SendMessage(Application.Handle, DDGM_FOOMSG, 0, 0);<br>end;<br><br>procedure TMainForm.PostBtnClick(Sender: TObject);<br>begin<br>&nbsp; PostMessage(Application.Handle, DDGM_FOOMSG, 0, 0);<br>end;<br><br>procedure TMainForm.FormCreate(Sender: TObject);<br>begin<br>&nbsp; Application.OnMessage := HandleAppMessage; &nbsp; &nbsp; // set OnMessage handler<br>&nbsp; WndProcPtr := MakeObjectInstance(WndMethod); &nbsp; // make window proc<br>&nbsp; OldWndProc := Pointer(SetWindowLong(Application.Handle, GWL_WNDPROC,<br>&nbsp; &nbsp; Integer(WndProcPtr)));<br>end;<br><br>procedure TMainForm.FormDestroy(Sender: TObject);<br>begin<br>&nbsp; SetWindowLong(Application.Handle, GWL_WNDPROC, Longint(OldWndProc));<br>&nbsp; FreeObjectInstance(WndProcPtr);<br>end;<br>1、里面的MakeObjectInstance()是创建了一个窗口过程吗<br>2、OldWndProc := Pointer(SetWindowLong(Application.Handle, GWL_WNDPROC,<br>&nbsp; &nbsp; Integer(WndProcPtr)))有什么作用<br>
 
1是的,但是他的内存分配不是很好,有些浪费,题外话了,不用深究。<br>2,保存原来的窗口过程,在适当的时候,你还会用这个窗口过程来处理窗口消息。
 
请问xiangya:<br>WndProcPtr := MakeObjectInstance(WndMethod); &nbsp; 得到的是什么<br>在OldWndProc := Pointer(SetWindowLong(Application.Handle, GWL_WNDPROC,<br>&nbsp; &nbsp; Integer(WndProcPtr)));<br>中SetWindowLong()是把WndProcPtr作为一个新的窗口句柄来替换Application的句柄的吧<br>应如何理解?<br><br><br>
 
得到一个窗口过程的指针,实际上主要是分配内存。(可以不用深究)<br>不是句柄,而是窗口过程,<br>不知你是否了解SDK的编程方式,每个窗口都有一个窗口过程,也可以叫做窗口函数,<br>是它在负责处理所有的窗口消息。好了,这时候,你把它替换掉,那么,Windows就会<br>让这个新的窗口过程来处理所有的窗口消息,这样,就像一个新的窗口一样不是?<br>然后,在需要的时候弄回去就行保证象原来的一样。
 
你是说SetWindowLong让一个新的窗口过程取代原来的窗口过程,<br>并且用一个OldWndPro的指针指向原来窗口的过程吗
 
程序应该是这样的<br>1、程序在窗口创建的时先发送一个消息给应用程序<br>  Application.OnMessage := HandleAppMessage<br>2、利用WndProcPtr := MakeObjectInstance(WndMethod)创建一个由WINAPI创建的<br>&nbsp; &nbsp;窗口,并且把这个新的窗口的消息处理过程替换了旧的窗口过程,同时还保存了<br>  旧窗口的过程<br>3、当窗口创建以后,Application窗口的消息处理实际上就是新窗口的过程<br>4、用PostMessage发送消息时实际是对新的窗口发送DDGM_FOOMSG,而在发送DDGM_FOOMSG <br>  以前又有Appmessage发送的DDGM_FOOMSG 在消息等待序列,所以要先处理掉旧的消息<br>  再处理PostMessage发送的消息<br>5、用sendmessage则绕过 Appmessage发送的DDGM_FOOMSG 消息,直接向API建立了窗体发送<br>  DDGM_FOOMSG
 
多人接受答案了。
 
后退
顶部