在ResourceHacker中,当您打开可执行文件(窗口)时,您可以看到与对话框关联的标识符。有没有人知道他们来自哪里?我的意思是,我怎样才能在我的C ++程序中从HWND获取ID?
BTW,GetWindowLong(hwnd,GWL_ID)返回0。
由于
答案 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)
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,因为它根本不存在。