win32u: Move set_foreground_window implementation from user32.

Signed-off-by: Jacek Caban <jacek@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Jacek Caban 2022-03-11 14:22:04 +01:00 committed by Alexandre Julliard
parent d5fd27761f
commit 917a80182d
9 changed files with 73 additions and 203 deletions

View File

@ -104,10 +104,6 @@ static void CDECL nulldrv_SetCapture( HWND hwnd, UINT flags )
{
}
static void CDECL nulldrv_SetFocus( HWND hwnd )
{
}
static void CDECL nulldrv_SetParent( HWND hwnd, HWND parent, HWND old_parent )
{
}
@ -212,7 +208,7 @@ static struct user_driver_funcs lazy_load_driver =
nulldrv_ReleaseDC,
NULL,
nulldrv_SetCapture,
nulldrv_SetFocus,
NULL,
NULL,
nulldrv_SetParent,
NULL,
@ -259,7 +255,6 @@ void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT v
SET_USER_FUNC(MsgWaitForMultipleObjectsEx);
SET_USER_FUNC(ReleaseDC);
SET_USER_FUNC(SetCapture);
SET_USER_FUNC(SetFocus);
SET_USER_FUNC(SetParent);
SET_USER_FUNC(SetWindowIcon);
SET_USER_FUNC(SetWindowStyle);

View File

@ -30,198 +30,6 @@
#include "imm.h"
#include "user_private.h"
#include "wine/server.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(win);
/*****************************************************************
* set_focus_window
*
* Change the focus window, sending the WM_SETFOCUS and WM_KILLFOCUS messages
*/
static HWND set_focus_window( HWND hwnd )
{
HWND previous = 0, ime_default;
BOOL ret;
SERVER_START_REQ( set_focus_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 0;
if (previous == hwnd) return previous;
if (previous)
{
SendMessageW( previous, WM_KILLFOCUS, (WPARAM)hwnd, 0 );
ime_default = ImmGetDefaultIMEWnd( previous );
if (ime_default)
SendMessageW( ime_default, WM_IME_INTERNAL, IME_INTERNAL_DEACTIVATE, (LPARAM)previous );
if (hwnd != GetFocus()) return previous; /* changed by the message */
}
if (IsWindow(hwnd))
{
USER_Driver->pSetFocus(hwnd);
ime_default = ImmGetDefaultIMEWnd( hwnd );
if (ime_default)
SendMessageW( ime_default, WM_IME_INTERNAL, IME_INTERNAL_ACTIVATE, (LPARAM)hwnd );
if (previous)
NtUserNotifyWinEvent( EVENT_OBJECT_FOCUS, hwnd, OBJID_CLIENT, 0 );
SendMessageW( hwnd, WM_SETFOCUS, (WPARAM)previous, 0 );
}
return previous;
}
/*******************************************************************
* 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 == NtUserGetForegroundWindow(), (LPARAM)previous );
SendMessageW( hwnd, WM_ACTIVATE,
MAKEWPARAM( mouse ? WA_CLICKACTIVE : WA_ACTIVE, IsIconic(hwnd) ),
(LPARAM)previous );
if (NtUserGetAncestor( hwnd, GA_PARENT ) == GetDesktopWindow())
PostMessageW( GetDesktopWindow(), WM_PARENTNOTIFY, WM_NCACTIVATE, (LPARAM)hwnd );
}
/* now change focus if necessary */
if (focus)
{
GUITHREADINFO info;
info.cbSize = sizeof(info);
NtUserGetGUIThreadInfo( GetCurrentThreadId(), &info );
/* Do not change focus if the window is no more active */
if (hwnd == info.hwndActive)
{
if (!info.hwndFocus || !hwnd || NtUserGetAncestor( info.hwndFocus, GA_ROOT ) != hwnd)
set_focus_window( hwnd );
}
}
return TRUE;
}
/*******************************************************************
* set_foreground_window
*/
static BOOL set_foreground_window( HWND hwnd, BOOL mouse )
{
BOOL ret, send_msg_old = FALSE, send_msg_new = FALSE;
HWND previous = 0;
SERVER_START_REQ( set_foreground_window )
{
req->handle = wine_server_user_handle( hwnd );
if ((ret = !wine_server_call_err( req )))
{
previous = wine_server_ptr_handle( reply->previous );
send_msg_old = reply->send_msg_old;
send_msg_new = reply->send_msg_new;
}
}
SERVER_END_REQ;
if (ret && previous != hwnd)
{
if (send_msg_old) /* old window belongs to other thread */
SendNotifyMessageW( previous, WM_WINE_SETACTIVEWINDOW, 0, 0 );
else if (send_msg_new) /* old window belongs to us but new one to other thread */
ret = set_active_window( 0, NULL, mouse, TRUE );
if (send_msg_new) /* new window belongs to other thread */
SendNotifyMessageW( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0 );
else /* new window belongs to us */
ret = set_active_window( hwnd, NULL, mouse, TRUE );
}
return ret;
}
/*******************************************************************
@ -231,7 +39,7 @@ static BOOL set_foreground_window( HWND hwnd, BOOL mouse )
*/
BOOL FOCUS_MouseActivate( HWND hwnd )
{
return set_foreground_window( hwnd, TRUE );
return NtUserCallHwndParam( hwnd, TRUE, NtUserSetForegroundWindow );
}
@ -240,10 +48,7 @@ BOOL FOCUS_MouseActivate( HWND hwnd )
*/
BOOL WINAPI SetForegroundWindow( HWND hwnd )
{
TRACE( "%p\n", hwnd );
hwnd = WIN_GetFullHandle( hwnd );
return set_foreground_window( hwnd, FALSE );
return NtUserCallHwndParam( hwnd, FALSE, NtUserSetForegroundWindow );
}

