第三个SetWindowSubclass参数中的uIdSubclass是什么?

Qua*_*002 5 c++ winapi

根据:http : //msdn.microsoft.com/zh-cn/library/windows/desktop/bb762102(v=vs.85).aspx

SetWindowSubclass原型是:

BOOL SetWindowSubclass(
   __in  HWND hWnd,
   __in  SUBCLASSPROC pfnSubclass,
   __in  UINT_PTR uIdSubclass,
   __in  DWORD_PTR dwRefData
);
Run Code Online (Sandbox Code Playgroud)

好吧,我明白了hWndpfnSubclassdwRefData

我找不到很好的信息,我该怎么设置uIdSubclass

MSDN说:

子类ID。该ID与子类过程一起唯一标识一个子类。若要删除子类,请将子类过程和此值传递给RemoveWindowSubclass函数。该值通过uIdSubclass参数传递给子类过程。

好的,可以理解,但仍然可以从哪里获得此ID?是我创造的东西还是某个地方得到的东西?如果是我创建的东西,它应该是什么样?

我在C ++和Win32 API中进行此操作,仅此而已。

谢谢。

bey*_*iii 0

Karl E. Peterson 在 Visual Studio Magazine 07/16/2009 Subclassing the XP Way中介绍了 uIdSubclass 参数的用途,并提供了一个名为HookXP的示例

\n

Karl E. Peterson 文章中讨论的主题:

\n
    \n
  1. 使用 uIdSubclass 来存储 this 指针[或 HWND]。
  2. \n
  3. 使用 dwRefData 传递可选数据,例如创建数据的指针。
  4. \n
  5. 在 pfnSubclass 中处理 WM_NCDESTROY 并调用\nRemoveWindowSubclass() 传递调用 SetWindowSubclass() 时使用的 uIdSubclass 非常重要。
  6. \n
\n

引用 Karl E. Peterson 的文章

\n
\n

每个子类都与窗口的 hWnd 一起被标识为两部分数据——它们是指向新消息处理过程的指针和由您生成的唯一 ID。您还可以选择将一个 Long 值作为额外参数传递给每个回调,无论您想要什么目的。我立即想到的是使用 ObjPtr() 作为每个子类的唯一 ID。什么物体?将处理回调的那个!

\n
\n
\n

我遇到的唯一未记录的警告是,您必须确保在窗口被销毁之前取消子类的挂钩。如果您使用我的技术将处理程序嵌入到在 Form_Unload 方法期间被破坏的表单或类中,那么这永远不会成为问题。如果你真的不想冒险,你可以在你的处理例程中插入一个简单的分支:

\n
\n
   Select Case uiMsg\n      Case WM_THIS\n         \'\n      Case WM_THAT\n         \'\n      Case WM_NCDESTROY\n         Call Unhook  \' !!!\n   End Select\n
Run Code Online (Sandbox Code Playgroud)\n

Explorer浏览器搜索示例还有一个使用 uIdSubclass 存储指向此的指针的示例。

\n
void CExplorerBrowserSearchApp::_OnInitializeDialog()\n{\n    ...\n        // Register the searchbox icon to receive hover and mouseclick events\n        SetWindowSubclass(GetDlgItem(_hdlg, IDC_SEARCHIMG), s_SearchIconProc, (UINT_PTR)this, 0);\n    ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n

Raymond Chen 的博客“The Old New Thing”文章Safer subclassing也提到了在 pfnSubclass 中处理 WM_NCDESTROY 的重要性,以便调用 RemoveWindowSubclass()。

\n

引用 Raymond Chen 的文章

\n
\n

文档中没有明确解释的一个问题是,您必须在被子类化的窗口被销毁之前删除窗口子类。这通常是通过在临时需求过去后删除子类来完成的,或者如果您要安装永久子类,则通过在子类过程本身内部插入对RemoveWindowSubclass的调用来完成:

\n
\n
case WM_NCDESTROY:\n  RemoveWindowSubclass(hwnd, thisfunctionname, uIdSubclass);\n  return DefSubclassProc(...);\n
Run Code Online (Sandbox Code Playgroud)\n

作为旁注,Microsoft SetWindowSubclass文档有一个警告,SetWindowSubclass() 仅限于每个线程。

\n
\n

警告 您不能使用子类化辅助函数来跨线程子类化窗口。

\n
\n