5

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

顺便说一句,GetWindowLong(hwnd, GWL_ID) 返回 0。

谢谢

4

2 回答 2

12

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

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

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

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

有关该主题的更多信息,您可以阅读有关CreateDialogIndirect()函数的信息,该函数在使用资源的情况下创建对话框。

于 2012-07-19T21:46:43.870 回答
5

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

这就像问,“给定一盘食物,我如何恢复原始食谱和食谱的页码?” 通过对食物进行化学分析,您可能能够恢复“一个”食谱,但食物本身并没有说:“我来自烹饪的乐趣,第 253 页。”

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

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

1.) 通过获取对话框的创建者文件GetWindowModuleFileName()

2.) 通过加载此 Exe 或 DllLoadLibraryEx(..., LOAD_LIBRARY_AS_IMAGE_RESOURCE)

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

4.) Create each enumerated dialog invisibly via LoadResource(), LockResource(), CreateDialogIndirect() but without showing the dialog with ShowWindow().

5.) Enumerate the child controls in each dialog via EnumChildWindows() and compare them to your dialog.

6.) Release all handles and destroy the dialogs.

It is not very probable that there are two identical dialogs in a Exe/Dll file. But the problem is that in WM_INITDIALOG the programmer may eliminate (destroy) or add or modify child controls. So your search algorithm would have to be fault tolerant. This would be possible by counting the congruency between each dialog from the resources and your dialog. You could count for how many child controls the ID (GetDlgCtrlID())and class name (GetClassName()) match. (e.g. Class="BUTTON" and ID = 311") While a programmer can easily change the text of a control or move it around, changing the ID is not very probable and does not make much sense and changing the class of a child control is even impossible.

As I said: It is not bullet proof, but you will find the ID of the resource that has most probably been used to create the dialog.

Be aware that not all dialogs come from a Microsoft resource. They can be created by a GUI framework that uses its own type of templates. In this case you will never find the Dialog ID because it simply does not exist.

于 2013-08-22T01:17:42.503 回答