win32u: Move NtUserCreateWindowEx 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-18 14:27:55 +01:00 committed by Alexandre Julliard
parent f2f07d5ba7
commit d765edc411
22 changed files with 616 additions and 824 deletions

View file

@ -42,8 +42,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(class);
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
#define CLASS_OTHER_PROCESS ((CLASS *)1)
static inline const char *debugstr_us( const UNICODE_STRING *us )
{
if (!us) return "<null>";
@ -351,15 +349,6 @@ void register_desktop_class(void)
}
/***********************************************************************
* get_class_winproc
*/
WNDPROC get_class_winproc( CLASS *class )
{
return class->winproc;
}
/***********************************************************************
* RegisterClassA (USER32.@)
*

View file

@ -114,7 +114,6 @@ struct tagWND;
extern ATOM get_int_atom_value( UNICODE_STRING *name ) DECLSPEC_HIDDEN;
extern void register_builtin_classes(void) DECLSPEC_HIDDEN;
extern void register_desktop_class(void) DECLSPEC_HIDDEN;
extern WNDPROC get_class_winproc( struct tagCLASS *class ) DECLSPEC_HIDDEN;
/* defwnd proc */
extern HBRUSH DEFWND_ControlColor( HDC hDC, UINT ctlType ) DECLSPEC_HIDDEN;

View file

@ -74,11 +74,6 @@ static void CDECL nulldrv_UpdateClipboard(void)
{
}
static BOOL CDECL nulldrv_CreateWindow( HWND hwnd )
{
return TRUE;
}
static DWORD CDECL nulldrv_MsgWaitForMultipleObjectsEx( DWORD count, const HANDLE *handles, DWORD timeout,
DWORD mask, DWORD flags )
{
@ -132,11 +127,6 @@ static void CDECL loaderdrv_UpdateClipboard(void)
load_driver()->pUpdateClipboard();
}
static BOOL CDECL loaderdrv_CreateWindow( HWND hwnd )
{
return load_driver()->pCreateWindow( hwnd );
}
static struct user_driver_funcs lazy_load_driver =
{
{ NULL },
@ -164,7 +154,7 @@ static struct user_driver_funcs lazy_load_driver =
NULL,
/* windowing functions */
NULL,
loaderdrv_CreateWindow,
NULL,
NULL,
NULL,
NULL,
@ -213,7 +203,6 @@ void CDECL __wine_set_user_driver( const struct user_driver_funcs *funcs, UINT v
SET_USER_FUNC(SetCursorPos);
SET_USER_FUNC(UpdateClipboard);
SET_USER_FUNC(CreateWindow);
SET_USER_FUNC(MsgWaitForMultipleObjectsEx);
SET_USER_FUNC(SetWindowIcon);
SET_USER_FUNC(SetWindowText);

View file

@ -140,7 +140,12 @@ static void CDECL notify_ime( HWND hwnd, UINT param )
if (ime_default) SendMessageW( ime_default, WM_IME_INTERNAL, param, HandleToUlong(hwnd) );
}
void WINAPI unregister_imm( HWND hwnd )
static BOOL WINAPI register_imm( HWND hwnd )
{
return imm_register_window( hwnd );
}
static void WINAPI unregister_imm( HWND hwnd )
{
imm_unregister_window( hwnd );
}
@ -149,7 +154,6 @@ static void CDECL free_win_ptr( WND *win )
{
HeapFree( GetProcessHeap(), 0, win->text );
HeapFree( GetProcessHeap(), 0, win->pScroll );
HeapFree( GetProcessHeap(), 0, win );
}
static const struct user_callbacks user_funcs =
@ -163,8 +167,10 @@ static const struct user_callbacks user_funcs =
PostMessageW,
SendInput,
SendMessageTimeoutW,
SendMessageA,
SendMessageW,
SendNotifyMessageW,
SetSystemMenu,
ShowCaret,
WaitForInputIdle,
free_win_ptr,
@ -172,9 +178,11 @@ static const struct user_callbacks user_funcs =
notify_ime,
register_builtin_classes,
MSG_SendInternalMessageTimeout,
MENU_SetMenu,
SCROLL_SetStandardScrollPainted,
(void *)__wine_set_user_driver,
set_window_pos,
register_imm,
unregister_imm,
};

View file

@ -128,9 +128,6 @@ extern BOOL USER_IsExitingThread( DWORD tid ) DECLSPEC_HIDDEN;
typedef LRESULT (*winproc_callback_t)( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp,
LRESULT *result, void *arg );
extern WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode ) DECLSPEC_HIDDEN;
extern BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val ) DECLSPEC_HIDDEN;
extern LRESULT WINPROC_CallProcAtoW( winproc_callback_t callback, HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam, LRESULT *result, void *arg,
enum wm_char_mapping mapping ) DECLSPEC_HIDDEN;

View file

