【问题标题】:Subclassing Control子类化控制
【发布时间】:2013-03-08 23:31:36
【问题描述】:

在 WINAPI 中,哪个是正确/必要的?

SetWindowLongPtr(HelpBox, GWLP_USERDATA, static_cast<LONG_PTR>(SetWindowLongPtr(HelpBox, GWLP_WNDPROC, (LONG_PTR)(Subclass))));

SetWindowLongPtr(HelpBox, GWLP_WNDPROC, (LONG_PTR)(Subclass));

然后在 WM_DESTROY 我都喜欢:

SetWindowLong(HelpBox, GWLP_WNDPROC, (LONG) Original);

为什么我应该使用第一个而不是第二个?我注意到它有两次 GWLP_USERDATA 和 setwindowlongptr .. 为什么?我在 MSDN 上看到了这两个示例,但我不知道何时使用第一个而不是第二个。

有什么想法吗?

【问题讨论】:

    标签: c++ winapi subclassing


    【解决方案1】:

    改用SetWindowSubclass;它处理将数据与窗口相关联的负担。反正。第一个将旧的窗口 proc 地址存储在与窗口关联的用户数据存储中,除非窗口类是您自己定义的,否则您不能这样做。即 窗口确实存在此类存储空间,您可以保证该存储空间不会用于其他任何用途。

    【讨论】:

    • 嗯,很抱歉编辑。我将自定义用户数据存储的非负索引与GWLP_USERDATA 混合在一起,这是一个单项存储并且始终存在。但同样的警告也适用。需要完全控制才能使用它。
    • 你能告诉我SetWindowSubclass的最后两个参数是做什么的吗?为什么我需要它们?我正在写一门课来制作窗户,如果需要的话,我有点不想跟踪所有的 ID。 pastebin.com/ePbbM57x
    • @CantChooseUsernames:id 用于删除子类化(通常你会在收到WM_DESTROY 时这样做)。由于删除函数将窗口句柄以及子类的窗口过程地址作为参数,因此您可以选择一个常量 id,例如 0 或 1 :-)。我能想到的唯一例外是,当代码使用相同的子类窗口过程对同一个窗口进行两次或多次子类化时,可能会发生,然后 id 至少原则上允许正确的与顺序无关的清理
    • @CantChooseUsernames:最后一个参数是提供给窗口过程的数据项。通常你会让它成为一个指向 C++ 类类型对象的指针。然后窗口过程可以转发到该对象的成员函数,然后该对象为您提供了一种更通用的方式将数据与窗口相关联,即作为普通 C++ 数据成员。
    猜你喜欢
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多