在ResourceHacker中,打开可执行文件(窗口)时,可以看到与对话框关联的标识符。有没有人有他们来自哪里的想法?我的意思是,我如何在我的C++程序中执行相同的操作以从HWND获取ID?从hWnd获取(资源)ID
顺便说一句,GetWindowLong(HWND,GWL_ID)返回0
由于
在ResourceHacker中,打开可执行文件(窗口)时,可以看到与对话框关联的标识符。有没有人有他们来自哪里的想法?我的意思是,我如何在我的C++程序中执行相同的操作以从HWND获取ID?从hWnd获取(资源)ID
顺便说一句,GetWindowLong(HWND,GWL_ID)返回0
由于
的GetWindowLong(hwnd, GWL_ID)
返回在对话框的控制的标识符,但是它不能被用于对话本身,因为对话只是没有标识符。
与对话框关联的标识符实际上用于引用资源blob本身,而不是窗口。它们被用来创建对话框(见CreateDialog()。
一旦创建对话框有原来的模板或该标识符没有关系。其实,有没有使用该ID,对话是简单地通过其HWND
鉴定需要注意的是,你可以使用相同的对话框资源创建多个不同的对话框。
这些标识符由资源编辑器分配(通常)顺序,或者手动你手工创建资源。
要了解更多有关您可以阅读有关CreateDialogIndirect()功能的主题,该功能会创建一个对话框withou t使用资源。
这里你可以找到一个很好的答案:“鉴于一盘菜,我该如何恢复原来 菜谱和页码为配方” http://blogs.msdn.com/b/oldnewthing/archive/2005/07/08/436815.aspx
这就像问,通过对食物进行化学分析 ,您可能能够恢复“a”配方,但是 食物本身没有任何内容说“我来自 烹饪的快乐”,第253页。“
所以答案是微软没有办法提供对话框ID。他们可以很容易地将其存储在任何地方以使其可用,但他们没有。
但是仍然有办法做到这一点,虽然它不是防弹的。你可以:
1)通过GetWindowModuleFileName()
2.获取对话框的创建者文件)通过LoadLibraryEx(..., LOAD_LIBRARY_AS_IMAGE_RESOURCE)
3.加载该EXE或DLL)枚举EXE或DLL所有RT_DIALOG资源通过EnumResourceNames()
其中对话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,因为它根本不存在
正如你所说,这个算法并不完全符合防弹要求。其他可能需要考虑的事情:在运行时创建的控件,以及在运行时删除的控件。除此之外,这是一个相当不错的答案,有一个值得信赖的介绍性链接到旧新事物。绝对值得赞赏。 – IInspectable 2016-03-08 02:23:59
找出该HWND的可执行文件,并从中提取资源。咄。 – 2012-07-19 21:35:41
@CatPlusPlus:例如,如果该对话框是在运行时创建的,那么通过调用[CreateDialogIndirect](例如https://msdn.microsoft.com/en-us/library/windows/desktop/ms645436.aspx)?该对话框甚至没有资源ID,因为模板是在内存中创建的。您将活动对象与资源混淆。 – IInspectable 2016-03-08 02:28:12