为什么WM_ACTIVATEAPP不是第一次来?

我目睹了我不明白的行为:

  • 我从桌面(这很重要,不是从VS)启动我的游戏应用程序的编译二进制文件,
  • 在加载之前,我点击另一个窗口(记事本,Skype等)
  • 几秒钟后,应用程序被加载,窗口出现(通过CreateWindow),但不成为活动(这是好的)
  • 我点击我的应用程序窗口

而消息WM_ACTIVATEAPP不来! WM_ACTIVATE。 虽然它应该,因为我的应用程序变得活跃(我可以看到这从标题栏颜色变化,因为GetForegroundWnd开始返回我的wnd)。 WM_NCACTIVATE然后点击msg来。 之后,如果我再次点击另一个窗口,并点击回来,WM_ACTIVATEAPP / WM_ACTIVE开始如我所料。 那里发生了什么?

最小工作示例:

#include <Windows.h> static HWND hWnd = 0; static bool bExit = false; static bool bActive = false; void SetActive( bool active ) { bActive = active; } void PumpMessages() { MSG msg; while ( PeekMessage( &msg, 0, 0, 0, PM_NOREMOVE ) ) { if ( ::GetMessage( &msg, 0, 0, 0 ) ) { TranslateMessage( &msg ); DispatchMessage( &msg ); } else { bExit = true; } } } static LRESULT CALLBACK WndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { switch ( uMsg ) { case WM_ACTIVATEAPP: { printf( "WM_ACTIVATEAPP, wParam = %d, lParam = %d\n", wParam, lParam ); SetActive( wParam != 0 ); } break; case WM_ACTIVATE: { printf( "WM_ACTIVATE, wParam = %d, lParam = %d\n", wParam, lParam ); if ( !(HIWORD(wParam)) ) // if window is not minimized { switch ( LOWORD(wParam) ) { case WA_CLICKACTIVE: // activate window case WA_ACTIVE: { SetActive( true ); break; } case WA_INACTIVE: // deactivate window { SetActive( false ); break; } } } } break; case WM_NCACTIVATE: printf( "WM_NCACTIVATE, wParam = %d\n", wParam ); break; default: break; } return DefWindowProc( hWnd, uMsg, wParam, lParam ); } int main( int argc, char* argv[] ) { HINSTANCE hInstance = GetModuleHandle( NULL ); const char *pszWnd = "WndMyMy"; const char *pszApp = "AppMyMy"; int posX = 50, posY = 50; DWORD dwWidth = 800, dwHeight = 600; Sleep(2000); WNDCLASS wndClass = { CS_DBLCLKS, WndProc, 0, 0, hInstance, 0, 0, 0, 0, pszWnd }; ATOM atomWndClassName = RegisterClass( &wndClass ); if ( !atomWndClassName ) return 0; DWORD dwWinStyle = WS_OVERLAPPED|WS_VISIBLE|WS_CAPTION|WS_SYSMENU|WS_THICKFRAME|WS_MINIMIZEBOX|WS_MAXIMIZEBOX; hWnd = CreateWindow( pszWnd, pszApp, dwWinStyle, posX, posY, dwWidth, dwHeight, 0L, 0, hInstance, 0L ); if ( !hWnd ) return 0; // show & update window ShowWindow( hWnd, SW_SHOW ); SetForegroundWindow( hWnd ); UpdateWindow( hWnd ); while ( !bExit ) { PumpMessages(); } return 0; } 

谢谢!

  • 操作系统Windows 8,
  • VS 2010 SP1。