View File

@ -147,6 +147,7 @@ static const struct user_callbacks user_funcs =
RedrawWindow,
SendMessageTimeoutW,
SendMessageW,
SendNotifyMessageW,
SetWindowPos,
WaitForInputIdle,
WindowFromDC,

View File

@ -1329,3 +1329,42 @@ HWND WINAPI NtUserSetFocus( HWND hwnd )
/* change focus and send messages */
return set_focus_window( hwnd );
}
/*******************************************************************
* set_foreground_window
*/
BOOL set_foreground_window( HWND hwnd, BOOL mouse )
{
BOOL ret, send_msg_old = FALSE, send_msg_new = FALSE;
HWND previous = 0;
if (mouse) hwnd = get_full_window_handle( hwnd );
SERVER_START_REQ( set_foreground_window )
{
req->handle = wine_server_user_handle( hwnd );
if ((ret = !wine_server_call_err( req )))
{
previous = wine_server_ptr_handle( reply->previous );
send_msg_old = reply->send_msg_old;
send_msg_new = reply->send_msg_new;
}
}
SERVER_END_REQ;
if (ret && previous != hwnd)
{
if (send_msg_old) /* old window belongs to other thread */
NtUserMessageCall( previous, WM_WINE_SETACTIVEWINDOW, 0, 0,
0, FNID_SENDNOTIFYMESSAGE, FALSE );
else if (send_msg_new) /* old window belongs to us but new one to other thread */
ret = set_active_window( 0, NULL, mouse, TRUE );
if (send_msg_new) /* new window belongs to other thread */
NtUserMessageCall( hwnd, WM_WINE_SETACTIVEWINDOW, (WPARAM)hwnd, 0,
0, FNID_SENDNOTIFYMESSAGE, FALSE );
else /* new window belongs to us */
ret = set_active_window( hwnd, NULL, mouse, TRUE );
}
return ret;
}

View File

@ -125,6 +125,12 @@ LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
return user_callbacks->pSendMessageW( hwnd, msg, wparam, lparam );
}
/* see SendNotifyMessageW */
static BOOL send_notify_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam, BOOL ansi )
{
return user_callbacks && user_callbacks->pSendNotifyMessageW( hwnd, msg, wparam, lparam );
}
/* see PostMessageW */
LRESULT post_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
@ -132,3 +138,16 @@ LRESULT post_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
if (!user_callbacks) return 0;
return user_callbacks->pPostMessageW( hwnd, msg, wparam, lparam );
}
BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
ULONG_PTR result_info, DWORD type, BOOL ansi )
{
switch (type)
{
case FNID_SENDNOTIFYMESSAGE:
return send_notify_message( hwnd, msg, wparam, lparam, ansi );
default:
FIXME( "%p %x %lx %lx %lx %x %x\n", hwnd, msg, wparam, lparam, result_info, type, ansi );
}
return 0;
}

View File

@ -34,6 +34,7 @@ struct user_callbacks
BOOL (WINAPI *pRedrawWindow)( HWND, const RECT*, HRGN, UINT );
LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
LRESULT (WINAPI *pSendMessageW)( HWND, UINT, WPARAM, LPARAM );
BOOL (WINAPI *pSendNotifyMessageW)( HWND, UINT, WPARAM, LPARAM );
BOOL (WINAPI *pSetWindowPos)( HWND, HWND, INT, INT, INT, INT, UINT );
DWORD (WINAPI *pWaitForInputIdle)( HANDLE, DWORD );
HWND (WINAPI *pWindowFromDC)( HDC );

View File

@ -289,6 +289,7 @@ extern LONG global_key_state_counter DECLSPEC_HIDDEN;
extern HWND get_active_window(void) DECLSPEC_HIDDEN;
extern BOOL get_cursor_pos( POINT *pt ) DECLSPEC_HIDDEN;
extern DWORD get_input_state(void) DECLSPEC_HIDDEN;
extern BOOL set_foreground_window( HWND hwnd, BOOL mouse ) DECLSPEC_HIDDEN;
/* message.c */
extern LRESULT post_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam ) DECLSPEC_HIDDEN;

View File

@ -1945,6 +1945,8 @@ ULONG_PTR WINAPI NtUserCallHwndParam( HWND hwnd, DWORD_PTR param, DWORD code )
return is_child( hwnd, UlongToHandle(param) );
case NtUserMonitorFromWindow:
return HandleToUlong( monitor_from_window( hwnd, param, NtUserMonitorFromWindow ));
case NtUserSetForegroundWindow:
return set_foreground_window( hwnd, param );
/* temporary exports */
case NtUserIsWindowDrawable:
return is_window_drawable( hwnd, param );

View File

@ -173,10 +173,17 @@ enum
NtUserGetWindowWord,
NtUserIsChild,
NtUserMonitorFromWindow,
NtUserSetForegroundWindow,
/* temporary exports */
NtUserIsWindowDrawable,
};
/* NtUserMessageCall codes */
enum
{
FNID_SENDNOTIFYMESSAGE = 0x02b7,
};
/* color index used to retrieve system 55aa brush */
#define COLOR_55AA_BRUSH 0x100