从hWnd获取(资源)ID

时间:2012-07-19 21:23:25

标签: c++ winapi

在ResourceHacker中,当您打开可执行文件(窗口)时,您可以看到与对话框关联的标识符。有没有人知道他们来自哪里?我的意思是,我怎样才能在我的C ++程序中从HWND获取ID?

BTW,GetWindowLong(hwnd,GWL_ID)返回0。

由于

2 个答案:

答案 0 :(得分:12)

GetWindowLong(hwnd, GWL_ID)在对话框中返回控件的标识符,但它不能用于对话框本身,因为对话框只是没有标识符。

与对话框关联的标识符实际上用于引用资源blob本身,而不是窗口。它们用于创建对话框(请参阅CreateDialog()

创建对话框后,没有与原始模板或该标识符的连接。实际上该ID没有用处,对话框只是由HWND标识。请注意,您可以使用相同的对话框资源创建多个不同的对话框。

这些标识符(通常)由资源编辑器按顺序分配,或者手动创建资源时手动分配。

有关该主题的更多信息,您可以阅读CreateDialogIndirect()函数,该函数使用资源创建一个没有的对话框

答案 1 :(得分:5)

在这里你找到了一个很好的答案: http://blogs.msdn.com/b/oldnewthing/archive/2005/07/08/436815.aspx

  

这就像是在问:“鉴于一盘食物,我该如何恢复   食谱的原始食谱和页码?“做化学品   分析食物,你可能能够恢复“一个”食谱,但是   食物中没有任何东西可以说:“我来自于喜悦   烹饪,第253页。“

所以答案是微软没有提供获取对话框ID的方法。他们可以轻松地将它存储在任何地方以使其可用,但他们没有。

但是仍然有办法做到这一点,虽然它不是防弹的。你可以:

1。)通过GetWindowModuleFileName()

获取对话框的创建者文件

2。)通过LoadLibraryEx(..., LOAD_LIBRARY_AS_IMAGE_RESOURCE)

加载此Exe或Dll

3.。)通过EnumResourceNames()枚举Exe或Dll中的所有RT_DIALOG资源,其中对话框ID在名称中:ResourceName = MAKEINTRESOURCE(IDD_DIALOG_ID)

4.。)通过LoadResource()LockResource()CreateDialogIndirect()无形地创建每个枚举对话框,但不显示ShowWindow()对话框。

5.。)通过EnumChildWindows()枚举每个对话框中的子控件,并将它们与对话框进行比较。

6。)释放所有句柄并销毁对话框。

Exe / Dll文件中不太可能存在两个相同的对话框。但问题是在WM_INITDIALOG中程序员可能会消除(破坏)或添加或修改子控件。因此,您的搜索算法必须具有容错能力。这可以通过计算资源和对话框中每个对话框之间的一致性来实现。您可以计算ID(GetDlgCtrlID())和类名(GetClassName())匹配的子控件数。 (例如,Class =“BUTTON”和ID = 311“)虽然程序员可以轻松地更改控件的文本或移动它,但更改ID并不是很可能,并且没有太大意义并且更改子控件的类甚至是不可能的。

正如我所说:它不是防弹,但您会发现最有可能用于创建对话框的资源的ID。

请注意,并非所有对话都来自Microsoft资源。 它们可以由使用自己的模板类型的GUI框架创建。在这种情况下,您永远不会找到对话框ID,因为它根本不存在。