@ -76,124 +76,6 @@ void *free_user_handle( HANDLE handle, unsigned int type )
}
/***********************************************************************
* create_window_handle
*
* Create a window handle with the server.
*/
static WND *create_window_handle( HWND parent, HWND owner, UNICODE_STRING *name,
HINSTANCE instance, BOOL unicode,
DWORD style, DWORD ex_style )
{
WND *win;
HWND handle = 0, full_parent = 0, full_owner = 0;
struct tagCLASS *class = NULL;
int extra_bytes = 0;
DPI_AWARENESS awareness = GetAwarenessFromDpiAwarenessContext( GetThreadDpiAwarenessContext() );
UINT dpi = 0;
SERVER_START_REQ( create_window )
{
req->parent = wine_server_user_handle( parent );
req->owner = wine_server_user_handle( owner );
req->instance = wine_server_client_ptr( instance );
req->dpi = GetDpiForSystem();
req->awareness = awareness;
req->style = style;
req->ex_style = ex_style;
if (!(req->atom = get_int_atom_value( name )) && name->Length)
wine_server_add_data( req, name->Buffer, name->Length );
if (!wine_server_call_err( req ))
{
handle = wine_server_ptr_handle( reply->handle );
full_parent = wine_server_ptr_handle( reply->parent );
full_owner = wine_server_ptr_handle( reply->owner );
extra_bytes = reply->extra;
dpi = reply->dpi;
awareness = reply->awareness;
class = wine_server_get_ptr( reply->class_ptr );
}
}
SERVER_END_REQ;
if (!handle)
{
WARN( "error %d creating window\n", GetLastError() );
return NULL;
}
if (!(win = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(WND) + extra_bytes - sizeof(win->wExtra) )))
{
SERVER_START_REQ( destroy_window )
{
req->handle = wine_server_user_handle( handle );
wine_server_call( req );
}
SERVER_END_REQ;
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return NULL;
}
if (!parent) /* if parent is 0 we don't have a desktop window yet */
{
struct user_thread_info *thread_info = get_user_thread_info();
if (name->Buffer == (LPCWSTR)DESKTOP_CLASS_ATOM)
{
if (!thread_info->top_window) thread_info->top_window = full_parent ? full_parent : handle;
else assert( full_parent == thread_info->top_window );
if (full_parent && !NtUserCallHwnd( thread_info->top_window, NtUserCreateDesktopWindow ))
ERR( "failed to create desktop window\n" );
register_builtin_classes();
}
else /* HWND_MESSAGE parent */
{
if (!thread_info->msg_window && !full_parent) thread_info->msg_window = handle;
}
}
USER_Lock();
win->obj.handle = handle;
win->obj.type = NTUSER_OBJ_WINDOW;
win->parent = full_parent;
win->owner = full_owner;
win->class = class;
win->winproc = get_class_winproc( class );
win->cbWndExtra = extra_bytes;
win->dpi = dpi;
win->dpi_awareness = awareness;
NtUserCallTwoParam( HandleToUlong(handle), (UINT_PTR)win, NtUserSetHandlePtr );
if (WINPROC_IsUnicode( win->winproc, unicode )) win->flags |= WIN_ISUNICODE;
return win;
}
/***********************************************************************
* free_window_handle
*
* Free a window handle.
*/
static void free_window_handle( HWND hwnd )
{
struct user_object *ptr;
if ((ptr = get_user_handle_ptr( hwnd, NTUSER_OBJ_WINDOW )) && ptr != OBJ_OTHER_PROCESS)
{
SERVER_START_REQ( destroy_window )
{
req->handle = wine_server_user_handle( hwnd );
wine_server_call( req );
NtUserCallTwoParam( HandleToUlong(hwnd), 0, NtUserSetHandlePtr );
}
SERVER_END_REQ;
USER_Unlock();
HeapFree( GetProcessHeap(), 0, ptr );
}
}
/*******************************************************************
* list_window_children
*
@ -242,22 +124,6 @@ static HWND *list_window_children( HDESK desktop, HWND hwnd, UNICODE_STRING *cla
}
/*******************************************************************
* send_parent_notify
*/
static void send_parent_notify( HWND hwnd, UINT msg )
{
if ((GetWindowLongW( hwnd, GWL_STYLE ) & (WS_CHILD | WS_POPUP)) == WS_CHILD &&
!(GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_NOPARENTNOTIFY))
{
HWND parent = GetParent(hwnd);
if (parent && parent != GetDesktopWindow())
SendMessageW( parent, WM_PARENTNOTIFY,
MAKEWPARAM( msg, GetWindowLongPtrW( hwnd, GWLP_ID )), (LPARAM)hwnd );
}
}
/*******************************************************************
* get_hwnd_message_parent
*
@ -707,66 +573,6 @@ other_process:
}
/***********************************************************************
* WIN_FixCoordinates
*
* Fix the coordinates - Helper for WIN_CreateWindowEx.
* returns default show mode in sw.
*/
static void WIN_FixCoordinates( CREATESTRUCTW *cs, INT *sw)
{
#define IS_DEFAULT(x) ((x) == CW_USEDEFAULT || (x) == (SHORT)0x8000)
if (cs->style & (WS_CHILD | WS_POPUP))
{
if (IS_DEFAULT(cs->x)) cs->x = cs->y = 0;
if (IS_DEFAULT(cs->cx)) cs->cx = cs->cy = 0;
}
else /* overlapped window */
{
HMONITOR monitor;
MONITORINFO mon_info;
STARTUPINFOW info;
if (!IS_DEFAULT(cs->x) && !IS_DEFAULT(cs->cx) && !IS_DEFAULT(cs->cy)) return;
monitor = MonitorFromWindow( cs->hwndParent, MONITOR_DEFAULTTOPRIMARY );
mon_info.cbSize = sizeof(mon_info);
GetMonitorInfoW( monitor, &mon_info );
GetStartupInfoW( &info );
if (IS_DEFAULT(cs->x))
{
if (!IS_DEFAULT(cs->y)) *sw = cs->y;
cs->x = (info.dwFlags & STARTF_USEPOSITION) ? info.dwX : mon_info.rcWork.left;
cs->y = (info.dwFlags & STARTF_USEPOSITION) ? info.dwY : mon_info.rcWork.top;
}
if (IS_DEFAULT(cs->cx))
{
if (info.dwFlags & STARTF_USESIZE)
{
cs->cx = info.dwXSize;
cs->cy = info.dwYSize;
}
else
{
cs->cx = (mon_info.rcWork.right - mon_info.rcWork.left) * 3 / 4 - cs->x;
cs->cy = (mon_info.rcWork.bottom - mon_info.rcWork.top) * 3 / 4 - cs->y;
}
}
/* neither x nor cx are default. Check the y values .
* In the trace we see Outlook and Outlook Express using
* cy set to CW_USEDEFAULT when opening the address book.
*/
else if (IS_DEFAULT(cs->cy))
{
FIXME("Strange use of CW_USEDEFAULT in nHeight\n");
cs->cy = (mon_info.rcWork.bottom - mon_info.rcWork.top) * 3 / 4 - cs->y;
}
}
#undef IS_DEFAULT
}
/***********************************************************************
* dump_window_styles
*/
@ -885,40 +691,6 @@ static BOOL is_default_coord( int x )
return x == CW_USEDEFAULT || x == 0x8000;
}
/***********************************************************************
* map_dpi_create_struct
*/
static void map_dpi_create_struct( CREATESTRUCTW *cs, UINT dpi_from, UINT dpi_to )
{
if (!dpi_from && !dpi_to) return;
if (!dpi_from || !dpi_to)
{
POINT pt = { cs->x, cs->y };
UINT mon_dpi = get_monitor_dpi( MonitorFromPoint( pt, MONITOR_DEFAULTTONEAREST ));
if (!dpi_from) dpi_from = mon_dpi;
else dpi_to = mon_dpi;
}
if (dpi_from == dpi_to) return;
cs->x = MulDiv( cs->x, dpi_to, dpi_from );
cs->y = MulDiv( cs->y, dpi_to, dpi_from );
cs->cx = MulDiv( cs->cx, dpi_to, dpi_from );
cs->cy = MulDiv( cs->cy, dpi_to, dpi_from );
}
/***********************************************************************
* fix_exstyle
*/
static DWORD fix_exstyle( DWORD style, DWORD exstyle )
{
if ((exstyle & WS_EX_DLGMODALFRAME) ||
(!(exstyle & WS_EX_STATICEDGE) &&
(style & (WS_DLGFRAME | WS_THICKFRAME))))
exstyle |= WS_EX_WINDOWEDGE;
else
exstyle &= ~WS_EX_WINDOWEDGE;
return exstyle;
}
/***********************************************************************
* WIN_CreateWindowEx
*
@ -926,19 +698,14 @@ static DWORD fix_exstyle( DWORD style, DWORD exstyle )
*/
HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module, BOOL unicode )
{
INT cx, cy, style, ex_style, sw = SW_SHOW;
LRESULT result;
RECT rect;
WND *wndPtr;
HWND hwnd, parent, owner, top_child = 0;
UINT win_dpi, thread_dpi = get_thread_dpi();
DPI_AWARENESS_CONTEXT context;
HWND hwnd, top_child = 0;
MDICREATESTRUCTW mdi_cs;
UNICODE_STRING class;
CBT_CREATEWNDW cbtc;
CREATESTRUCTW cbcs;
WNDCLASSEXW info;
HMENU menu;
if (!get_class_info( module, className, NULL, &class, FALSE )) return FALSE;
if (!get_class_info( module, className, &info, &class, FALSE )) return FALSE;
TRACE("%s %s%s%s ex=%08x style=%08x %d,%d %dx%d parent=%p menu=%p inst=%p params=%p\n",
unicode ? debugstr_w(cs->lpszName) : debugstr_a((LPCSTR)cs->lpszName),
@ -1030,300 +797,25 @@ HWND WIN_CreateWindowEx( CREATESTRUCTW *cs, LPCWSTR className, HINSTANCE module,
}
}
/* Find the parent window */
parent = cs->hwndParent;
owner = 0;
if (cs->hwndParent == HWND_MESSAGE)
/* FIXME: move to win32u */
if (!cs->hwndParent && className != (const WCHAR *)DESKTOP_CLASS_ATOM &&
(IS_INTRESOURCE(className) || wcsicmp( className, L"Message" )))
{
cs->hwndParent = parent = get_hwnd_message_parent();
}
else if (cs->hwndParent)
{
if ((cs->style & (WS_CHILD|WS_POPUP)) != WS_CHILD)
{
parent = GetDesktopWindow();
owner = cs->hwndParent;
}
else
{
DWORD parent_style = GetWindowLongW( parent, GWL_EXSTYLE );
if ((parent_style & WS_EX_LAYOUTRTL) && !(parent_style & WS_EX_NOINHERITLAYOUT))
cs->dwExStyle |= WS_EX_LAYOUTRTL;
}
}
else
{
if ((cs->style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
{
WARN("No parent for child window\n" );
SetLastError(ERROR_TLW_WITH_WSCHILD);
return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
}
/* are we creating the desktop or HWND_MESSAGE parent itself? */
if (className != (LPCWSTR)DESKTOP_CLASS_ATOM &&
(IS_INTRESOURCE(className) || wcsicmp( className, L"Message" )))
{
DWORD layout;
GetProcessDefaultLayout( &layout );
if (layout & LAYOUT_RTL) cs->dwExStyle |= WS_EX_LAYOUTRTL;
parent = GetDesktopWindow();
}
DWORD layout;
GetProcessDefaultLayout( &layout );
if (layout & LAYOUT_RTL) cs->dwExStyle |= WS_EX_LAYOUTRTL;
}
WIN_FixCoordinates(cs, &sw); /* fix default coordinates */
cs->dwExStyle = fix_exstyle(cs->style, cs->dwExStyle);
menu = cs->hMenu;
if (!menu && info.lpszMenuName && (cs->style & (WS_CHILD | WS_POPUP)) != WS_CHILD)
menu = LoadMenuW( cs->hInstance, info.lpszMenuName );
/* Create the window structure */
style = cs->style & ~WS_VISIBLE;
ex_style = cs->dwExStyle & ~WS_EX_LAYERED;
if (!(wndPtr = create_window_handle( parent, owner, &class, module,
unicode, style, ex_style )))
return 0;
hwnd = wndPtr->obj.handle;
/* Fill the window structure */
wndPtr->tid = GetCurrentThreadId();
wndPtr->hInstance = cs->hInstance;
wndPtr->text = NULL;
wndPtr->dwStyle = style;
wndPtr->dwExStyle = ex_style;
wndPtr->wIDmenu = 0;
wndPtr->helpContext = 0;
wndPtr->pScroll = NULL;
wndPtr->userdata = 0;
wndPtr->hIcon = 0;
wndPtr->hIconSmall = 0;
wndPtr->hIconSmall2 = 0;
wndPtr->hSysMenu = 0;
wndPtr->min_pos.x = wndPtr->min_pos.y = -1;
wndPtr->max_pos.x = wndPtr->max_pos.y = -1;
SetRect( &wndPtr->normal_rect, cs->x, cs->y, cs->x + cs->cx, cs->y + cs->cy );
if (wndPtr->dwStyle & WS_SYSMENU) SetSystemMenu( hwnd, 0 );
/* call the WH_CBT hook */
WIN_ReleasePtr( wndPtr );
cbcs = *cs;
cbtc.lpcs = &cbcs;
cbtc.hwndInsertAfter = HWND_TOP;
if (HOOK_CallHooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)&cbtc, unicode ) ||
!(wndPtr = WIN_GetPtr( hwnd )))
{
free_window_handle( hwnd );
return 0;
}
/*
* Correct the window styles.
*
* It affects only the style loaded into the WIN structure.
*/
if ((wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
{
wndPtr->dwStyle |= WS_CLIPSIBLINGS;
if (!(wndPtr->dwStyle & WS_POPUP))
wndPtr->dwStyle |= WS_CAPTION;
}
wndPtr->dwExStyle = cs->dwExStyle;
/* WS_EX_WINDOWEDGE depends on some other styles */
if ((wndPtr->dwStyle & (WS_DLGFRAME | WS_THICKFRAME)) &&
!(wndPtr->dwStyle & (WS_CHILD | WS_POPUP)))
wndPtr->dwExStyle |= WS_EX_WINDOWEDGE;
if (!(wndPtr->dwStyle & (WS_CHILD | WS_POPUP)))
wndPtr->flags |= WIN_NEED_SIZE;
SERVER_START_REQ( set_window_info )
{
req->handle = wine_server_user_handle( hwnd );
req->flags = SET_WIN_STYLE | SET_WIN_EXSTYLE | SET_WIN_INSTANCE | SET_WIN_UNICODE;
req->style = wndPtr->dwStyle;
req->ex_style = wndPtr->dwExStyle;
req->instance = wine_server_client_ptr( wndPtr->hInstance );
req->is_unicode = (wndPtr->flags & WIN_ISUNICODE) != 0;
req->extra_offset = -1;
wine_server_call( req );
}
SERVER_END_REQ;
/* Set the window menu */
if ((wndPtr->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
{
if (cs->hMenu)
{
if (!MENU_SetMenu(hwnd, cs->hMenu))
{
WIN_ReleasePtr( wndPtr );
free_window_handle( hwnd );
return 0;
}
}
else
{
LPCWSTR menuName = (LPCWSTR)GetClassLongPtrW( hwnd, GCLP_MENUNAME );
if (menuName)
{
cs->hMenu = LoadMenuW( cs->hInstance, menuName );
if (cs->hMenu) MENU_SetMenu( hwnd, cs->hMenu );
}
}
}
else SetWindowLongPtrW( hwnd, GWLP_ID, (ULONG_PTR)cs->hMenu );
win_dpi = wndPtr->dpi;
WIN_ReleasePtr( wndPtr );
if (parent) map_dpi_create_struct( cs, thread_dpi, win_dpi );
context = SetThreadDpiAwarenessContext( GetWindowDpiAwarenessContext( hwnd ));
/* send the WM_GETMINMAXINFO message and fix the size if needed */
cx = cs->cx;
cy = cs->cy;
if ((cs->style & WS_THICKFRAME) || !(cs->style & (WS_POPUP | WS_CHILD)))
{
MINMAXINFO info = WINPOS_GetMinMaxInfo( hwnd );
cx = max( min( cx, info.ptMaxTrackSize.x ), info.ptMinTrackSize.x );
cy = max( min( cy, info.ptMaxTrackSize.y ), info.ptMinTrackSize.y );
}
if (cx < 0) cx = 0;
if (cy < 0) cy = 0;
SetRect( &rect, cs->x, cs->y, cs->x + cx, cs->y + cy );
/* check for wraparound */
if (cs->x > 0x7fffffff - cx) rect.right = 0x7fffffff;
if (cs->y > 0x7fffffff - cy) rect.bottom = 0x7fffffff;
if (!set_window_pos( hwnd, 0, SWP_NOZORDER | SWP_NOACTIVATE, &rect, &rect, NULL )) goto failed;
/* send WM_NCCREATE */
TRACE( "hwnd %p cs %d,%d %dx%d %s\n", hwnd, cs->x, cs->y, cs->cx, cs->cy, wine_dbgstr_rect(&rect) );
if (unicode)
result = SendMessageW( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
else
result = SendMessageA( hwnd, WM_NCCREATE, 0, (LPARAM)cs );
if (!result)
{
WARN( "%p: aborted by WM_NCCREATE\n", hwnd );
goto failed;
}
/* create default IME window */
if (imm_register_window && !is_desktop_window( hwnd ) &&
parent != get_hwnd_message_parent() && imm_register_window( hwnd ))
{
TRACE("register IME window for %p\n", hwnd);
win_set_flags( hwnd, WIN_HAS_IME_WIN, 0 );
}
/* send WM_NCCALCSIZE */
if (WIN_GetRectangles( hwnd, COORDS_PARENT, &rect, NULL ))
{
/* yes, even if the CBT hook was called with HWND_TOP */
HWND insert_after = (GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
RECT client_rect = rect;
/* the rectangle is in screen coords for WM_NCCALCSIZE when wparam is FALSE */
MapWindowPoints( parent, 0, (POINT *)&client_rect, 2 );
SendMessageW( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&client_rect );
MapWindowPoints( 0, parent, (POINT *)&client_rect, 2 );
set_window_pos( hwnd, insert_after, SWP_NOACTIVATE, &rect, &client_rect, NULL );
}
else goto failed;
/* send WM_CREATE */
if (unicode)
result = SendMessageW( hwnd, WM_CREATE, 0, (LPARAM)cs );
else
result = SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs );
if (result == -1) goto failed;
/* call the driver */
if (!USER_Driver->pCreateWindow( hwnd )) goto failed;
NtUserNotifyWinEvent( EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0 );
/* send the size messages */
if (!(win_get_flags( hwnd ) & WIN_NEED_SIZE))
{
WIN_GetRectangles( hwnd, COORDS_PARENT, NULL, &rect );
SendMessageW( hwnd, WM_SIZE, SIZE_RESTORED,
MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
SendMessageW( hwnd, WM_MOVE, 0, MAKELONG( rect.left, rect.top ) );
}
/* Show the window, maximizing or minimizing if needed */
style = WIN_SetStyle( hwnd, 0, WS_MAXIMIZE | WS_MINIMIZE );
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
RECT newPos;
UINT swFlag = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
swFlag = WINPOS_MinMaximize( hwnd, swFlag, &newPos );
swFlag |= SWP_FRAMECHANGED; /* Frame always gets changed */
if (!(style & WS_VISIBLE) || (style & WS_CHILD) || GetActiveWindow()) swFlag |= SWP_NOACTIVATE;
NtUserSetWindowPos( hwnd, 0, newPos.left, newPos.top, newPos.right - newPos.left,
newPos.bottom - newPos.top, swFlag );
}
/* Notify the parent window only */
send_parent_notify( hwnd, WM_CREATE );
if (!IsWindow( hwnd ))
{
SetThreadDpiAwarenessContext( context );
return 0;
}
if (parent == GetDesktopWindow())
PostMessageW( parent, WM_PARENTNOTIFY, WM_CREATE, (LPARAM)hwnd );
if (cs->style & WS_VISIBLE)
{
if (cs->style & WS_MAXIMIZE)
sw = SW_SHOW;
else if (cs->style & WS_MINIMIZE)
sw = SW_SHOWMINIMIZED;
NtUserShowWindow( hwnd, sw );
if (cs->dwExStyle & WS_EX_MDICHILD)
{
SendMessageW(cs->hwndParent, WM_MDIREFRESHMENU, 0, 0);
/* ShowWindow won't activate child windows */
NtUserSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE );
}
}
/* Call WH_SHELL hook */
if (!(GetWindowLongW( hwnd, GWL_STYLE ) & WS_CHILD) && !GetWindow( hwnd, GW_OWNER ))
HOOK_CallHooks( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0, TRUE );
TRACE("created window %p\n", hwnd);
SetThreadDpiAwarenessContext( context );
cbtc.lpcs = cs;
hwnd = NtUserCreateWindowEx( cs->dwExStyle, &class, NULL, NULL, cs->style, cs->x, cs->y,
cs->cx, cs->cy, cs->hwndParent, menu, module,
cs->lpCreateParams, 0, &cbtc, 0, !unicode );
if (!hwnd && menu && menu != cs->hMenu) DestroyMenu( menu );
return hwnd;
failed:
NtUserCallHwnd( hwnd, NtUserDestroyWindowHandle );
SetThreadDpiAwarenessContext( context );
return 0;
}

View file

@ -66,7 +66,6 @@ extern MINMAXINFO WINPOS_GetMinMaxInfo( HWND hwnd ) DECLSPEC_HIDDEN;
extern LONG WINPOS_HandleWindowPosChanging(HWND hwnd, WINDOWPOS *winpos) DECLSPEC_HIDDEN;
extern HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest ) DECLSPEC_HIDDEN;
extern void WINPOS_ActivateOtherWindow( HWND hwnd ) DECLSPEC_HIDDEN;
extern UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect ) DECLSPEC_HIDDEN;
extern void WINPOS_SysCommandSizeMove( HWND hwnd, WPARAM wParam ) DECLSPEC_HIDDEN;
extern UINT get_monitor_dpi( HMONITOR monitor ) DECLSPEC_HIDDEN;

View file

@ -622,182 +622,6 @@ static void get_next_minimized_child_pos( const RECT *parent, const MINIMIZEDMET
}
}
static POINT get_minimized_pos( HWND hwnd, POINT pt )
{
RECT rect, rectParent;
HWND parent, child;
HRGN hrgn, tmp;
MINIMIZEDMETRICS metrics;
int width, height;
parent = NtUserGetAncestor( hwnd, GA_PARENT );
if (parent == GetDesktopWindow())
{
MONITORINFO mon_info;
HMONITOR monitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY );
mon_info.cbSize = sizeof( mon_info );
GetMonitorInfoW( monitor, &mon_info );
rectParent = mon_info.rcWork;
}
else GetClientRect( parent, &rectParent );
if ((pt.x >= rectParent.left) && (pt.x + GetSystemMetrics( SM_CXMINIMIZED ) < rectParent.right) &&
(pt.y >= rectParent.top) && (pt.y + GetSystemMetrics( SM_CYMINIMIZED ) < rectParent.bottom))
return pt; /* The icon already has a suitable position */
width = GetSystemMetrics( SM_CXMINIMIZED );
height = GetSystemMetrics( SM_CYMINIMIZED );
metrics.cbSize = sizeof(metrics);
SystemParametersInfoW( SPI_GETMINIMIZEDMETRICS, sizeof(metrics), &metrics, 0 );
/* Check if another icon already occupies this spot */
/* FIXME: this is completely inefficient */
hrgn = CreateRectRgn( 0, 0, 0, 0 );
tmp = CreateRectRgn( 0, 0, 0, 0 );
for (child = GetWindow( parent, GW_CHILD ); child; child = GetWindow( child, GW_HWNDNEXT ))
{
if (child == hwnd) continue;
if ((GetWindowLongW( child, GWL_STYLE ) & (WS_VISIBLE|WS_MINIMIZE)) != (WS_VISIBLE|WS_MINIMIZE))
continue;
if (WIN_GetRectangles( child, COORDS_PARENT, &rect, NULL ))
{
SetRectRgn( tmp, rect.left, rect.top, rect.right, rect.bottom );
CombineRgn( hrgn, hrgn, tmp, RGN_OR );
}
}
DeleteObject( tmp );
pt = get_first_minimized_child_pos( &rectParent, &metrics, width, height );
for (;;)
{
SetRect( &rect, pt.x, pt.y, pt.x + width, pt.y + height );
if (!RectInRegion( hrgn, &rect ))
break;
get_next_minimized_child_pos( &rectParent, &metrics, width, height, &pt );
}
DeleteObject( hrgn );
return pt;
}
/***********************************************************************
* WINPOS_MinMaximize
*/
UINT WINPOS_MinMaximize( HWND hwnd, UINT cmd, LPRECT rect )
{
UINT swpFlags = 0;
LONG old_style;
MINMAXINFO minmax;
WINDOWPLACEMENT wpl;
TRACE("%p %u\n", hwnd, cmd );
wpl.length = sizeof(wpl);
GetWindowPlacement( hwnd, &wpl );
if (HOOK_CallHooks( WH_CBT, HCBT_MINMAX, (WPARAM)hwnd, cmd, TRUE ))
return SWP_NOSIZE | SWP_NOMOVE;
if (IsIconic( hwnd ))
{
switch (cmd)
{
case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
wpl.ptMinPosition = get_minimized_pos( hwnd, wpl.ptMinPosition );
SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
wpl.ptMinPosition.x + GetSystemMetrics(SM_CXMINIMIZED),
wpl.ptMinPosition.y + GetSystemMetrics(SM_CYMINIMIZED) );
return SWP_NOSIZE | SWP_NOMOVE;
}
if (!SendMessageW( hwnd, WM_QUERYOPEN, 0, 0 )) return SWP_NOSIZE | SWP_NOMOVE;
swpFlags |= SWP_NOCOPYBITS;
}
switch( cmd )
{
case SW_SHOWMINNOACTIVE:
case SW_SHOWMINIMIZED:
case SW_FORCEMINIMIZE:
case SW_MINIMIZE:
if (IsZoomed( hwnd )) win_set_flags( hwnd, WIN_RESTORE_MAX, 0 );
else win_set_flags( hwnd, 0, WIN_RESTORE_MAX );
if (GetFocus() == hwnd)
{
if (GetWindowLongW(hwnd, GWL_STYLE) & WS_CHILD)
NtUserSetFocus( NtUserGetAncestor( hwnd, GA_PARENT ));
else
NtUserSetFocus( 0 );
}
old_style = WIN_SetStyle( hwnd, WS_MINIMIZE, WS_MAXIMIZE );
wpl.ptMinPosition = get_minimized_pos( hwnd, wpl.ptMinPosition );
if (!(old_style & WS_MINIMIZE)) swpFlags |= SWP_STATECHANGED;
SetRect( rect, wpl.ptMinPosition.x, wpl.ptMinPosition.y,
wpl.ptMinPosition.x + GetSystemMetrics(SM_CXMINIMIZED),
wpl.ptMinPosition.y + GetSystemMetrics(SM_CYMINIMIZED) );
swpFlags |= SWP_NOCOPYBITS;
break;
case SW_MAXIMIZE:
old_style = GetWindowLongW( hwnd, GWL_STYLE );
if ((old_style & WS_MAXIMIZE) && (old_style & WS_VISIBLE)) return SWP_NOSIZE | SWP_NOMOVE;
minmax = WINPOS_GetMinMaxInfo( hwnd );
old_style = WIN_SetStyle( hwnd, WS_MAXIMIZE, WS_MINIMIZE );
if (old_style & WS_MINIMIZE)
win_set_flags( hwnd, WIN_RESTORE_MAX, 0 );
if (!(old_style & WS_MAXIMIZE)) swpFlags |= SWP_STATECHANGED;
SetRect( rect, minmax.ptMaxPosition.x, minmax.ptMaxPosition.y,
minmax.ptMaxPosition.x + minmax.ptMaxSize.x, minmax.ptMaxPosition.y + minmax.ptMaxSize.y );
break;
case SW_SHOWNOACTIVATE:
win_set_flags( hwnd, 0, WIN_RESTORE_MAX );
/* fall through */
case SW_SHOWNORMAL:
case SW_RESTORE:
case SW_SHOWDEFAULT: /* FIXME: should have its own handler */
old_style = WIN_SetStyle( hwnd, 0, WS_MINIMIZE | WS_MAXIMIZE );
if (old_style & WS_MINIMIZE)
{
if (win_get_flags( hwnd ) & WIN_RESTORE_MAX)
{
/* Restore to maximized position */
minmax = WINPOS_GetMinMaxInfo( hwnd );
WIN_SetStyle( hwnd, WS_MAXIMIZE, 0 );
swpFlags |= SWP_STATECHANGED;
SetRect( rect, minmax.ptMaxPosition.x, minmax.ptMaxPosition.y,
minmax.ptMaxPosition.x + minmax.ptMaxSize.x, minmax.ptMaxPosition.y + minmax.ptMaxSize.y );
break;
}
}
else if (!(old_style & WS_MAXIMIZE)) break;
swpFlags |= SWP_STATECHANGED;
/* Restore to normal position */
*rect = wpl.rcNormalPosition;
break;
}
return swpFlags;
}
/***********************************************************************
* GetInternalWindowPos (USER32.@)

View file

@ -161,29 +161,6 @@ static LRESULT call_dialog_proc( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp, LRES
}
/**********************************************************************
* WINPROC_GetProc
*
* Get a window procedure pointer that can be passed to the Windows program.
*/
WNDPROC WINPROC_GetProc( WNDPROC proc, BOOL unicode )
{
WINDOWPROC *ptr = handle_to_proc( proc );
if (!ptr || ptr == WINPROC_PROC16) return proc;
if (unicode)
{
if (ptr->procW) return ptr->procW;
return proc;
}
else
{
if (ptr->procA) return ptr->procA;
return proc;
}
}
/**********************************************************************
* WINPROC_AllocProc
*
@ -199,22 +176,6 @@ static WNDPROC WINPROC_AllocProc( WNDPROC func, BOOL unicode )
}
/**********************************************************************
* WINPROC_IsUnicode
*
* Return the window procedure type, or the default value if not a winproc handle.
*/
BOOL WINPROC_IsUnicode( WNDPROC proc, BOOL def_val )
{
WINDOWPROC *ptr = handle_to_proc( proc );
if (!ptr) return def_val;
if (ptr == WINPROC_PROC16) return FALSE; /* 16-bit is always A */
if (ptr->procA && ptr->procW) return def_val; /* can be both */
return (ptr->procW != NULL);
}
/**********************************************************************
* WINPROC_TestLBForStr
*

View file

@ -39,6 +39,27 @@ WINE_DECLARE_DEBUG_CHANNEL(win);
#define MAX_WINPROCS 4096
#define WINPROC_PROC16 ((WINDOWPROC *)1) /* placeholder for 16-bit window procs */
typedef struct tagCLASS
{
struct list entry; /* Entry in class list */
UINT style; /* Class style */
BOOL local; /* Local class? */
WNDPROC winproc; /* Window procedure */
INT cbClsExtra; /* Class extra bytes */
INT cbWndExtra; /* Window extra bytes */
struct dce *dce; /* Opaque pointer to class DCE */
UINT_PTR instance; /* Module that created the task */
HICON hIcon; /* Default icon */
HICON hIconSm; /* Default small icon */
HICON hIconSmIntern; /* Internal small icon, derived from hIcon */
HCURSOR hCursor; /* Default cursor */
HBRUSH hbrBackground; /* Default background */
ATOM atomName; /* Name of the class */
WCHAR name[MAX_ATOM_LEN + 1];
WCHAR *basename; /* Base name for redirected classes, pointer within 'name'. */
struct client_menu_name menu_name; /* Default menu name */
} CLASS;
static WINDOWPROC winproc_array[MAX_WINPROCS];
static UINT winproc_used = NB_BUILTIN_WINPROCS;
static pthread_mutex_t winproc_lock = PTHREAD_MUTEX_INITIALIZER;
@ -283,6 +304,14 @@ static CLASS *find_class( HINSTANCE module, UNICODE_STRING *name )
return NULL;
}
/***********************************************************************
* get_class_winproc
*/
WNDPROC get_class_winproc( CLASS *class )
{
return class->winproc;
}
/***********************************************************************
* get_class_dce
*/

