如何获得下一个选定的窗口?

时间:2012-09-10 21:12:34

标签: c# winapi hwnd

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

流程将类似于:

用户按下表示选择窗口的表单按钮,表单隐藏自己不允许自己选择,用户点击桌面上的另一个窗口,这可以是任何应用程序,表单重新出现并收集HWND在所选窗口中,程序使用HWND进行业务。

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

非常感谢任何帮助!

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

  • 有一些显示十字准线的UI,它响应WM_LBUTTONDOWN / Control.MouseDown
  • 点击鼠标时,
    • 使用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 :(得分:0)

一种方法是

  • 在您的应用中添加global mouse event handler
  • 尽量减少您的申请
  • 当您的全局事件处理程序检测到鼠标单击时:
  • 调用GetForegroundWindow()