众所周知, GWLP_USERDATA
可用于将某些指针大小数据与指定窗口相关联。但谁有权利呢?很明显,如果两段代码独立地执行此操作 - 一块代码覆盖另一块代码 - 因此必须只有一个所有者。但必须明确确定一般规则 - 谁是 GWLP_USERDATA
单元格的所有者?它属于谁?
可以是两个内部一致的协议:
必须使用这两种解决方案中的哪一种?
GWLP_USERDATA :
设置与窗口关联的用户数据。 此数据是预期的 供创建窗口的应用程序使用。它的价值在于 最初为零。
如何理解 This data is intended for use by the application that created the window
?
所以调用CreateWindowEx
,CreateDialogParam
,DialogBoxParam
等的代码和只有此代码的代码可以使用 GWLP_USERDATA
。此后,窗口类实现者也无法使用 GWLP_USERDATA
。如此大量的示例,其中 GWLP_USERDATA
用于指定窗口的类的绑定实例是不正确的。 Managing Application State - 官方MSDN示例,其中用于绑定数据结构到窗口的 GWLP_USERDATA
不正确?
SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
是此规则下的错误。
有什么可以说有利于这个版本?
我检查不同的Windows版本(从xp到win10) - 我如何看到所有窗口内置窗口类(WC_*
和其他)使用
SetWindowLongPtr(hwnd, 0, (LONG_PTR)pThis);
用于将类的bind实例绑定到指定的窗口。始终使用索引0代替 GWLP_USERDATA
GWLP_USERDATA
会有什么意义呢?
将现有SetWindowLongPtr(hwnd, 0, (LONG_PTR)pThis);
更改为SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);
奖品是多少?或者另外开始使用索引为0的 GWLP_USERDATA
?这已经是绝对无意义的 - 一个指针足以将绑定窗口转换为数据结构,所有其他指针必须是(在Windows代码将是)的情况下已经在此结构中。所以我个人可以认为这没有改变
也可以在 SetWindowLongPtr
和 GetWindowLongPtr
的文档中注明错误:
要设置的值的从零开始的偏移量。有效值在 范围为零,通过额外窗口内存的字节数减去 整数
的大小
真的减去指针的大小,当x64上的8个字节时,整数的大小总是为4。
请注意,此值,...,属于窗口类而不属于 创建窗口的代码...只有窗口类实现者可以 读取或写入值。
但还存在下两篇作者评论:
有趣。我正在检查那个。但即使它确实属于 窗口的创建者,足够的窗口类实现使用它 为了安全起见,你仍然应该远离它。
和
我四处询问,指导是"不清楚"虽然略微倾斜 朝向"它属于名为CreateWindow"的人。对于 安全的缘故,你应该避免它,除非你能建立起来 明确所有权
再次查找Managing Application State MSDN示例 - 使用 GWLP_USERDATA
的窗口类实现者!
查找使用 ATL
atlhost.h
AtlAxWindowProc
- GWLP_USERDATA
//case WM_CREATE:
::SetWindowLongPtr(hWnd, GWLP_USERDATA, (DWORD_PTR)pAxWindow);
类实施者再次使用 GWLP_USERDATA
但根据此协议,我们无法将 GWLP_USERDATA
与CreateDialogParam
,DialogBoxParam
一起使用,因为此处我们没有实施({ {3}}函数是一个应用程序定义的回调函数,来自DialogProc
- 对话框的实际类实现代码 - 因此只有DefDlgProc
可以使用 GWLP_USERDATA
单元格)
创建窗口的应用程序或窗口类实施者是所有者?
如果认为 - 创建窗口的变种应用程序更符合逻辑。 window类实现有两个选择:可以将DefDlgProc
设置为sizeof(PVOID)
并使用索引0或使用 GWLP_USERDATA
索引。当创建窗口的应用程序 - 没有选择 - 只有 GWLP_USERDATA
索引或使用另一种(效率更低,更复杂)的方式,如cbWndExtra
,SetProp
等如果窗口类实现者使用索引0将自己的数据绑定到窗口,并为创建窗口的代码保留免费的 GWLP_USERDATA
,那么这是合乎逻辑的。再次如何SetWindowSubclass
,CreateDialogParam
- 这里使用的大多数原生方式数据结构绑定到对话框使用 GWLP_USERDATA
索引,但这里我们窗口创建者,而不是对话框类实施者!那么可以使用 GWLP_USERDATA
吗?
在所有情况下都需要考虑到足够的现有自定义窗口类实现使用 GWLP_USERDATA
我的假设:
DialogBoxParam
class - 我们不得在此使用 GWLP_USERDATA
CreateWindowEx
,CreateDialogParam
- 我假设
我们可以在这里使用 GWLP_USERDATA
DialogBoxParam
(WC_ *
我们也可以使用 GWLP_USERDATA
CreateWindowEx
到sizeof(PVOID)
并使用索引0