View file

@ -34,6 +34,17 @@
WINE_DEFAULT_DEBUG_CHANNEL(win);
struct dce
{
struct list entry; /* entry in global DCE list */
HDC hdc;
HWND hwnd;
HRGN clip_rgn;
DWORD flags;
LONG count; /* usage count; 0 or 1 for cache DCEs, always 1 for window DCEs,
always >= 1 for class DCEs */
};
static struct list dce_list = LIST_INIT(dce_list);
#define DCE_CACHE_SIZE 64

View file

@ -1132,6 +1132,11 @@ static BOOL CDECL loaderdrv_CreateDesktopWindow( HWND hwnd )
return load_driver()->pCreateDesktopWindow( hwnd );
}
static BOOL CDECL loaderdrv_CreateWindow( HWND hwnd )
{
return load_driver()->pCreateWindow( hwnd );
}
static void CDECL loaderdrv_GetDC( HDC hdc, HWND hwnd, HWND top_win, const RECT *win_rect,
const RECT *top_rect, DWORD flags )
{
@ -1190,6 +1195,7 @@ static const struct user_driver_funcs lazy_load_driver =
.pUpdateDisplayDevices = loaderdrv_UpdateDisplayDevices,
/* windowing functions */
.pCreateDesktopWindow = loaderdrv_CreateDesktopWindow,
.pCreateWindow = loaderdrv_CreateWindow,
.pDestroyWindow = nulldrv_DestroyWindow,
.pFlashWindowEx = loaderdrv_FlashWindowEx,
.pGetDC = loaderdrv_GetDC,

View file

@ -1160,6 +1160,7 @@ static struct unix_funcs unix_funcs =
NtUserChangeDisplaySettings,
NtUserClipCursor,
NtUserCountClipboardFormats,
NtUserCreateWindowEx,
NtUserDeferWindowPosAndBand,
NtUserDestroyCursor,
NtUserDestroyWindow,

View file

@ -119,3 +119,11 @@ BOOL WINAPI NtUserDestroyMenu( HMENU menu )
{
return user_callbacks && user_callbacks->pDestroyMenu( menu );
}
/*******************************************************************
* NtUserSetSystemMenu (win32u.@)
*/
BOOL WINAPI NtUserSetSystemMenu( HWND hwnd, HMENU menu )
{
return user_callbacks && user_callbacks->pSetSystemMenu( hwnd, menu );
}

View file

@ -231,12 +231,23 @@ BOOL kill_system_timer( HWND hwnd, UINT_PTR id )
return ret;
}
static BOOL send_window_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam,
LRESULT *result, BOOL ansi )
{
/* FIXME: move implementation from user32 */
if (!user_callbacks) return FALSE;
*result = ansi
? user_callbacks->pSendMessageA( hwnd, msg, wparam, lparam )
: user_callbacks->pSendMessageW( hwnd, msg, wparam, lparam );
return TRUE;
}
/* see SendMessageW */
LRESULT send_message( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
/* FIXME: move implementation from user32 */
if (!user_callbacks) return 0;
return user_callbacks->pSendMessageW( hwnd, msg, wparam, lparam );
LRESULT result = 0;
send_window_message( hwnd, msg, wparam, lparam, &result, FALSE );
return result;
}
/* see SendNotifyMessageW */
@ -258,6 +269,8 @@ BOOL WINAPI NtUserMessageCall( HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam
{
switch (type)
{
case FNID_SENDMESSAGE:
return send_window_message( hwnd, msg, wparam, lparam, (LRESULT *)result_info, ansi );
case FNID_SENDNOTIFYMESSAGE:
return send_notify_message( hwnd, msg, wparam, lparam, ansi );
default:

View file

@ -39,8 +39,10 @@ struct user_callbacks
BOOL (WINAPI *pPostMessageW)( HWND, UINT, WPARAM, LPARAM );
UINT (WINAPI *pSendInput)( UINT count, INPUT *inputs, int size );
LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
LRESULT (WINAPI *pSendMessageA)( HWND, UINT, WPARAM, LPARAM );
LRESULT (WINAPI *pSendMessageW)( HWND, UINT, WPARAM, LPARAM );
BOOL (WINAPI *pSendNotifyMessageW)( HWND, UINT, WPARAM, LPARAM );
BOOL (WINAPI *pSetSystemMenu)( HWND hwnd, HMENU menu );
BOOL (WINAPI *pShowCaret)( HWND hwnd );
DWORD (WINAPI *pWaitForInputIdle)( HANDLE, DWORD );
void (CDECL *free_win_ptr)( struct tagWND *win );
@ -48,11 +50,13 @@ struct user_callbacks
void (CDECL *notify_ime)( HWND hwnd, UINT param );
void (CDECL *register_builtin_classes)(void);
LRESULT (WINAPI *send_ll_message)( DWORD, DWORD, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
BOOL (CDECL *set_menu)( HWND hwnd, HMENU menu );
void (WINAPI *set_standard_scroll_painted)( HWND hwnd, INT bar, BOOL visible );
void (CDECL *set_user_driver)( void *, UINT );
BOOL (CDECL *set_window_pos)( HWND hwnd, HWND insert_after, UINT swp_flags,
const RECT *window_rect, const RECT *client_rect,
const RECT *valid_rects );
BOOL (WINAPI *register_imm)( HWND hwnd );
void (WINAPI *unregister_imm)( HWND hwnd );
};
@ -69,7 +73,6 @@ struct user_object
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type ) DECLSPEC_HIDDEN;
void *get_user_handle_ptr( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
void set_user_handle_ptr( HANDLE handle, struct user_object *ptr ) DECLSPEC_HIDDEN;
void release_user_handle_ptr( void *ptr ) DECLSPEC_HIDDEN;
void *free_user_handle( HANDLE handle, unsigned int type ) DECLSPEC_HIDDEN;
@ -210,18 +213,6 @@ typedef struct tagWINDOWPROC
#define MAX_ATOM_LEN 255
/* FIXME: make it private to dce.c */
struct dce
{
struct list entry; /* entry in global DCE list */
HDC hdc;
HWND hwnd;
HRGN clip_rgn;
DWORD flags;
LONG count; /* usage count; 0 or 1 for cache DCEs, always 1 for window DCEs,
always >= 1 for class DCEs */
};
/* Built-in class names (see _Undocumented_Windows_ p.418) */
#define POPUPMENU_CLASS_ATOM MAKEINTATOM(32768) /* PopupMenu */
#define DESKTOP_CLASS_ATOM MAKEINTATOM(32769) /* Desktop */
@ -229,32 +220,12 @@ struct dce
#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771) /* WinSwitch */
#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772) /* IconTitle */
typedef struct tagCLASS
{
struct list entry; /* Entry in class list */
UINT style; /* Class style */
BOOL local; /* Local class? */
WNDPROC winproc; /* Window procedure */
INT cbClsExtra; /* Class extra bytes */
INT cbWndExtra; /* Window extra bytes */
struct client_menu_name menu_name; /* Default menu name */
struct dce *dce; /* Opaque pointer to class DCE */
UINT_PTR instance; /* Module that created the task */
HICON hIcon; /* Default icon */
HICON hIconSm; /* Default small icon */
HICON hIconSmIntern; /* Internal small icon, derived from hIcon */
HCURSOR hCursor; /* Default cursor */
HBRUSH hbrBackground; /* Default background */
ATOM atomName; /* Name of the class */
WCHAR name[MAX_ATOM_LEN + 1];
WCHAR *basename; /* Base name for redirected classes, pointer within 'name'. */
} CLASS;
/* class.c */
WNDPROC alloc_winproc( WNDPROC func, BOOL ansi ) DECLSPEC_HIDDEN;
WINDOWPROC *get_winproc_ptr( WNDPROC handle ) DECLSPEC_HIDDEN;
BOOL is_winproc_unicode( WNDPROC proc, BOOL def_val ) DECLSPEC_HIDDEN;
DWORD get_class_long( HWND hwnd, INT offset, BOOL ansi ) DECLSPEC_HIDDEN;
WNDPROC get_class_winproc( struct tagCLASS *class ) DECLSPEC_HIDDEN;
ULONG_PTR get_class_long_ptr( HWND hwnd, INT offset, BOOL ansi ) DECLSPEC_HIDDEN;
WORD get_class_word( HWND hwnd, INT offset ) DECLSPEC_HIDDEN;
ATOM get_int_atom_value( UNICODE_STRING *name ) DECLSPEC_HIDDEN;

View file

@ -1391,7 +1391,7 @@ UINT get_win_monitor_dpi( HWND hwnd )
/**********************************************************************
* get_thread_dpi_awareness
*/
static DPI_AWARENESS get_thread_dpi_awareness(void)
DPI_AWARENESS get_thread_dpi_awareness(void)
{
struct user_thread_info *info = get_user_thread_info();
ULONG_PTR context = info->dpi_awareness;
@ -4749,9 +4749,6 @@ ULONG_PTR WINAPI NtUserCallTwoParam( ULONG_PTR arg1, ULONG_PTR arg2, ULONG code
case NtUserRegisterWindowSurface:
register_window_surface( (struct window_surface *)arg1, (struct window_surface *)arg2 );
return 0;
case NtUserSetHandlePtr:
set_user_handle_ptr( UlongToHandle(arg1), (struct user_object *)arg2 );
return 0;
default:
FIXME( "invalid code %u\n", code );
return 0;

View file

@ -814,7 +814,7 @@
@ stub NtUserCreateInputContext
@ stub NtUserCreateLocalMemHandle
@ stub NtUserCreatePalmRejectionDelayZone
@ stub NtUserCreateWindowEx
@ stdcall NtUserCreateWindowEx(long ptr ptr ptr long long long long long long long long ptr long long long long)
@ stub NtUserCreateWindowGroup
@ stdcall -syscall NtUserCreateWindowStation(ptr long long long long long long)
@ stub NtUserCtxDisplayIOCtl

View file

@ -195,6 +195,11 @@ struct unix_funcs
DWORD flags, void *lparam );
BOOL (WINAPI *pNtUserClipCursor)( const RECT *rect );
INT (WINAPI *pNtUserCountClipboardFormats)(void);
HWND (WINAPI *pNtUserCreateWindowEx)( DWORD ex_style, UNICODE_STRING *class_name,
UNICODE_STRING *version, UNICODE_STRING *window_name,
DWORD style, INT x, INT y, INT width, INT height,
HWND parent, HMENU menu, HINSTANCE instance, void *params,
DWORD flags, CBT_CREATEWNDW *cbtc, DWORD unk, BOOL ansi );
HDWP (WINAPI *pNtUserDeferWindowPosAndBand)( HDWP hdwp, HWND hwnd, HWND after,
INT x, INT y, INT cx, INT cy,
UINT flags, UINT unk1, UINT unk2 );
@ -300,6 +305,7 @@ extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param ) DECLSPEC_HIDDEN
/* dce.c */
extern struct window_surface dummy_surface DECLSPEC_HIDDEN;
extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN;
extern void flush_window_surfaces( BOOL idle ) DECLSPEC_HIDDEN;
extern void register_window_surface( struct window_surface *old,
struct window_surface *new ) DECLSPEC_HIDDEN;
@ -336,6 +342,7 @@ extern RECT get_primary_monitor_rect( UINT dpi ) DECLSPEC_HIDDEN;
extern UINT get_system_dpi(void) DECLSPEC_HIDDEN;
extern int get_system_metrics( int index ) DECLSPEC_HIDDEN;
extern UINT get_thread_dpi(void) DECLSPEC_HIDDEN;
extern DPI_AWARENESS get_thread_dpi_awareness(void) DECLSPEC_HIDDEN;
extern RECT get_virtual_screen_rect( UINT dpi ) DECLSPEC_HIDDEN;
extern BOOL is_exiting_thread( DWORD tid ) DECLSPEC_HIDDEN;
extern POINT map_dpi_point( POINT pt, UINT dpi_from, UINT dpi_to ) DECLSPEC_HIDDEN;
@ -348,9 +355,6 @@ extern void user_lock(void) DECLSPEC_HIDDEN;
extern void user_unlock(void) DECLSPEC_HIDDEN;
extern void user_check_not_lock(void) DECLSPEC_HIDDEN;
/* windc.c */
extern void erase_now( HWND hwnd, UINT rdw_flags ) DECLSPEC_HIDDEN;
/* window.c */
struct tagWND;
extern HDWP begin_defer_window_pos( INT count ) DECLSPEC_HIDDEN;

View file

@ -100,7 +100,7 @@ void *get_user_handle_ptr( HANDLE handle, unsigned int type )
/***********************************************************************
* set_user_handle_ptr
*/
void set_user_handle_ptr( HANDLE handle, struct user_object *ptr )
static void set_user_handle_ptr( HANDLE handle, struct user_object *ptr )
{
WORD index = USER_HANDLE_TO_INDEX(handle);
assert( index < NB_USER_HANDLES );
@ -3990,6 +3990,7 @@ static void free_window_handle( HWND hwnd )
SERVER_END_REQ;
user_unlock();
if (user_callbacks) user_callbacks->free_win_ptr( win );
free( win );
}
}
@ -4192,9 +4193,490 @@ void destroy_thread_windows(void)
window_surface_release( win->surface );
}
if (user_callbacks) user_callbacks->free_win_ptr( win );
free( win );
}
}
/***********************************************************************
* create_window_handle
*
* Create a window handle with the server.
*/
static WND *create_window_handle( HWND parent, HWND owner, UNICODE_STRING *name,
HINSTANCE instance, BOOL ansi,
DWORD style, DWORD ex_style )
{
DPI_AWARENESS awareness = get_thread_dpi_awareness();
HWND handle = 0, full_parent = 0, full_owner = 0;
struct tagCLASS *class = NULL;
int extra_bytes = 0;
UINT dpi = 0;
WND *win;
SERVER_START_REQ( create_window )
{
req->parent = wine_server_user_handle( parent );
req->owner = wine_server_user_handle( owner );
req->instance = wine_server_client_ptr( instance );
req->dpi = get_system_dpi();
req->awareness = awareness;
req->style = style;
req->ex_style = ex_style;
if (!(req->atom = get_int_atom_value( name )) && name->Length)
wine_server_add_data( req, name->Buffer, name->Length );
if (!wine_server_call_err( req ))
{
handle = wine_server_ptr_handle( reply->handle );
full_parent = wine_server_ptr_handle( reply->parent );
full_owner = wine_server_ptr_handle( reply->owner );
extra_bytes = reply->extra;
dpi = reply->dpi;
awareness = reply->awareness;
class = wine_server_get_ptr( reply->class_ptr );
}
}
SERVER_END_REQ;
if (!handle)
{
WARN( "error %d creating window\n", GetLastError() );
return NULL;
}
if (!(win = calloc( 1, FIELD_OFFSET(WND, wExtra) + extra_bytes )))
{
SERVER_START_REQ( destroy_window )
{
req->handle = wine_server_user_handle( handle );
wine_server_call( req );
}
SERVER_END_REQ;
SetLastError( ERROR_NOT_ENOUGH_MEMORY );
return NULL;
}
if (!parent) /* if parent is 0 we don't have a desktop window yet */
{
struct user_thread_info *thread_info = get_user_thread_info();
if (name->Buffer == (const WCHAR *)DESKTOP_CLASS_ATOM)
{
if (!thread_info->top_window) thread_info->top_window = full_parent ? full_parent : handle;
else assert( full_parent == thread_info->top_window );
if (full_parent && !user_driver->pCreateDesktopWindow( thread_info->top_window ))
ERR( "failed to create desktop window\n" );
if (user_callbacks) user_callbacks->register_builtin_classes();
}
else /* HWND_MESSAGE parent */
{
if (!thread_info->msg_window && !full_parent) thread_info->msg_window = handle;
}
}
user_lock();
win->obj.handle = handle;
win->obj.type = NTUSER_OBJ_WINDOW;
win->parent = full_parent;
win->owner = full_owner;
win->class = class;
win->winproc = get_class_winproc( class );
win->cbWndExtra = extra_bytes;
win->dpi = dpi;
win->dpi_awareness = awareness;
set_user_handle_ptr( handle, &win->obj );
if (is_winproc_unicode( win->winproc, !ansi )) win->flags |= WIN_ISUNICODE;
return win;
}
static BOOL is_default_coord( int x )
{
return x == CW_USEDEFAULT || x == 0x8000;
}
/***********************************************************************
* fix_cs_coordinates
*
* Fix the coordinates and return default show mode in sw.
*/
static void fix_cs_coordinates( CREATESTRUCTW *cs, INT *sw )
{
if (cs->style & (WS_CHILD | WS_POPUP))
{
if (is_default_coord(cs->x)) cs->x = cs->y = 0;
if (is_default_coord(cs->cx)) cs->cx = cs->cy = 0;
}
else /* overlapped window */
{
RTL_USER_PROCESS_PARAMETERS *params = NtCurrentTeb()->Peb->ProcessParameters;
HMONITOR monitor;
MONITORINFO mon_info;
if (!is_default_coord( cs->x ) && !is_default_coord( cs->cx ) && !is_default_coord( cs->cy ))
return;
monitor = monitor_from_window( cs->hwndParent, MONITOR_DEFAULTTOPRIMARY, get_thread_dpi() );
mon_info.cbSize = sizeof(mon_info);
get_monitor_info( monitor, &mon_info );
if (is_default_coord( cs->x ))
{
if (!is_default_coord( cs->y )) *sw = cs->y;
cs->x = (params->dwFlags & STARTF_USEPOSITION) ? params->dwX : mon_info.rcWork.left;
cs->y = (params->dwFlags & STARTF_USEPOSITION) ? params->dwY : mon_info.rcWork.top;
}
if (is_default_coord( cs->cx ))
{
if (params->dwFlags & STARTF_USESIZE)
{
cs->cx = params->dwXSize;
cs->cy = params->dwYSize;
}
else
{
cs->cx = (mon_info.rcWork.right - mon_info.rcWork.left) * 3 / 4 - cs->x;
cs->cy = (mon_info.rcWork.bottom - mon_info.rcWork.top) * 3 / 4 - cs->y;
}
}
/* neither x nor cx are default. Check the y values.
* In the trace we see Outlook and Outlook Express using
* cy set to CW_USEDEFAULT when opening the address book.
*/
else if (is_default_coord( cs->cy ))
{
FIXME( "Strange use of CW_USEDEFAULT in cy\n" );
cs->cy = (mon_info.rcWork.bottom - mon_info.rcWork.top) * 3 / 4 - cs->y;
}
}
}
/***********************************************************************
* map_dpi_create_struct
*/
static void map_dpi_create_struct( CREATESTRUCTW *cs, UINT dpi_from, UINT dpi_to )
{
if (!dpi_from && !dpi_to) return;
if (!dpi_from || !dpi_to)
{
POINT pt = { cs->x, cs->y };
UINT mon_dpi = get_monitor_dpi( monitor_from_point( pt, MONITOR_DEFAULTTONEAREST, dpi_from ));
if (!dpi_from) dpi_from = mon_dpi;
else dpi_to = mon_dpi;
}
if (dpi_from == dpi_to) return;
cs->x = muldiv( cs->x, dpi_to, dpi_from );
cs->y = muldiv( cs->y, dpi_to, dpi_from );
cs->cx = muldiv( cs->cx, dpi_to, dpi_from );
cs->cy = muldiv( cs->cy, dpi_to, dpi_from );
}
/***********************************************************************
* NtUserCreateWindowEx (win32u.@)
*/
HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name,
UNICODE_STRING *version, UNICODE_STRING *window_name,
DWORD style, INT x, INT y, INT cx, INT cy,
HWND parent, HMENU menu, HINSTANCE instance, void *params,
DWORD flags, CBT_CREATEWNDW *cbtc, DWORD unk, BOOL ansi )
{
CREATESTRUCTW cs, *client_cs = cbtc->lpcs;
UINT win_dpi, thread_dpi = get_thread_dpi();
DPI_AWARENESS_CONTEXT context;
HWND hwnd, owner = 0;
INT sw = SW_SHOW;
LRESULT result;
RECT rect;
WND *win;
static const WCHAR messageW[] = {'M','e','s','s','a','g','e'};
cs.lpCreateParams = params;
cs.hInstance = client_cs->hInstance; /* may be different than instance for win16 */
cs.hMenu = menu;
cs.hwndParent = parent;
cs.style = style;
cs.dwExStyle = ex_style;
cs.x = x;
cs.y = y;
cs.cx = cx;
cs.cy = cy;
/* We use client_cs to pass original class and name pointers,
* that's probably not how native handles it. */
cs.lpszName = client_cs->lpszName;
cs.lpszClass = client_cs->lpszClass;
/* Find the parent window */
if (parent == HWND_MESSAGE)
{
cs.hwndParent = parent = get_hwnd_message_parent();
}
else if (parent)
{
if ((cs.style & (WS_CHILD|WS_POPUP)) != WS_CHILD)
{
owner = parent;
parent = get_desktop_window();
}
else
{
DWORD parent_style = get_window_long( parent, GWL_EXSTYLE );
if ((parent_style & WS_EX_LAYOUTRTL) && !(parent_style & WS_EX_NOINHERITLAYOUT))
cs.dwExStyle |= WS_EX_LAYOUTRTL;
}
}
else
{
if ((cs.style & (WS_CHILD|WS_POPUP)) == WS_CHILD)
{
WARN( "No parent for child window\n" );
SetLastError( ERROR_TLW_WITH_WSCHILD );
return 0; /* WS_CHILD needs a parent, but WS_POPUP doesn't */
}
/* are we creating the desktop or HWND_MESSAGE parent itself? */
if (class_name->Buffer != (LPCWSTR)DESKTOP_CLASS_ATOM &&
(class_name->Length != sizeof(messageW) ||
wcsnicmp( class_name->Buffer, messageW, ARRAYSIZE(messageW) )))
{
parent = get_desktop_window();
}
}
fix_cs_coordinates( &cs, &sw );
cs.dwExStyle = fix_exstyle( cs.style, cs.dwExStyle );
/* Create the window structure */
style = cs.style & ~WS_VISIBLE;
ex_style = cs.dwExStyle & ~WS_EX_LAYERED;
if (!(win = create_window_handle( parent, owner, class_name, instance, ansi, style, ex_style )))
return 0;
hwnd = win->obj.handle;
/* Fill the window structure */
win->tid = GetCurrentThreadId();
win->hInstance = cs.hInstance;
win->text = NULL;
win->dwStyle = style;
win->dwExStyle = ex_style;
win->wIDmenu = 0;
win->helpContext = 0;
win->pScroll = NULL;
win->userdata = 0;
win->hIcon = 0;
win->hIconSmall = 0;
win->hIconSmall2 = 0;
win->hSysMenu = 0;
win->min_pos.x = win->min_pos.y = -1;
win->max_pos.x = win->max_pos.y = -1;
SetRect( &win->normal_rect, cs.x, cs.y, cs.x + cs.cx, cs.y + cs.cy );
if (win->dwStyle & WS_SYSMENU) NtUserSetSystemMenu( hwnd, 0 );
/* call the WH_CBT hook */
release_win_ptr( win );
*client_cs = cs;
cbtc->hwndInsertAfter = HWND_TOP;
if (call_hooks( WH_CBT, HCBT_CREATEWND, (WPARAM)hwnd, (LPARAM)cbtc, !ansi ))
{
free_window_handle( hwnd );
return 0;
}
if (!(win = get_win_ptr( hwnd ))) return 0;
/*
* Correct the window styles.
*
* It affects only the style loaded into the WND structure.
*/
if ((win->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
{
win->dwStyle |= WS_CLIPSIBLINGS;
if (!(win->dwStyle & WS_POPUP)) win->dwStyle |= WS_CAPTION;
}
win->dwExStyle = cs.dwExStyle;
/* WS_EX_WINDOWEDGE depends on some other styles */
if ((win->dwStyle & (WS_DLGFRAME | WS_THICKFRAME)) &&
!(win->dwStyle & (WS_CHILD | WS_POPUP)))
win->dwExStyle |= WS_EX_WINDOWEDGE;
if (!(win->dwStyle & (WS_CHILD | WS_POPUP))) win->flags |= WIN_NEED_SIZE;
SERVER_START_REQ( set_window_info )
{
req->handle = wine_server_user_handle( hwnd );
req->flags = SET_WIN_STYLE | SET_WIN_EXSTYLE | SET_WIN_INSTANCE | SET_WIN_UNICODE;
req->style = win->dwStyle;
req->ex_style = win->dwExStyle;
req->instance = wine_server_client_ptr( win->hInstance );
req->is_unicode = (win->flags & WIN_ISUNICODE) != 0;
req->extra_offset = -1;
wine_server_call( req );
}
SERVER_END_REQ;
/* Set the window menu */
if ((win->dwStyle & (WS_CHILD | WS_POPUP)) != WS_CHILD)
{
if (cs.hMenu && user_callbacks && !user_callbacks->set_menu( hwnd, cs.hMenu ))
{
release_win_ptr( win );
free_window_handle( hwnd );
return 0;
}
}
else NtUserSetWindowLongPtr( hwnd, GWLP_ID, (ULONG_PTR)cs.hMenu, FALSE );
win_dpi = win->dpi;
release_win_ptr( win );
if (parent) map_dpi_create_struct( &cs, thread_dpi, win_dpi );
context = set_thread_dpi_awareness_context( get_window_dpi_awareness_context( hwnd ));
/* send the WM_GETMINMAXINFO message and fix the size if needed */
cx = cs.cx;
cy = cs.cy;
if ((cs.style & WS_THICKFRAME) || !(cs.style & (WS_POPUP | WS_CHILD)))
{
MINMAXINFO info = get_min_max_info( hwnd );
cx = max( min( cx, info.ptMaxTrackSize.x ), info.ptMinTrackSize.x );
cy = max( min( cy, info.ptMaxTrackSize.y ), info.ptMinTrackSize.y );
}
if (cx < 0) cx = 0;
if (cy < 0) cy = 0;
set_rect( &rect, cs.x, cs.y, cs.x + cx, cs.y + cy );
/* check for wraparound */
if (cs.x > 0x7fffffff - cx) rect.right = 0x7fffffff;
if (cs.y > 0x7fffffff - cy) rect.bottom = 0x7fffffff;
if (user_callbacks && !user_callbacks->set_window_pos( hwnd, 0, SWP_NOZORDER | SWP_NOACTIVATE,
&rect, &rect, NULL )) goto failed;
/* send WM_NCCREATE */
TRACE( "hwnd %p cs %d,%d %dx%d %s\n", hwnd, cs.x, cs.y, cs.cx, cs.cy, wine_dbgstr_rect(&rect) );
*client_cs = cs;
if (!NtUserMessageCall( hwnd, WM_NCCREATE, 0, (LPARAM)client_cs, (ULONG_PTR)&result,
FNID_SENDMESSAGE, ansi ) || !result)
{
WARN( "%p: aborted by WM_NCCREATE\n", hwnd );
goto failed;
}
/* create default IME window */
if (!is_desktop_window( hwnd ) && parent != get_hwnd_message_parent() &&
user_callbacks && user_callbacks->register_imm( hwnd ))
{
TRACE( "register IME window for %p\n", hwnd );
win_set_flags( hwnd, WIN_HAS_IME_WIN, 0 );
}
/* send WM_NCCALCSIZE */
if (get_window_rects( hwnd, COORDS_PARENT, &rect, NULL, win_dpi ))
{
/* yes, even if the CBT hook was called with HWND_TOP */
HWND insert_after = (get_window_long( hwnd, GWL_STYLE ) & WS_CHILD) ? HWND_BOTTOM : HWND_TOP;
RECT client_rect = rect;
/* the rectangle is in screen coords for WM_NCCALCSIZE when wparam is FALSE */
map_window_points( parent, 0, (POINT *)&client_rect, 2, win_dpi );
send_message( hwnd, WM_NCCALCSIZE, FALSE, (LPARAM)&client_rect );
map_window_points( 0, parent, (POINT *)&client_rect, 2, win_dpi );
user_callbacks->set_window_pos( hwnd, insert_after, SWP_NOACTIVATE, &rect, &client_rect, NULL );
}
else goto failed;
/* send WM_CREATE */
if (!NtUserMessageCall( hwnd, WM_CREATE, 0, (LPARAM)client_cs, (ULONG_PTR)&result,
FNID_SENDMESSAGE, ansi ) || result == -1) goto failed;
cs = *client_cs;
/* call the driver */
if (!user_driver->pCreateWindow( hwnd )) goto failed;
NtUserNotifyWinEvent( EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0 );
/* send the size messages */
if (!(win_get_flags( hwnd ) & WIN_NEED_SIZE))
{
get_window_rects( hwnd, COORDS_PARENT, NULL, &rect, win_dpi );
send_message( hwnd, WM_SIZE, SIZE_RESTORED,
MAKELONG(rect.right-rect.left, rect.bottom-rect.top));
send_message( hwnd, WM_MOVE, 0, MAKELONG( rect.left, rect.top ) );
}
/* Show the window, maximizing or minimizing if needed */
style = set_window_style( hwnd, 0, WS_MAXIMIZE | WS_MINIMIZE );
if (style & (WS_MINIMIZE | WS_MAXIMIZE))
{
RECT new_pos;
UINT sw_flags = (style & WS_MINIMIZE) ? SW_MINIMIZE : SW_MAXIMIZE;
sw_flags = window_min_maximize( hwnd, sw_flags, &new_pos );
sw_flags |= SWP_FRAMECHANGED; /* Frame always gets changed */
if (!(style & WS_VISIBLE) || (style & WS_CHILD) || get_active_window())
sw_flags |= SWP_NOACTIVATE;
NtUserSetWindowPos( hwnd, 0, new_pos.left, new_pos.top, new_pos.right - new_pos.left,
new_pos.bottom - new_pos.top, sw_flags );
}
/* Notify the parent window only */
send_parent_notify( hwnd, WM_CREATE );
if (!is_window( hwnd ))
{
set_thread_dpi_awareness_context( context );
return 0;
}
if (parent == get_desktop_window())
post_message( parent, WM_PARENTNOTIFY, WM_CREATE, (LPARAM)hwnd );
if (cs.style & WS_VISIBLE)
{
if (cs.style & WS_MAXIMIZE)
sw = SW_SHOW;
else if (cs.style & WS_MINIMIZE)
sw = SW_SHOWMINIMIZED;
NtUserShowWindow( hwnd, sw );
if (cs.dwExStyle & WS_EX_MDICHILD)
{
send_message( cs.hwndParent, WM_MDIREFRESHMENU, 0, 0 );
/* ShowWindow won't activate child windows */
NtUserSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_SHOWWINDOW | SWP_NOMOVE | SWP_NOSIZE );
}
}
/* Call WH_SHELL hook */
if (!(get_window_long( hwnd, GWL_STYLE ) & WS_CHILD) && !get_window_relative( hwnd, GW_OWNER ))
call_hooks( WH_SHELL, HSHELL_WINDOWCREATED, (WPARAM)hwnd, 0, TRUE );
TRACE( "created window %p\n", hwnd );
set_thread_dpi_awareness_context( context );
return hwnd;
failed:
destroy_window( hwnd );
set_thread_dpi_awareness_context( context );
return 0;
}
/*****************************************************************************
* NtUserCallHwnd (win32u.@)
*/
@ -4219,10 +4701,6 @@ ULONG_PTR WINAPI NtUserCallHwnd( HWND hwnd, DWORD code )
case NtUserIsWindowVisible:
return is_window_visible( hwnd );
/* temporary exports */
case NtUserCreateDesktopWindow:
return user_driver->pCreateDesktopWindow( hwnd );
case NtUserDestroyWindowHandle:
return destroy_window( hwnd );
case NtUserGetDummySurface:
return (UINT_PTR)&dummy_surface;
default:

View file

@ -768,6 +768,18 @@ INT WINAPI NtUserCountClipboardFormats(void)
return unix_funcs->pNtUserCountClipboardFormats();
}
HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name,
UNICODE_STRING *version, UNICODE_STRING *window_name,
DWORD style, INT x, INT y, INT width, INT height,
HWND parent, HMENU menu, HINSTANCE instance, void *params,
DWORD flags, CBT_CREATEWNDW *cbtc, DWORD unk, BOOL ansi )
{
if (!unix_funcs) return 0;
return unix_funcs->pNtUserCreateWindowEx( ex_style, class_name, version, window_name,
style, x, y, width, height, parent, menu,
instance, params, flags, cbtc, unk, ansi );
}
HDWP WINAPI NtUserDeferWindowPosAndBand( HDWP hdwp, HWND hwnd, HWND after,
INT x, INT y, INT cx, INT cy,
UINT flags, UINT unk1, UINT unk2 )

