众所周知, GWLP_USERDATA
可用于将指针大小数据与指定的窗口关联起来。 但谁有权这样做呢? 显然,如果两个代码独立地做到这一点 – 一个是覆盖另一个的数据 – 所以只能有一个所有者。 但是必须清楚确定一个通用规则 – 谁是GWLP_USERDATA
单元的所有者? 它属于谁?
可以是两个内部一致的协议:
这两个解决scheme必须使用什么?
GWLP_USERDATA :
- 编译wlua.exe
- MessageBeep不能播放任何声音
- 在Windows上高并发负载时,Gatlingscheme似乎具有networking或HTTP损坏
- 为什么Vulkan在窗口模式下在Windows 10上使用CPU blitting? (presentmon)
- 在PsychoPy中使用pyo时pythonw.exe崩溃
设置与窗口关联的用户数据。 此数据旨在供创build该窗口的应用程序使用 。 它的值最初是零。
如何理解This data is intended for use by the application that created the window
?
所以调用CreateWindowEx
, CreateDialogParam
, DialogBoxParam
等的代码 – 只有这个代码可以使用GWLP_USERDATA
。 由此也可以看出,窗口类的实现者不能使用GWLP_USERDATA
。 所以GWLP_USERDATA
用于将类的实例绑定到指定的窗口的示例数量巨大不正确。 pipe理应用程序状态 – 官方MSDN示例,其中GWLP_USERDATA
用于将数据结构绑定到窗口不正确?
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
在这个规则下是错误的。
有什么可以说赞成这个版本? 我检查不同的Windows版本(从XP到WIN10) – 我怎么能看到所有的Windows内置窗口类( WC_*
和其他)使用
SetWindowLongPtr(hwnd, 0, (LONG_PTR)pThis);
用于将类的实例绑定到指定的窗口。 始终使用索引0,而不是GWLP_USERDATA
很多人可以说 – 那又怎样? 即使现在这是真的,未来的Windows版本呢? 但是如果想想,从GWLP_USERDATA
索引0(真正的私有实现者索引)什么意义上迁移? 改变现有的SetWindowLongPtr(hwnd, 0, (LONG_PTR)pThis);
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
什么奖项? 或者额外的开始使用GWLP_USERDATA
与索引0呢? 这已经绝对没有意义了 – 一个指针对于绑定窗口到数据结构是足够的,所有额外的指针必须是(在Windows代码将是),在这个结构已经。 所以我个人可以认为这没有改变
也可以在 这里 注意 SetWindowLongPtr
和 GetWindowLongPtr
的文档中的错误 :
要设置的值为零的偏移量。 有效值的范围为零至额外窗口内存的字节数,减去整数的大小
真正减去一个指针的大小,这个指针在x64的8个字节上,当一个整数的大小总是4。
请注意,此值…属于窗口类,不属于创build窗口的代码…只有窗口类实现者可以读取或写入值。
但也有接下来的两位作者的评论:
有趣。 我正在检查。 但是,即使它属于窗口的创build者,也有足够的窗口类实现使用它,为了安全起见,您仍然应该远离它。
和
我问周围,指导是“不清楚”,虽然略微倾向于“它属于调用CreateWindow的人”。 为了安全起见,你应该避免它,除非你能build立明确的所有权
再次寻找pipe理应用程序状态的 MSDN示例 – 窗口类实现者使用GWLP_USERDATA
!
寻找ATL
atlhost.h
– AtlAxWindowProc
使用了GWLP_USERDATA
//case WM_CREATE: ::SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD_PTR)pAxWindow);
再次使用类实现者GWLP_USERDATA
但是根据这个协议,我们不能使用带有CreateDialogParam
, DialogBoxParam
GWLP_USERDATA
,因为这里我们不是实现者( DialogProc
函数是DefDlgProc
调用的应用程序定义的callback函数 – 用于对话的真实类实现代码 – 所以只有DefDlgProc
可以潜在地使用GWLP_USERDATA
单元)
所以创build窗口或窗口类实现者的应用程序是所有者?
如果认为 – 创build窗口的变体应用程序更合乎逻辑。 窗口类实现者有两种select:可以将cbWndExtra
设置为sizeof(PVOID)
并使用索引0或使用GWLP_USERDATA
索引。 当创build窗口的应用程序 – 没有select – 只有GWLP_USERDATA
索引或使用像SetProp
, SetWindowSubclass
等另一种(不太有效和更复杂)的方式,如果窗口类实现者使用索引0绑定自己的数据窗口和离开为创build该窗口的代码提供免费的GWLP_USERDATA
。 又如何CreateDialogParam
, DialogBoxParam
– 最原始的方式这里使用数据结构绑定到对话框使用GWLP_USERDATA
索引,但在这里,我们的窗口创build者,而不是对话框类的实现者! 那么可以使用GWLP_USERDATA
吗?
在所有情况下,需要考虑到现有的自定义窗口类实现使用GWLP_USERDATA
我的假设:
CreateWindowEx
– 我们不能在这里使用GWLP_USERDATA
CreateDialogParam
, DialogBoxParam
– 我假设我们可以在这里使用GWLP_USERDATA
CreateWindowEx
for windows内置类(WC_ * named),我们也可以使用GWLP_USERDATA
cbWndExtra
设置为sizeof(PVOID)
并使用索引0