GWL_USERDATA用于存储对象指针的替代方法是什么?

Ben*_*ack 27 windows winapi win64

在我工作的Windows应用程序中,我们有一个直接位于Win32上方的自定义框架(不要问).当我们创建一个窗口时,我们通常的做法是将this窗口的用户数据区域放入SetWindowLong(hwnd, GWL_USERDATA, this),这样我们就可以进行类似MFC的回调或紧密集成WndProc.问题是这不适用于Win64,因为LONG只有32位宽.什么是解决这个问题的更好的解决方案适用于32位和64位系统?

Chr*_*ris 36

SetWindowLongPtr的建立是为了取代调用SetWindowLong在这些情况下.它的LONG_PTR参数允许您存储32位或64位编译的指针.

LONG_PTR SetWindowLongPtr(      
    HWND hWnd,
    int nIndex,
    LONG_PTR dwNewLong
);
Run Code Online (Sandbox Code Playgroud)

请记住,常量也已更改,因此现在使用情况如下:

SetWindowLongPtr(hWnd, GWLP_USERDATA, this);
Run Code Online (Sandbox Code Playgroud)

另外不要忘记现在要检索指针,必须使用GetWindowLongPtr:

LONG_PTR GetWindowLongPtr(      
    HWND hWnd,
    int nIndex
);
Run Code Online (Sandbox Code Playgroud)

用法看起来像(再次,改变常量):

LONG_PTR lpUserData = GetWindowLongPtr(hWnd, GWLP_USERDATA);
MyObject* pMyObject = (MyObject*)lpUserData;
Run Code Online (Sandbox Code Playgroud)


And*_*ers 9

另一种选择是SetProp/RemoveProp(当您为已经使用GWLP_USERDATA的窗口创建子类时)

另一个不错的选择是WNDPROC的ATL风格的thunking,有关详细信息,请参阅

  • (啊,这是另一个旧的答案,由于最近的编辑,在RSS领域以某种方式显示为"新的"......)是的,我同意答案的第一部分; Get/SetProp是子类化时的方法.当有一个有效的API时,仍然没有理由使用汇编程序.(也许在几年内代码需要更改以添加ARM版本!) (2认同)
  • ......我在这些案件中是否真的证明了perf是否合理; 任何人认为perf可能是一个问题,在使用汇编程序之前首先需要先测量.我确信雷鬼有合法的用途,但IMO似乎只在极少数情况下是合理的; 因此,对于通过更易读,更强大和可维护的API推荐它们会非常谨慎. (2认同)