View file

@ -139,7 +139,6 @@ enum
NtUserGetHandlePtr,
NtUserInvalidateDCE,
NtUserRegisterWindowSurface,
NtUserSetHandlePtr,
};
/* NtUserCallHwnd codes, not compatible with Windows */
@ -154,8 +153,6 @@ enum
NtUserIsWindowUnicode,
NtUserIsWindowVisible,
/* temporary exports */
NtUserCreateDesktopWindow,
NtUserDestroyWindowHandle,
NtUserGetDummySurface,
};
@ -193,6 +190,7 @@ enum
/* NtUserMessageCall codes */
enum
{
FNID_SENDMESSAGE = 0x02b1,
FNID_SENDNOTIFYMESSAGE = 0x02b7,
};
@ -298,6 +296,11 @@ HACCEL WINAPI NtUserCreateAcceleratorTable( ACCEL *table, INT count );
HDESK WINAPI NtUserCreateDesktopEx( OBJECT_ATTRIBUTES *attr, UNICODE_STRING *device,
DEVMODEW *devmode, DWORD flags, ACCESS_MASK access,
ULONG heap_size );
HWND WINAPI NtUserCreateWindowEx( DWORD ex_style, UNICODE_STRING *class_name,
UNICODE_STRING *version, UNICODE_STRING *window_name,
DWORD style, INT x, INT y, INT cx, INT cy,
HWND parent, HMENU menu, HINSTANCE instance, void *params,
DWORD flags, CBT_CREATEWNDW *cbtc, DWORD unk, BOOL ansi );
HWINSTA WINAPI NtUserCreateWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK mask, ULONG arg3,
ULONG arg4, ULONG arg5, ULONG arg6, ULONG arg7 );
HDWP WINAPI NtUserDeferWindowPosAndBand( HDWP hdwp, HWND hwnd, HWND after, INT x, INT y,
@ -408,6 +411,7 @@ BOOL WINAPI NtUserSetProcessDpiAwarenessContext( ULONG awareness, ULONG unkno
BOOL WINAPI NtUserSetProcessWindowStation( HWINSTA handle );
BOOL WINAPI NtUserSetProp( HWND hwnd, const WCHAR *str, HANDLE handle );
BOOL WINAPI NtUserSetSysColors( INT count, const INT *colors, const COLORREF *values );
BOOL WINAPI NtUserSetSystemMenu( HWND hwnd, HMENU menu );
UINT_PTR WINAPI NtUserSetSystemTimer( HWND hwnd, UINT_PTR id, UINT timeout, TIMERPROC proc );
BOOL WINAPI NtUserSetThreadDesktop( HDESK handle );
UINT_PTR WINAPI NtUserSetTimer( HWND hwnd, UINT_PTR id, UINT timeout, TIMERPROC proc, ULONG tolerance );