如何将信息传递到使用Winapi创建的窗口Proc
我需要创建一个用于处理消息的窗口(WM_HOTKEY),因此我在以下方面的水平较低,并使用setWindowlong将实例信息传递到WindowProc中。
fWindow:=CreateWindowEx(WS_EX_TOOLWINDOW,MsgWndClass.lpszClassName,'',WS_POPUP,0,0,0,0,0,0,HInstance,nil);
SetWindowLong(fWindow,GWL_USERDATA,NativeInt(Self));
class function TMessageWindow.WindowProc(hWnd: HWND; uMsg: Integer; wParam: WPARAM; lParam: LPARAM): Integer;
begin
var I:=GetWindowLong(hWnd,GWL_USERDATA);
if I=0 then
Exit(DefWindowProc(hWnd,uMsg,wParam,lParam));
Result:=TMessageWindow(I).HandleMessage(uMsg,wParam,lParam);
end;
当我尝试从tmessagewindow创建一个带有handlemessage的继承类时,我的问题就会出现。 我发现,尽管在继承的类中,处理函数被超越,但tmessagewindow(i)的类型正在调用基本方法。
在寻找此示例的示例之后,我找不到任何使用setWindowlong函数将信息传递给WindowProc的示例,因此现在我认为必须有更好的方法。
I needed to create a window for handling messages (WM_HOTKEY) so I went about going low level with the following and using SetWindowLong to pass the instance information for use in the windowproc.
fWindow:=CreateWindowEx(WS_EX_TOOLWINDOW,MsgWndClass.lpszClassName,'',WS_POPUP,0,0,0,0,0,0,HInstance,nil);
SetWindowLong(fWindow,GWL_USERDATA,NativeInt(Self));
and the windowproc is
class function TMessageWindow.WindowProc(hWnd: HWND; uMsg: Integer; wParam: WPARAM; lParam: LPARAM): Integer;
begin
var I:=GetWindowLong(hWnd,GWL_USERDATA);
if I=0 then
Exit(DefWindowProc(hWnd,uMsg,wParam,lParam));
Result:=TMessageWindow(I).HandleMessage(uMsg,wParam,lParam);
end;
My issues arise when I tried to create an inherited class from TMessageWindow with HandleMessage being virtual.
I found that although the HandleMessage function was overriden in the inherited class, the typecast of TMessageWindow(I) was calling the base method.
After searching around looking for an example of this I could not find any examples of people using the SetWindowLong function to pass information to the windowproc so am now thinking there must be a better way.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,请确保您的
类
方法也标记为static
以删除隐藏的self
参数,并使用stdcall < /code>调用约定,如果您还没有这样做,例如:
之后,如果您要编译64位,则代码需要使用
(get | set)windowlongptr()
而不是:另外,请使用 相反,例如:
说,使用虚拟消息过程创建消息窗口的一种更简单的方法是使用rtl的
allocateHwnd()
函数,例如:First off, make sure your
class
method is also marked asstatic
to remove the hiddenSelf
parameter, and is using thestdcall
calling convention, if you haven't already done so, eg:After that, if you are compiling for 64bit, your code needs to use
(Get|Set)WindowLongPtr()
instead, eg:Alternatively, use
SetWindowSubclass()
instead, eg:That being said, an easier way to create a message window with a virtual message procedure is to use the RTL's
AllocateHWnd()
function instead, eg: