SetWindowLong和GetWindowLong的用法,哪位大侠帮一下呀!!!--100分 ( 积分: 100 )

  • 主题发起人 主题发起人 DragonInCity
  • 开始时间 开始时间
D

DragonInCity

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Memo1: TMemo;<br> &nbsp; &nbsp;procedure FormCreate(Sender: TObject);<br> &nbsp;private<br> &nbsp;<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br> &nbsp;Function ClientWindowProc( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br> &nbsp;Function ClientWindowProc11( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>Function ClientWindowProc( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>Var<br> &nbsp;pUserdata: Pointer;<br>Begin<br> &nbsp;pUserdata:= Pointer( GetWindowLong( wnd, GWL_USERDATA ));<br> &nbsp;Case msg of<br> &nbsp; &nbsp;WM_MOUSEWHEEL:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShowMessage('WM_MOUSEWHEEL');<br> &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp;Result := CallWindowProc(pUserdata, wnd, msg, wparam, lparam );<br>end;<br><br>Function ClientWindowProc11( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>Var<br> &nbsp;pUserdata: Pointer;<br>Begin<br> &nbsp;pUserdata:= Pointer( GetWindowLong( wnd, GWL_USERDATA ));<br> &nbsp;Case msg of<br> &nbsp; &nbsp;WM_RBUTTONDOWN:begin<br> &nbsp; &nbsp; &nbsp;showmessage('WM_RBUTTONDOWN');<br> &nbsp; &nbsp;end;<br> &nbsp;End;<br> &nbsp;Result := CallWindowProc(pUserdata, wnd, msg, wparam, lparam );<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br> //为什么同一个控件不能用两次?<br> &nbsp;SetWindowLong(Memo1.Handle, GWL_USERDATA, SetWindowLong(Memo1.Handle, GWL_WNDPROC, integer( @ClientWindowProc)));<br> &nbsp;SetWindowLong(Memo1.Handle, GWL_USERDATA, SetWindowLong(Memo1.Handle, GWL_WNDPROC, integer( @ClientWindowProc11)));<br>end;<br><br>end.
 
unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Memo1: TMemo;<br> &nbsp; &nbsp;procedure FormCreate(Sender: TObject);<br> &nbsp;private<br> &nbsp;<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br> &nbsp;Function ClientWindowProc( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br> &nbsp;Function ClientWindowProc11( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>Function ClientWindowProc( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>Var<br> &nbsp;pUserdata: Pointer;<br>Begin<br> &nbsp;pUserdata:= Pointer( GetWindowLong( wnd, GWL_USERDATA ));<br> &nbsp;Case msg of<br> &nbsp; &nbsp;WM_MOUSEWHEEL:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShowMessage('WM_MOUSEWHEEL');<br> &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp;Result := CallWindowProc(pUserdata, wnd, msg, wparam, lparam );<br>end;<br><br>Function ClientWindowProc11( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>Var<br> &nbsp;pUserdata: Pointer;<br>Begin<br> &nbsp;pUserdata:= Pointer( GetWindowLong( wnd, GWL_USERDATA ));<br> &nbsp;Case msg of<br> &nbsp; &nbsp;WM_RBUTTONDOWN:begin<br> &nbsp; &nbsp; &nbsp;showmessage('WM_RBUTTONDOWN');<br> &nbsp; &nbsp;end;<br> &nbsp;End;<br> &nbsp;Result := CallWindowProc(pUserdata, wnd, msg, wparam, lparam );<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>begin<br> //为什么同一个控件不能用两次?<br> &nbsp;SetWindowLong(Memo1.Handle, GWL_USERDATA, SetWindowLong(Memo1.Handle, GWL_WNDPROC, integer( @ClientWindowProc)));<br> &nbsp;SetWindowLong(Memo1.Handle, GWL_USERDATA, SetWindowLong(Memo1.Handle, GWL_WNDPROC, integer( @ClientWindowProc11)));<br>end;<br><br>end.
 
老兄, GWL_USERDATA标志只能保存一个32位变量吧 ?
 
To:刘麻子<br>  谢谢指导,那请问刘兄,如果要实现上述功能应怎么做呀?
 
可以增加类额外空间或者窗口实例额外空间的大小,<br>把我们自己的数据写在最后面而不影响原类,<br>具体请看这本书里关于子类化/超类化相关章节,<br>http://www.2ccc.com/article.asp?articleid=2063
 
谢谢刘兄,先看看再说
 
执行两次造成的消息处理死循环
 
ClientWindowProc11调用ClientWindowProc-调用ClientWindowProc11造成死循环
 
To:ffhello<br> &nbsp;那如何对其进行改进呢
 
setwindowlong前先判断<br>pUserdata:= Pointer( GetWindowLong( wnd, GWL_USERDATA ));的值是不是&gt;0
 
To:刘麻子<br>  大哥,具体是哪一章呀
 
To:ffhello<br> &nbsp;如果在SetWindowLong前判断一下,那就不能执行两次SetWindowLong了
 
pUserdata:= Pointer( GetWindowLong( dd, GWL_USERDATA ));<br>pwinlong:=GetWindowLong(dd, GWL_wndproc ));<br>if(puserdata&lt;&gt;pwinlong)then//判断是否已经setwindowlong了<br> SetWindowLong(dd.Handle, GWL_USERDATA, SetWindowLong(dd.Handle, GWL_WNDPROC, integer( @ClientWindowProc)));
 
To:ffhello<br> &nbsp;不行呀
 
应该没问题,你把代码贴上来看看
 
unit Unit1;<br><br>interface<br><br>uses<br> &nbsp;Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,<br> &nbsp;Dialogs, StdCtrls;<br><br>type<br> &nbsp;TForm1 = class(TForm)<br> &nbsp; &nbsp;Memo1: TMemo;<br> &nbsp; &nbsp;procedure FormCreate(Sender: TObject);<br> &nbsp;private<br> &nbsp;<br> &nbsp;public<br> &nbsp; &nbsp;{ Public declarations }<br> &nbsp;end;<br> &nbsp;Function ClientWindowProc( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br> &nbsp;Function ClientWindowProc11( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>var<br> &nbsp;Form1: TForm1;<br><br>implementation<br><br>{$R *.dfm}<br><br>Function ClientWindowProc( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>Var<br> &nbsp;pUserdata: Pointer;<br>Begin<br> &nbsp;pUserdata:= Pointer( GetWindowLong( wnd, GWL_USERDATA ));<br> &nbsp;Case msg of<br> &nbsp; &nbsp;WM_MOUSEWHEEL:<br> &nbsp; &nbsp; &nbsp; &nbsp;begin<br> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;ShowMessage('WM_MOUSEWHEEL');<br> &nbsp; &nbsp; &nbsp; &nbsp;End;<br> &nbsp;Result := CallWindowProc(pUserdata, wnd, msg, wparam, lparam );<br>end;<br><br>Function ClientWindowProc11( wnd: HWND; msg: Cardinal; wparam, lparam: Integer ): Integer; stdcall;<br>Var<br> &nbsp;pUserdata: Pointer;<br>Begin<br> &nbsp;pUserdata:= Pointer( GetWindowLong( wnd, GWL_USERDATA ));<br> &nbsp;Case msg of<br> &nbsp; &nbsp;WM_RBUTTONDOWN:begin<br> &nbsp; &nbsp; &nbsp;showmessage('WM_RBUTTONDOWN');<br> &nbsp; &nbsp;end;<br> &nbsp;End;<br> &nbsp;Result := CallWindowProc(pUserdata, wnd, msg, wparam, lparam );<br>end;<br><br>procedure TForm1.FormCreate(Sender: TObject);<br>var<br> &nbsp;pUserdata:pointer;<br> &nbsp;pwinlong:integer;<br>begin<br> &nbsp;SetWindowLong(ScrollBox1.Handle, GWL_USERDATA, SetWindowLong(ScrollBox1.Handle, GWL_WNDPROC, integer( @ClientWindowProc)));<br> &nbsp;pUserdata:= Pointer( GetWindowLong( Memo1.Handle, GWL_USERDATA ));<br> &nbsp;pwinlong:=GetWindowLong(Memo1.Handle, GWL_wndproc );<br> &nbsp;if(integer(puserdata)&lt;&gt;pwinlong) then//判断是否已经setwindowlong了<br> &nbsp; SetWindowLong(Memo1.Handle, GWL_USERDATA, SetWindowLong(Memo1.Handle, GWL_WNDPROC, integer( @ClientWindowProc11)));<br><br>end;<br><br>end.
 
最简单的方法,分别用两个变量保存原函数地址。
 
To:刘兄<br>我还是想学学“可以增加类额外空间或者窗口实例额外空间的大小,<br>把我们自己的数据写在最后面而不影响原类,<br>”,能不能麻烦刘兄给小弟讲解一二呀,谢谢了!
 
请看“第5章 Window Subclassing 和 Window Superclassing”。
 

Similar threads

后退
顶部