/***************************************************************** * SetFocus (USER32.@) */ HWND WINAPI SetFocus( HWND hwnd ) { HWND hwndTop = hwnd; HWND previous = GetFocus(); TRACE( "%p prev %p\n", hwnd, previous ); if (hwnd) { /* Check if we can set the focus to this window */ hwnd = WIN_GetFullHandle( hwnd ); if (!IsWindow( hwnd )) { SetLastError( ERROR_INVALID_WINDOW_HANDLE ); return 0; } if (hwnd == previous) return previous; /* nothing to do */ for (;;) { HWND parent; LONG style = GetWindowLongW( hwndTop, GWL_STYLE ); if (style & (WS_MINIMIZE | WS_DISABLED)) return 0; if (!(style & WS_CHILD)) break; parent = GetAncestor( hwndTop, GA_PARENT ); if (!parent || parent == GetDesktopWindow()) { if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return 0; break; } if (parent == get_hwnd_message_parent()) return 0; hwndTop = parent; } /* call hooks */ if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, (WPARAM)hwnd, (LPARAM)previous, TRUE )) return 0; /* activate hwndTop if needed. */ if (hwndTop != GetActiveWindow()) { if (!set_active_window( hwndTop, NULL, FALSE, FALSE )) return 0; if (!IsWindow( hwnd )) return 0; /* Abort if window destroyed */ /* Do not change focus if the window is no longer active */ if (hwndTop != GetActiveWindow()) return 0; } } else /* NULL hwnd passed in */ { if (!previous) return 0; /* nothing to do */ if (HOOK_CallHooks( WH_CBT, HCBT_SETFOCUS, 0, (LPARAM)previous, TRUE )) return 0; } /* change focus and send messages */ return set_focus_window( hwnd ); }
/*********************************************************************** * CallMsgFilterW (USER32.@) */ BOOL WINAPI CallMsgFilterW( LPMSG msg, INT code ) { if (HOOK_CallHooks( WH_SYSMSGFILTER, code, 0, (LPARAM)msg, TRUE )) return TRUE; return HOOK_CallHooks( WH_MSGFILTER, code, 0, (LPARAM)msg, TRUE ); }
/******************************************************************* * set_active_window */ static BOOL set_active_window( HWND hwnd, HWND *prev, BOOL mouse, BOOL focus ) { HWND previous = GetActiveWindow(); BOOL ret; DWORD old_thread, new_thread; CBTACTIVATESTRUCT cbt; if (previous == hwnd) { if (prev) *prev = hwnd; return TRUE; } /* call CBT hook chain */ cbt.fMouse = mouse; cbt.hWndActive = previous; if (HOOK_CallHooks( WH_CBT, HCBT_ACTIVATE, (WPARAM)hwnd, (LPARAM)&cbt, TRUE )) return FALSE; if (IsWindow(previous)) { SendMessageW( previous, WM_NCACTIVATE, FALSE, (LPARAM)hwnd ); SendMessageW( previous, WM_ACTIVATE, MAKEWPARAM( WA_INACTIVE, IsIconic(previous) ), (LPARAM)hwnd ); } SERVER_START_REQ( set_active_window ) { req->handle = wine_server_user_handle( hwnd ); if ((ret = !wine_server_call_err( req ))) previous = wine_server_ptr_handle( reply->previous ); } SERVER_END_REQ; if (!ret) return FALSE; if (prev) *prev = previous; if (previous == hwnd) return TRUE; if (hwnd) { /* send palette messages */ if (SendMessageW( hwnd, WM_QUERYNEWPALETTE, 0, 0 )) SendMessageTimeoutW( HWND_BROADCAST, WM_PALETTEISCHANGING, (WPARAM)hwnd, 0, SMTO_ABORTIFHUNG, 2000, NULL ); if (!IsWindow(hwnd)) return FALSE; } old_thread = previous ? GetWindowThreadProcessId( previous, NULL ) : 0; new_thread = hwnd ? GetWindowThreadProcessId( hwnd, NULL ) : 0; if (old_thread != new_thread) { HWND *list, *phwnd; if ((list = WIN_ListChildren( GetDesktopWindow() ))) { if (old_thread) { for (phwnd = list; *phwnd; phwnd++) { if (GetWindowThreadProcessId( *phwnd, NULL ) == old_thread) SendMessageW( *phwnd, WM_ACTIVATEAPP, 0, new_thread ); } } if (new_thread) { for (phwnd = list; *phwnd; phwnd++) { if (GetWindowThreadProcessId( *phwnd, NULL ) == new_thread) SendMessageW( *phwnd, WM_ACTIVATEAPP, 1, old_thread ); } } HeapFree( GetProcessHeap(), 0, list ); } } if (IsWindow(hwnd)) { SendMessageW( hwnd, WM_NCACTIVATE, (hwnd == GetForegroundWindow()), (LPARAM)previous ); SendMessageW( hwnd, WM_ACTIVATE, MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, IsIconic(hwnd) ), (LPARAM)previous ); if (GetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow()) PostMessageW( GetDesktopWindow(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd ); if (hwnd == GetForegroundWindow() && !IsIconic( hwnd )) USER_Driver->pSetActiveWindow( hwnd ); } /* now change focus if necessary */ if (focus) { GUITHREADINFO info; info.cbSize = sizeof(info); GetGUIThreadInfo( GetCurrentThreadId(), &info ); /* Do not change focus if the window is no more active */ if (hwnd == info.hwndActive) { if (!info.hwndFocus || !hwnd || GetAncestor( info.hwndFocus, GA_ROOT ) != hwnd) set_focus_window( hwnd ); } } return TRUE; }