如何判断一个窗口是否获得了焦点?(Win32 API)

33

使用Win32 API(用C语言实现,但无关紧要),如何判断一个给定的窗口(由HWND标识)是否有焦点?

我正在钩取一个应用程序以监视事件,当该事件发生时,我想检查应用程序是否已经获得了焦点。如果没有,我想闪烁该窗口,直到他们将焦点放在它上面。

另外,FlashWindowEx结构体的FLASHW_TIMERNOFG标志是否会在窗口已经具有焦点时也进行闪烁?

由于我不在我的开发环境中,因此不能进行测试,但我认为它仍会进行闪烁,这就是我试图避免的。

此外,如果有影响的话,该应用程序在该窗口中使用了DirectX。


您想询问“此窗口是否具有焦点”还是“此应用程序的任何窗口是否具有焦点”? - ChrisW
我在下面的注释中指出,这个应用程序只会有一个窗口。 - Daniel Jennings
5个回答

33

那个工具真棒! - Alex Budovski
2
该链接已不再位于其显示的位置,但可以在存档中找到:web.archive.org/web/200308 - Sabuncu
2
或者,如果您想要一个比@Sabuncu的页面更现代的页面,请尝试这个链接:https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms646292(v=vs.85).aspx - acenturyandabit
https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getactivewindow - zwcloud

18

除了gkrogers使用GetActiveWindow的答案外,您还可以通过捕获WM_SETFOCUSWM_KILLFOCUS事件或WM_ACTIVATE来维护一个布尔变量,以了解您想知道的窗口是否具有焦点:

WndProc() ..
case WM_SETFOCUS:
  puts( "Got the focus" ) ;
  break ;

case WM_KILLFOCUS:
  puts( "Lost the focus" ) ;
  break;

case WM_ACTIVATE:
  if( LOWORD(wparam) == WA_INACTIVE )
    puts( "I AM NOW INACTIVE." ) ;
  else // WA_ACTIVE or WA_CLICKACTIVE
    puts( "MEGAZORD ACTIVATED kew kew kew (flashy-eyes)" ) ;
  break ;

10

您是真的想说"焦点"还是想说"活动"?

一个窗口拥有焦点——即第一个接收键盘事件的窗口。外部窗口(用户可以在屏幕上拖动的窗口)如果其子窗口拥有焦点,则为“活动”,但它本身可能或可能没有焦点。


1
该应用程序将永远只有一个窗口,没有子窗口或子窗体。 - Daniel Jennings

4

使用GetForegroundWindow函数获取您现在关注的Hwnd。然后,只需将其与您应用程序的窗口进行比较,以检查它是否包含焦点。


0

对于多个非模态子窗口:

子窗口中,您可以保存焦点, 2019年8月13日 Visual Studio 2017。

您可以保存焦点,以便父窗口知道单击了哪个非模态子窗口。

在子窗口的回调处理程序中:

case WM_CHILDACTIVATE: // Only gets called when the child border is click on.
    //CurrentFocus = hDlg; // Example: can save the focus globally for parent usage.
    //Beep(2000, 250); // So you can test
break;

case WM_GETMINMAXINFO: // Gets called when child window is being moved or sized.
        //Beep(2000, 250);
break;

case WM_LBUTTONDOWN:  // Only called when cursor is inside the child client area
    //CurrentFocus = hDlg; // Following the focus.
    //Beep(2000, 250);
break;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接