谁是GWLP_USERDATA单元的所有者?

时间:2017-01-07 13:12:30

标签: windows winapi

众所周知, GWLP_USERDATA 可用于将某些指针大小数据与指定窗口相关联。但谁有权利呢?很明显,如果两段代码独立地执行此操作 - 一块代码覆盖另一块代码 - 因此必须只有一个所有者。但必须明确确定一般规则 - 谁是 GWLP_USERDATA 单元格的所有者?它属于谁?

可以是两个内部一致的协议:

  1. 创建窗口的代码是所有者。属于的创造者 窗口
  2. 实现窗口类的代码。属于窗口类 实施者
  3. 必须使用这两种解决方案中的哪一种?

    1。来自MSDN

      

    GWLP_USERDATA

         

    设置与窗口关联的用户数据。 此数据是预期的   供创建窗口的应用程序使用。它的价值在于   最初为零。

    如何理解 This data is intended for use by the application that created the window

    所以调用CreateWindowExCreateDialogParamDialogBoxParam等的代码和只有此代码的代码可以使用 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

    许多人可以说 - 那又怎样?即使现在这是真的,未来的Windows版本呢? 但是如果想一想,从索引0(所有意义上的私人实施者指数)迁移到 GWLP_USERDATA 会有什么意义呢? 将现有SetWindowLongPtr(hwnd, 0, (LONG_PTR)pThis);更改为SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)pThis);奖品是多少?或者另外开始使用索引为0的 GWLP_USERDATA ?这已经是绝对无意义的 - 一个指针足以将绑定窗口转换为数据结构,所有其他指针必须是(在Windows代码将是)的情况下已经在此结构中。所以我个人可以认为这没有改变

    也可以在 SetWindowLongPtr GetWindowLongPtr 的文档中注明错误:

      

    要设置的值的从零开始的偏移量。有效值在   范围为零,通过额外窗口内存的字节数减去   整数

    的大小

    真的减去指针的大小,当x64上的8个字节时,整数的大小总是为4。

    2。看一下声誉良好的博客 - The bonus window bytes at GWLP_USERDATA

      

    请注意,此值,...,属于窗口类而不属于   创建窗口的代码...只有窗口类实现者可以   读取或写入值。

    还存在下两篇作者评论:

      

    有趣。我正在检查那个。但即使它确实属于   窗口的创建者,足够的窗口类实现使用它   为了安全起见,你仍然应该远离它。

      

    我四处询问,指导是"不清楚"虽然略微倾斜   朝向"它属于名为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 CreateDialogParamDialogBoxParam一起使用,因为此处我们没有实施({ {3}}函数是一个应用程序定义的回调函数,来自DialogProc - 对话框的实际类实现代码 - 因此只有DefDlgProc可以使用 GWLP_USERDATA 单元格)

    创建窗口的应用程序窗口类实施者是所有者?

    如果认为 - 创建窗口的变种应用程序更符合逻辑。 window类实现有两个选择:可以将DefDlgProc设置为sizeof(PVOID)并使用索引0或使用 GWLP_USERDATA 索引。当创建窗口的应用程序 - 没有选择 - 只有 GWLP_USERDATA 索引或使用另一种(效率更低,更复杂)的方式,如cbWndExtraSetProp等如果窗口类实现者使用索引0将自己的数据绑定到窗口,并为创建窗口的代码保留免费的 GWLP_USERDATA ,那么这是合乎逻辑的。再次如何SetWindowSubclassCreateDialogParam - 这里使用的大多数原生方式数据结构绑定到对话框使用 GWLP_USERDATA 索引,但这里我们窗口创建者,而不是对话框类实施者!那么可以使用 GWLP_USERDATA 吗?

    在所有情况下都需要考虑到足够的现有自定义窗口类实现使用 GWLP_USERDATA

    我的假设:

    • 如果我们为非Windows核心内置调用DialogBoxParam class - 我们不得在此使用 GWLP_USERDATA
    • 如果我们致电CreateWindowExCreateDialogParam - 我假设 我们可以在这里使用 GWLP_USERDATA
    • 如果我们为Windows内置类调用DialogBoxParam(WC_ * 我们也可以使用 GWLP_USERDATA
    • 如果我们窗口类实现者 - 最佳选择 - 设置CreateWindowExsizeof(PVOID)并使用索引0

0 个答案:

没有答案