每次运行Win32控件的控件ID是否会更改?

时间:2009-11-03 17:08:57

标签: winapi

换句话说,我可以指望控件ID作为可靠的标识符吗?

从我已经完成的一些阅读中,听起来.NET控件可以拥有随每次运行而变化的控件ID,对于Win32应用程序也是如此,或者它们是否在源代码中被硬编码?

有问题的窗口/控件实际上是Internet Explorer对话框(如果有帮助的话)。

6 个答案:

答案 0 :(得分:5)

通常,运行应用程序时,win32对话框资源ID不会更改。但是,它们是内部实现细节,因此只要对应用程序进行更新(修补程序,Service Pack,主要版本),它们就会发生变化。

通常,IE的所有对话框都使用硬编码控件ID。可能有一些是动态的。如果你给出具体的控制,我可能会给你一个更好的答案。

答案 1 :(得分:4)

答案是“这取决于具体情况,但在大多数程序中,这些程序不会因多次执行而改变。”通常,每次执行同一程序时,控件ID或资源ID都是相同的。

在大多数实现中,资源存储在PE可执行文件的资源部分中,并在该数据结构内分配资源ID。通常,开发人员在.rc文件中指定资源。

例外情况是通过诸如CreateDialogIndirect()之类的API,它允许在运行时通过API指定的ID。然而,这种动态创造并不常见。资源ID和控制ID的一致性是预期的条件,因此即使在CreateXXXIndirect()API的情况下,也不建议API的用户选择不同的ID。

答案 2 :(得分:4)

微软花了数年时间尝试处理嵌入内部Windows实现细节假设的应用程序。 IE8兼容性问题的最大原因之一是由对IE控件的窗口顺序做出假设的应用程序引起的。当在IE8中更改UI时,控件移动了,并且许多浏览器插件都被破坏了。

一般情况下,你永远不应该对你没有编写的应用程序中的控件做出假设 - 你的代码将来会破坏(不会破坏,中断)。

答案 3 :(得分:2)

作为一般规则,不会在两次运行之间进行更改。控件ID通常使用对话框模板指定,这是一个编译为.exe或.dll的静态资源。也可以使用对CreateWindow或CreateWindowEx的常规调用来创建控件。在这种情况下,ID通常是常量,但它可以是任何原则(甚至是随机值)。

在任何情况下,如果您打算在另一个应用程序中使用对话框,那么您就会遇到麻烦。控件ID可以在程序的不同版本之间进行更改。

答案 4 :(得分:1)

这取决于控制。动态创建的控件每次创建时都可以具有不同的ID。基于静态对话框资源的控件将具有静态ID。

即使对话框资源模板支持对话框,也可以在运行时动态添加控件,这些控件可以动态生成ID。

答案 5 :(得分:1)

根据您的意图,将其存储和重复用于将来的查找或跟踪可能是可以接受的;但总的来说它并不安全。

如果窗口基于对话框模板,则模板中声明的项目通常不会更改。在典型情况下,将它们用作标识符是完全安全的。

有时窗口类名称或其中的一部分可以用作标识符,具体取决于窗口主机。

如果对话框是Internet Explorer的标准提示之一,您可能希望使用存储在相邻控件中的文本或对话框标题作为附加验证信息(如果IE的本地化版本不是问题)。如果对话框是嵌入MSHTML / IE实例的窗口;这些选项都不可行 - 但您可以使用OLE辅助功能获取显示的文档,然后从那里浏览DOM。