【问题标题】:How to get the next selected window?如何获得下一个选定的窗口?
【发布时间】:2012-09-10 21:12:33
【问题描述】:

我正在编写一个对选定窗口进行一些更改的应用程序。我试图弄清楚如何在 c# 中按下按钮后选择窗口的 HWND。

流程类似于:

用户按下一个说选择窗口的表单按钮,表单隐藏自己不允许自己选择,用户点击桌面上的另一个窗口,这可以是任何应用程序,表单重新出现并收集 HWND选择的窗口,程序使用 HWND 来处理它的事务。

我不知道该怎么做的部分是获取选择了哪个窗口。

任何帮助将不胜感激!

【问题讨论】:

    标签: c# winapi hwnd


    【解决方案1】:

    执行此类操作的“经典”方式 - as used by Spy++ 和其他各种允许您选择要检查或使用的 UI 的应用程序 - 类似于:(这是从 C++/Win32 API 编写的观点,但除了 WindowFromPoint 和 GetAncestor 之外,大多数步骤都有 .Net 等价物)

    • 有一些显示十字准线并响应 WM_LBUTTONDOWN/Control.MouseDown 的 UI
    • 当它获得鼠标点击时,
      • 使用 SetCapture/Control.Capture 来“捕获”鼠标:这是一个神奇的部分,只要保持按下左键,您的 HWND 就会接收所有进一步的鼠标移动事件。 (这意味着您不需要钩子或类似的东西。),
      • 使用 SetCursor 将光标设置为合适的位置,例如十字准线。
      • 在某处设置一个标志,这样您就可以知道在拖动/捕获期间您将要获得的鼠标移动事件,以及如果用户只是将鼠标正常移动到您的控件上会获得的鼠标移动事件。
    • 现在,当用户在屏幕上移动十字准线指针时,您将收到 WM_MOUSEMOVE/Control.MouseMove 事件 - 检查您之前设置的标志以确保这是在“拖动”期间。使用 ClientToScreen/Control.PointToScreen 从移动事件中的控件相对坐标获取屏幕坐标,使用 WindowFromPoint 获取该位置的最子窗口,并使用 GetAncestor(GA_ROOT) 获取顶级窗口。也许检查窗口是否设置了 WS_CAPTION 以确保它是带有标题栏的窗口,如果您关心的话。 (您可能还想过滤掉任务栏和桌面窗口。)您还可以使用 GetWindowThreadProcessID 等 API 从您自己的进程中过滤掉窗口。如果 HWND 是一个可行的候选者,请将其保存在某个地方。如果您仍有一些 UI,您甚至可以使用 GetWindowText 来获取窗口的标题和/或其他详细信息,并提供有关在用户拖动时可能选择哪个窗口的实时反馈。
    • 当用户释放鼠标位置时,您将获得 WM_LBUTTONUP/Control.MouseUp - 用户已完成拖动。 ReleaseCapture,将图标和光标恢复到用户按下鼠标之前的状态,然后继续使用保存的 HWND - 如果有的话。

    在拖动取消操作的过程中也处理ESC也被认为是礼貌的。

    此外,以上内容对键盘不友好;在您的应用程序的生命周期内或仅在存在选择对话框时永久使用带有某个热键的说 RegisterHotkey 也是一个好主意,并使用 GetForegroundWindow() 来响应热键,如其他回复中所述。

    【讨论】:

      【解决方案2】:

      一种选择是轮询GetForegroundWindow API,直到 HWND 更改为另一个窗口。

      【讨论】:

        【解决方案3】:

        一种方法是

        • global mouse event handler 添加到您的应用程序中
        • 最小化您的应用程序
        • 当您的全局事件处理程序检测到鼠标点击时:
        • 调用 GetForegroundWindow()

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-10-25
          • 2021-04-08
          • 1970-01-01
          • 2010-11-24
          相关资源
          最近更新 更多