【问题标题】:How come some controls don't have a windows handle?为什么有些控件没有窗口句柄?
【发布时间】:2011-06-15 15:05:51
【问题描述】:

我想获得一些控件的窗口句柄来做一些事情(需要一个句柄)。控件位于不同的应用程序中。

很奇怪;我发现许多控件没有 Windows 句柄,例如 Windows 资源管理器中工具栏 (?) 中的按钮。只需尝试获取文件夹/搜索/(等)按钮的句柄。它只给我 0。

所以.. 第一个问题:为什么有些控件没有窗口句柄?不是所有的控制窗口,在他们的心中? (只是谈论标准控件,就像我在 Windows 资源管理器中所期望的那样,没有在窗格等上自定义绘制。)

这让我想到了我的第二个问题:如果您无法获得它们的句柄,如何使用它们(例如使用 EnableWindow)?

非常感谢您的任何意见!

编辑(附加信息):

Windows 资源管理器只是一个示例。我经常遇到这个问题 - 而且是在不同的应用程序中(我真正感兴趣的应用程序,专有应用程序)。我有“物理”控件(因为我可以获得这些控件的 AutomationElement),但它们没有窗口句柄。此外,我正在尝试发送一条消息(SendMessage)来获取按钮状态,试图找出它是否被按下(它是一个标准按钮,似乎只通过该消息表现出这种行为 - 至少就我已经看到了。此外,尽管 Windows 资源管理器按钮显示类似的行为,就像按钮样式的复选框,但该按钮上的推送状态可能比标准按钮上的预期持续时间更长,尽管它们是(推送)按钮)。 SendMessage 需要一个窗口句柄。

ToolBar 是否会以某种方式改变其子元素的行为?拿走他们的窗户把手或类似的东西? (使用父句柄/控件ID进行识别??)但是如何在那些需要窗口句柄的控件上使用函数呢?

【问题讨论】:

    标签: windows winapi button controls handle


    【解决方案1】:

    如果它们没有句柄,它们就不是真正的控件,它们只是被绘制成看起来像控件。

    当然,Windows Explorer 中的工具栏按钮确实有窗口句柄,它们是工具栏的一部分。使用toolbar manipulation functions 与他们互动,而不是EnableWindow

    或者,更好的是,将记录在案的 API 用于搜索等内容。逆向工程 Windows 资源管理器从来没有对任何人都有好处,尤其是可怜的 Windows Shell 团队,他们为某些认为 API 适用于其他所有人的开发人员背负了多年的向后兼容性黑客攻击。无论您设法开始工作,很可能会在下一版本的 Windows 上中断。

    【讨论】:

    • 我试图笼统地说,然后举一个具体的例子,实际上与我想做的事情无关——我的错,对不起。实际上,我在一个完全不同的应用程序中有完全不同的按钮,也没有窗口句柄。还是它们所属的工具栏的特定功能?另外,我想使用的函数类似于 int res = SendMessage(realHwnd, BM_GETSTATE, 0, 0);找出按钮是否被按下。
    • @Andreas:是的,部分原因也是我的错。我花了太长时间阅读 Raymond Chen 的博客并在此处回答问题,这两者可能都让我对人们试图对 Windows 进行逆向工程感到痛苦。至于其他应用程序在做什么,很难说。有很多可能的场景。如果您有 Visual Studio 的副本,则应该有一个名为 Spy++ 的小实用程序。使用它来确定哪些控件实际包含这些按钮。如果它确实是一个工具栏(ToolbarWindow32 或类似的东西),那么您可以使用其中一个工具栏操作函数。
    • 具体来说,您需要检测由TBSTATE_* values 定义的工具栏按钮状态之一。按下(或选中)按钮将设置TBSTATE_CHECKED 状态标志(您可能不想要TBSTATE_PRESSED,因为这表明用户当前正在单击该按钮)。 TB_GETSTATE message 用于确定特定按钮的状态。
    • 感谢您添加的信息! (感觉就像在这里聊天;))所以 ToolBar 确实改变了它的“孩子”的行为,因为 TB_GETSTATE 消息与 BM_GETSTATE 消息不同(将命令 id 作为附加参数)。我可能不得不回到我的应用程序——它只在专用硬件上运行,所以每当我发现相似之处时,我都会检查 Windows 资源管理器,因为它更容易使用——并且可以在我的开发人员机器上使用。除了 ToolBar 之外,是否还有其他具有无句柄子级的控件?
    • 这似乎是我自己创建 GUI 时从未考虑过的控件/(嵌入)元素构造。现在,以这种方式使用 GUI,我很惊讶还有多少需要了解和学习(并且还要考虑在内)。
    【解决方案2】:

    您所说的控件使用的是 ToolbarWindow32 类。如果你想与他们交互,那么你需要使用toolbar control APIs/message。例如,要启用您想要使用的按钮TB_ENABLEBUTTON

    【讨论】:

      【解决方案3】:

      您可以使用 GDI、OpenGL 或 DirectX 自己实现这些控件。在 Mozilla Firefox 上尝试 Window Detective,您会看到只有 一个 窗口。对话框中的控件不是 Windows 已知的窗口。

      【讨论】:

        猜你喜欢
        • 2019-06-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-26
        • 2012-12-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多