mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 16:47:17 +00:00
win32u: Move class management 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:
parent
b1b0470083
commit
7c76aa05a9
|
@ -40,7 +40,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(class);
|
|||
|
||||
#define MAX_ATOM_LEN 255 /* from dlls/kernel32/atom.c */
|
||||
|
||||
static struct list class_list = LIST_INIT( class_list );
|
||||
static INIT_ONCE init_once = INIT_ONCE_STATIC_INIT;
|
||||
|
||||
#define CLASS_OTHER_PROCESS ((CLASS *)1)
|
||||
|
@ -301,54 +300,6 @@ static void CLASS_SetMenuNameW( CLASS *classPtr, LPCWSTR name )
|
|||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CLASS_FreeClass
|
||||
*
|
||||
* Free a class structure.
|
||||
*/
|
||||
static void CLASS_FreeClass( CLASS *classPtr )
|
||||
{
|
||||
TRACE("%p\n", classPtr);
|
||||
|
||||
USER_Lock();
|
||||
|
||||
if (classPtr->dce) free_dce( classPtr->dce, 0 );
|
||||
list_remove( &classPtr->entry );
|
||||
if (classPtr->hbrBackground > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1))
|
||||
DeleteObject( classPtr->hbrBackground );
|
||||
DestroyIcon( classPtr->hIconSmIntern );
|
||||
free_menu_name( &classPtr->menu_name );
|
||||
HeapFree( GetProcessHeap(), 0, classPtr );
|
||||
USER_Unlock();
|
||||
}
|
||||
|
||||
static CLASS *find_class( HINSTANCE module, UNICODE_STRING *name )
|
||||
{
|
||||
ATOM atom = get_int_atom_value( name );
|
||||
UINT_PTR instance = (UINT_PTR)module & ~0xffff;
|
||||
CLASS *class;
|
||||
|
||||
USER_Lock();
|
||||
LIST_FOR_EACH_ENTRY( class, &class_list, CLASS, entry )
|
||||
{
|
||||
if (atom)
|
||||
{
|
||||
if (class->atomName != atom) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wcsnicmp( class->name, name->Buffer, name->Length / sizeof(WCHAR) )) continue;
|
||||
}
|
||||
if (!class->local || !module || (class->instance & ~0xffff) == instance)
|
||||
{
|
||||
TRACE( "%s %Ix -> %p\n", debugstr_us(name), instance, class );
|
||||
return class;
|
||||
}
|
||||
}
|
||||
USER_Unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void get_versioned_name( const WCHAR *name, UNICODE_STRING *ret, UNICODE_STRING *version, HMODULE *reg_module )
|
||||
{
|
||||
ACTCTX_SECTION_KEYED_DATA data;
|
||||
|
@ -407,75 +358,6 @@ static void get_versioned_name( const WCHAR *name, UNICODE_STRING *ret, UNICODE_
|
|||
init_class_name( ret, ptr );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* CLASS_RegisterClass
|
||||
*
|
||||
* The real RegisterClass() functionality.
|
||||
*/
|
||||
static CLASS *CLASS_RegisterClass( UNICODE_STRING *name, UINT basename_offset, HINSTANCE hInstance,
|
||||
BOOL local, DWORD style, INT classExtra, INT winExtra )
|
||||
{
|
||||
CLASS *classPtr;
|
||||
BOOL ret;
|
||||
|
||||
TRACE("name=%s hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n",
|
||||
debugstr_us(name), hInstance, style, classExtra, winExtra );
|
||||
|
||||
/* Fix the extra bytes value */
|
||||
|
||||
if (classExtra > 40) /* Extra bytes are limited to 40 in Win32 */
|
||||
WARN("Class extra bytes %d is > 40\n", classExtra);
|
||||
if (winExtra > 40) /* Extra bytes are limited to 40 in Win32 */
|
||||
WARN("Win extra bytes %d is > 40\n", winExtra );
|
||||
|
||||
classPtr = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CLASS) + classExtra );
|
||||
if (!classPtr) return NULL;
|
||||
|
||||
classPtr->atomName = get_int_atom_value( name );
|
||||
classPtr->basename = classPtr->name;
|
||||
if (!classPtr->atomName && name)
|
||||
{
|
||||
memcpy( classPtr->name, name->Buffer, name->Length );
|
||||
classPtr->name[name->Length / sizeof(WCHAR)] = 0;
|
||||
classPtr->basename += basename_offset;
|
||||
}
|
||||
else GlobalGetAtomNameW( classPtr->atomName, classPtr->name, ARRAY_SIZE( classPtr->name ));
|
||||
|
||||
SERVER_START_REQ( create_class )
|
||||
{
|
||||
req->local = local;
|
||||
req->style = style;
|
||||
req->instance = wine_server_client_ptr( hInstance );
|
||||
req->extra = classExtra;
|
||||
req->win_extra = winExtra;
|
||||
req->client_ptr = wine_server_client_ptr( classPtr );
|
||||
req->atom = classPtr->atomName;
|
||||
req->name_offset = basename_offset;
|
||||
if (!req->atom && name) wine_server_add_data( req, name->Buffer, name->Length );
|
||||
ret = !wine_server_call_err( req );
|
||||
classPtr->atomName = reply->atom;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!ret)
|
||||
{
|
||||
HeapFree( GetProcessHeap(), 0, classPtr );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
classPtr->style = style;
|
||||
classPtr->local = local;
|
||||
classPtr->cbWndExtra = winExtra;
|
||||
classPtr->cbClsExtra = classExtra;
|
||||
classPtr->instance = (UINT_PTR)hInstance;
|
||||
|
||||
/* Other non-null values must be set by caller */
|
||||
|
||||
USER_Lock();
|
||||
if (local) list_add_head( &class_list, &classPtr->entry );
|
||||
else list_add_tail( &class_list, &classPtr->entry );
|
||||
return classPtr;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* register_builtin
|
||||
|
@ -485,24 +367,22 @@ static CLASS *CLASS_RegisterClass( UNICODE_STRING *name, UINT basename_offset, H
|
|||
*/
|
||||
static void register_builtin( const struct builtin_class_descr *descr )
|
||||
{
|
||||
UNICODE_STRING name;
|
||||
CLASS *classPtr;
|
||||
HCURSOR cursor = 0;
|
||||
UNICODE_STRING name, version = { .Length = 0 };
|
||||
struct client_menu_name menu_name = { 0 };
|
||||
WNDCLASSEXW class = {
|
||||
.cbSize = sizeof(class),
|
||||
.hInstance = user32_module,
|
||||
.style = descr->style,
|
||||
.cbWndExtra = descr->extra,
|
||||
.hbrBackground = descr->brush,
|
||||
.lpfnWndProc = BUILTIN_WINPROC( descr->proc ),
|
||||
};
|
||||
|
||||
if (descr->cursor) cursor = LoadCursorA( 0, (LPSTR)descr->cursor );
|
||||
if (descr->cursor) class.hCursor = LoadCursorA( 0, (LPSTR)descr->cursor );
|
||||
|
||||
init_class_name( &name, descr->name );
|
||||
if (!(classPtr = CLASS_RegisterClass( &name, 0, user32_module, FALSE,
|
||||
descr->style, 0, descr->extra )))
|
||||
{
|
||||
if (cursor) DestroyCursor( cursor );
|
||||
return;
|
||||
}
|
||||
|
||||
classPtr->hCursor = cursor;
|
||||
classPtr->hbrBackground = descr->brush;
|
||||
classPtr->winproc = BUILTIN_WINPROC( descr->proc );
|
||||
release_class_ptr( classPtr );
|
||||
if (!NtUserRegisterClassExWOW( &class, &name, &version, &menu_name, 1, 0, NULL ) && class.hCursor)
|
||||
DestroyCursor( class.hCursor );
|
||||
}
|
||||
|
||||
static void load_uxtheme(void)
|
||||
|
@ -654,18 +534,6 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
|
|||
struct client_menu_name menu_name;
|
||||
UNICODE_STRING name, version;
|
||||
ATOM atom;
|
||||
CLASS *classPtr;
|
||||
HINSTANCE instance;
|
||||
|
||||
GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */
|
||||
|
||||
if (wc->cbSize != sizeof(*wc) || wc->cbClsExtra < 0 || wc->cbWndExtra < 0 ||
|
||||
wc->hInstance == user32_module) /* we can't register a class for user32 */
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
|
||||
|
||||
version.Buffer = combined;
|
||||
version.MaximumLength = sizeof(combined);
|
||||
|
@ -682,27 +550,8 @@ ATOM WINAPI RegisterClassExA( const WNDCLASSEXA* wc )
|
|||
|
||||
if (!alloc_menu_nameA( &menu_name, wc->lpszMenuName )) return 0;
|
||||
|
||||
classPtr = CLASS_RegisterClass( &name, version.Length / sizeof(WCHAR), instance, !(wc->style & CS_GLOBALCLASS),
|
||||
wc->style, wc->cbClsExtra, wc->cbWndExtra );
|
||||
if (!classPtr) return 0;
|
||||
atom = classPtr->atomName;
|
||||
|
||||
TRACE( "name=%s->%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
|
||||
debugstr_a(wc->lpszClassName), debugstr_us(&name), atom, wc->lpfnWndProc,
|
||||
instance, wc->hbrBackground, wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
|
||||
|
||||
classPtr->hIcon = wc->hIcon;
|
||||
classPtr->hIconSm = wc->hIconSm;
|
||||
classPtr->hIconSmIntern = wc->hIcon && !wc->hIconSm ?
|
||||
CopyImage( wc->hIcon, IMAGE_ICON,
|
||||
GetSystemMetrics( SM_CXSMICON ),
|
||||
GetSystemMetrics( SM_CYSMICON ),
|
||||
LR_COPYFROMRESOURCE ) : NULL;
|
||||
classPtr->hCursor = wc->hCursor;
|
||||
classPtr->hbrBackground = wc->hbrBackground;
|
||||
classPtr->winproc = WINPROC_AllocProc( wc->lpfnWndProc, FALSE );
|
||||
classPtr->menu_name = menu_name;
|
||||
release_class_ptr( classPtr );
|
||||
atom = NtUserRegisterClassExWOW( (WNDCLASSEXW *)wc, &name, &version, &menu_name, 0, 1, NULL );
|
||||
if (!atom) free_menu_name( &menu_name );
|
||||
return atom;
|
||||
}
|
||||
|
||||
|
@ -716,50 +565,15 @@ ATOM WINAPI RegisterClassExW( const WNDCLASSEXW* wc )
|
|||
struct client_menu_name menu_name;
|
||||
UNICODE_STRING name, version;
|
||||
ATOM atom;
|
||||
CLASS *classPtr;
|
||||
HINSTANCE instance;
|
||||
|
||||
GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */
|
||||
|
||||
if (wc->cbSize != sizeof(*wc) || wc->cbClsExtra < 0 || wc->cbWndExtra < 0 ||
|
||||
wc->hInstance == user32_module) /* we can't register a class for user32 */
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
if (!(instance = wc->hInstance)) instance = GetModuleHandleW( NULL );
|
||||
|
||||
if (!alloc_menu_nameW( &menu_name, wc->lpszMenuName )) return 0;
|
||||
|
||||
version.Buffer = combined;
|
||||
version.MaximumLength = sizeof(combined);
|
||||
get_versioned_name( wc->lpszClassName, &name, &version, FALSE );
|
||||
if (!(classPtr = CLASS_RegisterClass( &name, version.Length / sizeof(WCHAR), instance,
|
||||
!(wc->style & CS_GLOBALCLASS),
|
||||
wc->style, wc->cbClsExtra, wc->cbWndExtra )))
|
||||
{
|
||||
free_menu_name( &menu_name );
|
||||
return 0;
|
||||
}
|
||||
|
||||
atom = classPtr->atomName;
|
||||
if (!alloc_menu_nameW( &menu_name, wc->lpszMenuName )) return 0;
|
||||
|
||||
TRACE( "name=%s->%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
|
||||
debugstr_w(wc->lpszClassName), debugstr_us(&name), atom, wc->lpfnWndProc, instance,
|
||||
wc->hbrBackground, wc->style, wc->cbClsExtra, wc->cbWndExtra, classPtr );
|
||||
|
||||
classPtr->hIcon = wc->hIcon;
|
||||
classPtr->hIconSm = wc->hIconSm;
|
||||
classPtr->hIconSmIntern = wc->hIcon && !wc->hIconSm ?
|
||||
CopyImage( wc->hIcon, IMAGE_ICON,
|
||||
GetSystemMetrics( SM_CXSMICON ),
|
||||
GetSystemMetrics( SM_CYSMICON ),
|
||||
LR_COPYFROMRESOURCE ) : NULL;
|
||||
classPtr->hCursor = wc->hCursor;
|
||||
classPtr->hbrBackground = wc->hbrBackground;
|
||||
classPtr->winproc = WINPROC_AllocProc( wc->lpfnWndProc, TRUE );
|
||||
CLASS_SetMenuNameW( classPtr, wc->lpszMenuName );
|
||||
release_class_ptr( classPtr );
|
||||
atom = NtUserRegisterClassExWOW( wc, &name, &version, &menu_name, 0, 0, NULL );
|
||||
if (!atom) free_menu_name( &menu_name );
|
||||
return atom;
|
||||
}
|
||||
|
||||
|
@ -785,23 +599,14 @@ BOOL WINAPI UnregisterClassA( LPCSTR className, HINSTANCE hInstance )
|
|||
*/
|
||||
BOOL WINAPI UnregisterClassW( LPCWSTR className, HINSTANCE hInstance )
|
||||
{
|
||||
CLASS *classPtr = NULL;
|
||||
struct client_menu_name menu_name;
|
||||
UNICODE_STRING name;
|
||||
|
||||
GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */
|
||||
BOOL ret;
|
||||
|
||||
get_versioned_name( className, &name, NULL, FALSE );
|
||||
SERVER_START_REQ( destroy_class )
|
||||
{
|
||||
req->instance = wine_server_client_ptr( hInstance );
|
||||
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 )) classPtr = wine_server_get_ptr( reply->client_ptr );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
|
||||
if (classPtr) CLASS_FreeClass( classPtr );
|
||||
return (classPtr != NULL);
|
||||
ret = NtUserUnregisterClass( &name, hInstance, &menu_name );
|
||||
if (ret) free_menu_name( &menu_name );
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
|
@ -1259,19 +1064,13 @@ ATOM get_class_info( HINSTANCE instance, const WCHAR *class_name, WNDCLASSEXW *i
|
|||
{
|
||||
UNICODE_STRING name;
|
||||
HMODULE module;
|
||||
CLASS *class;
|
||||
ATOM atom;
|
||||
|
||||
get_versioned_name( class_name, &name, NULL, &module );
|
||||
|
||||
if (!name_str && !instance) instance = user32_module;
|
||||
|
||||
if (name.Buffer != (LPCWSTR)DESKTOP_CLASS_ATOM &&
|
||||
(IS_INTRESOURCE(name.Buffer) || name.Length != sizeof(L"Message") ||
|
||||
wcsnicmp( name.Buffer, L"Message", ARRAYSIZE(L"Message") )))
|
||||
GetDesktopWindow(); /* create the desktop window to trigger builtin class registration */
|
||||
|
||||
while (class_name && !(class = find_class( instance, &name )))
|
||||
while (!(atom = NtUserGetClassInfoEx( instance, &name, info, NULL, ansi )))
|
||||
{
|
||||
if (module)
|
||||
{
|
||||
|
@ -1292,31 +1091,14 @@ ATOM get_class_info( HINSTANCE instance, const WCHAR *class_name, WNDCLASSEXW *i
|
|||
TRACE( "%s retrying after loading comctl32\n", debugstr_w(class_name) );
|
||||
}
|
||||
|
||||
if (!class)
|
||||
if (!atom)
|
||||
{
|
||||
TRACE("%s %p -> not found\n", debugstr_w(class_name), instance);
|
||||
TRACE( "%s %p -> not found\n", debugstr_w(class_name), instance );
|
||||
SetLastError( ERROR_CLASS_DOES_NOT_EXIST );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (info)
|
||||
{
|
||||
info->style = class->style;
|
||||
info->lpfnWndProc = WINPROC_GetProc( class->winproc, !ansi );
|
||||
info->cbClsExtra = class->cbClsExtra;
|
||||
info->cbWndExtra = class->cbWndExtra;
|
||||
info->hInstance = (instance == user32_module) ? 0 : instance;
|
||||
info->hIcon = class->hIcon;
|
||||
info->hIconSm = class->hIconSm ? class->hIconSm : class->hIconSmIntern;
|
||||
info->hCursor = class->hCursor;
|
||||
info->hbrBackground = class->hbrBackground;
|
||||
info->lpszMenuName = ansi ? (const WCHAR *)class->menu_name.nameA : class->menu_name.nameW;
|
||||
info->lpszClassName = class_name;
|
||||
}
|
||||
|
||||
if (name_str) *name_str = name;
|
||||
atom = class->atomName;
|
||||
release_class_ptr( class );
|
||||
return atom;
|
||||
}
|
||||
|
||||
|
@ -1355,6 +1137,8 @@ BOOL WINAPI GetClassInfoExA( HINSTANCE hInstance, LPCSTR name, WNDCLASSEXA *wc )
|
|||
*/
|
||||
BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSEXW *wc )
|
||||
{
|
||||
ATOM atom;
|
||||
|
||||
TRACE("%p %s %p\n", hInstance, debugstr_w(name), wc);
|
||||
|
||||
if (!wc)
|
||||
|
@ -1363,7 +1147,11 @@ BOOL WINAPI GetClassInfoExW( HINSTANCE hInstance, LPCWSTR name, WNDCLASSEXW *wc
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
return get_class_info( hInstance, name, wc, NULL, FALSE );
|
||||
atom = get_class_info( hInstance, name, wc, NULL, FALSE );
|
||||
if (atom) wc->lpszClassName = name;
|
||||
|
||||
/* We must return the atom of the class here instead of just TRUE. */
|
||||
return atom;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -24,13 +24,6 @@
|
|||
#include "winuser.h"
|
||||
#include "../win32u/ntuser_private.h"
|
||||
|
||||
/* Built-in class names (see _Undocumented_Windows_ p.418) */
|
||||
#define POPUPMENU_CLASS_ATOM MAKEINTATOM(32768) /* PopupMenu */
|
||||
#define DESKTOP_CLASS_ATOM MAKEINTATOM(32769) /* Desktop */
|
||||
#define DIALOG_CLASS_ATOM MAKEINTATOM(32770) /* Dialog */
|
||||
#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771) /* WinSwitch */
|
||||
#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772) /* IconTitle */
|
||||
|
||||
/* Built-in class descriptor */
|
||||
struct builtin_class_descr
|
||||
{
|
||||
|
|
|
@ -328,7 +328,7 @@ static struct dce *get_window_dce( HWND hwnd )
|
|||
*
|
||||
* Free a class or window DCE.
|
||||
*/
|
||||
void free_dce( struct dce *dce, HWND hwnd )
|
||||
void WINAPI free_dce( struct dce *dce, HWND hwnd )
|
||||
{
|
||||
struct dce *dce_to_free = NULL;
|
||||
|
||||
|
|
|
@ -135,12 +135,14 @@ static void dpiaware_init(void)
|
|||
|
||||
static const struct user_callbacks user_funcs =
|
||||
{
|
||||
CopyImage,
|
||||
GetDesktopWindow,
|
||||
GetWindowRect,
|
||||
IsChild,
|
||||
RedrawWindow,
|
||||
SendMessageTimeoutW,
|
||||
WindowFromDC,
|
||||
free_dce,
|
||||
MSG_SendInternalMessageTimeout,
|
||||
};
|
||||
|
||||
|
|
|
@ -113,7 +113,7 @@ extern void create_offscreen_window_surface( const RECT *visible_rect, struct wi
|
|||
extern void CLIPBOARD_ReleaseOwner( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern BOOL FOCUS_MouseActivate( HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern BOOL set_capture_window( HWND hwnd, UINT gui_flags, HWND *prev_ret ) DECLSPEC_HIDDEN;
|
||||
extern void free_dce( struct dce *dce, HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern void WINAPI free_dce( struct dce *dce, HWND hwnd ) DECLSPEC_HIDDEN;
|
||||
extern void invalidate_dce( struct tagWND *win, const RECT *rect ) DECLSPEC_HIDDEN;
|
||||
extern HDC get_display_dc(void) DECLSPEC_HIDDEN;
|
||||
extern void release_display_dc( HDC hdc ) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -42,6 +42,10 @@ static WINDOWPROC winproc_array[MAX_WINPROCS];
|
|||
static UINT winproc_used = NB_BUILTIN_WINPROCS;
|
||||
static pthread_mutex_t winproc_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
static struct list class_list = LIST_INIT( class_list );
|
||||
|
||||
static HINSTANCE user32_module;
|
||||
|
||||
/* find an existing winproc for a given function and type */
|
||||
/* FIXME: probably should do something more clever than a linear search */
|
||||
static WINDOWPROC *find_winproc( WNDPROC func, BOOL ansi )
|
||||
|
@ -129,6 +133,24 @@ WNDPROC alloc_winproc( WNDPROC func, BOOL ansi )
|
|||
return proc_to_handle( proc );
|
||||
}
|
||||
|
||||
/* Get a window procedure pointer that can be passed to the Windows program. */
|
||||
static WNDPROC get_winproc( WNDPROC proc, BOOL ansi )
|
||||
{
|
||||
WINDOWPROC *ptr = get_winproc_ptr( proc );
|
||||
|
||||
if (!ptr || ptr == WINPROC_PROC16) return proc;
|
||||
if (ansi)
|
||||
{
|
||||
if (ptr->procA) return ptr->procA;
|
||||
return proc;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ptr->procW) return ptr->procW;
|
||||
return proc;
|
||||
}
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserInitializeClientPfnArrays (win32u.@)
|
||||
*/
|
||||
|
@ -165,9 +187,31 @@ NTSTATUS WINAPI NtUserInitializeClientPfnArrays( const struct user_client_procs
|
|||
winproc_array[WINPROC_MESSAGE].procA = client_procsA->pMessageWndProc;
|
||||
winproc_array[WINPROC_MESSAGE].procW = client_procsW->pMessageWndProc;
|
||||
|
||||
user32_module = user_module;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_int_atom_value
|
||||
*/
|
||||
static ATOM get_int_atom_value( UNICODE_STRING *name )
|
||||
{
|
||||
const WCHAR *ptr = name->Buffer;
|
||||
const WCHAR *end = ptr + name->Length / sizeof(WCHAR);
|
||||
UINT ret = 0;
|
||||
|
||||
if (IS_INTRESOURCE(ptr)) return LOWORD(ptr);
|
||||
|
||||
if (*ptr++ != '#') return 0;
|
||||
while (ptr < end)
|
||||
{
|
||||
if (*ptr < '0' || *ptr > '9') return 0;
|
||||
ret = ret * 10 + *ptr++ - '0';
|
||||
if (ret > 0xffff) return 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* get_class_ptr
|
||||
*/
|
||||
|
@ -191,15 +235,218 @@ static CLASS *get_class_ptr( HWND hwnd, BOOL write_access )
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* release_class_ptr
|
||||
*/
|
||||
static inline void release_class_ptr( CLASS *ptr )
|
||||
static void release_class_ptr( CLASS *ptr )
|
||||
{
|
||||
user_unlock();
|
||||
}
|
||||
|
||||
static CLASS *find_class( HINSTANCE module, UNICODE_STRING *name )
|
||||
{
|
||||
ATOM atom = get_int_atom_value( name );
|
||||
ULONG_PTR instance = (UINT_PTR)module & ~0xffff;
|
||||
CLASS *class;
|
||||
|
||||
user_lock();
|
||||
LIST_FOR_EACH_ENTRY( class, &class_list, CLASS, entry )
|
||||
{
|
||||
if (atom)
|
||||
{
|
||||
if (class->atomName != atom) continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (wcsnicmp( class->name, name->Buffer, name->Length / sizeof(WCHAR) )) continue;
|
||||
}
|
||||
if (!class->local || !module || (class->instance & ~0xffff) == instance)
|
||||
{
|
||||
TRACE( "%s %lx -> %p\n", debugstr_us(name), instance, class );
|
||||
return class;
|
||||
}
|
||||
}
|
||||
user_unlock();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserRegisterClassExWOW (win32u.@)
|
||||
*/
|
||||
ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version,
|
||||
struct client_menu_name *client_menu_name, DWORD fnid,
|
||||
DWORD flags, DWORD *wow )
|
||||
{
|
||||
const BOOL is_builtin = fnid, ansi = flags;
|
||||
HINSTANCE instance;
|
||||
CLASS *class;
|
||||
ATOM atom;
|
||||
BOOL ret;
|
||||
|
||||
/* create the desktop window to trigger builtin class registration */
|
||||
if (!is_builtin && user_callbacks) user_callbacks->pGetDesktopWindow();
|
||||
|
||||
if (wc->cbSize != sizeof(*wc) || wc->cbClsExtra < 0 || wc->cbWndExtra < 0 ||
|
||||
(!is_builtin && wc->hInstance == user32_module)) /* we can't register a class for user32 */
|
||||
{
|
||||
SetLastError( ERROR_INVALID_PARAMETER );
|
||||
return 0;
|
||||
}
|
||||
if (!(instance = wc->hInstance)) instance = NtCurrentTeb()->Peb->ImageBaseAddress;
|
||||
|
||||
TRACE( "name=%s hinst=%p style=0x%x clExtr=0x%x winExtr=0x%x\n",
|
||||
debugstr_us(name), instance, wc->style, wc->cbClsExtra, wc->cbWndExtra );
|
||||
|
||||
/* Fix the extra bytes value */
|
||||
|
||||
if (wc->cbClsExtra > 40) /* Extra bytes are limited to 40 in Win32 */
|
||||
WARN( "Class extra bytes %d is > 40\n", wc->cbClsExtra);
|
||||
if (wc->cbWndExtra > 40) /* Extra bytes are limited to 40 in Win32 */
|
||||
WARN("Win extra bytes %d is > 40\n", wc->cbWndExtra );
|
||||
|
||||
if (!(class = calloc( 1, sizeof(CLASS) + wc->cbClsExtra ))) return 0;
|
||||
|
||||
class->atomName = get_int_atom_value( name );
|
||||
class->basename = class->name;
|
||||
if (!class->atomName && name)
|
||||
{
|
||||
memcpy( class->name, name->Buffer, name->Length );
|
||||
class->name[name->Length / sizeof(WCHAR)] = 0;
|
||||
class->basename += version->Length / sizeof(WCHAR);
|
||||
}
|
||||
else
|
||||
{
|
||||
UNICODE_STRING str = { .MaximumLength = sizeof(class->name), .Buffer = class->name };
|
||||
NtUserGetAtomName( class->atomName, &str );
|
||||
}
|
||||
|
||||
class->style = wc->style;
|
||||
class->local = !is_builtin && !(wc->style & CS_GLOBALCLASS);
|
||||
class->cbWndExtra = wc->cbWndExtra;
|
||||
class->cbClsExtra = wc->cbClsExtra;
|
||||
class->instance = (UINT_PTR)instance;
|
||||
|
||||
SERVER_START_REQ( create_class )
|
||||
{
|
||||
req->local = class->local;
|
||||
req->style = class->style;
|
||||
req->instance = class->instance;
|
||||
req->extra = class->cbClsExtra;
|
||||
req->win_extra = class->cbWndExtra;
|
||||
req->client_ptr = wine_server_client_ptr( class );
|
||||
req->atom = class->atomName;
|
||||
req->name_offset = version->Length / sizeof(WCHAR);
|
||||
if (!req->atom && name) wine_server_add_data( req, name->Buffer, name->Length );
|
||||
ret = !wine_server_call_err( req );
|
||||
class->atomName = reply->atom;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!ret)
|
||||
{
|
||||
free( class );
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Other non-null values must be set by caller */
|
||||
|
||||
user_lock();
|
||||
if (class->local) list_add_head( &class_list, &class->entry );
|
||||
else list_add_tail( &class_list, &class->entry );
|
||||
|
||||
atom = class->atomName;
|
||||
|
||||
TRACE( "name=%s->%s atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
|
||||
debugstr_w(wc->lpszClassName), debugstr_us(name), atom, wc->lpfnWndProc, instance,
|
||||
wc->hbrBackground, wc->style, wc->cbClsExtra, wc->cbWndExtra, class );
|
||||
|
||||
class->hIcon = wc->hIcon;
|
||||
class->hIconSm = wc->hIconSm;
|
||||
class->hCursor = wc->hCursor;
|
||||
class->hbrBackground = wc->hbrBackground;
|
||||
class->winproc = alloc_winproc( wc->lpfnWndProc, ansi );
|
||||
class->menu_name = *client_menu_name;
|
||||
if (wc->hIcon && !wc->hIconSm && user_callbacks)
|
||||
class->hIconSmIntern = user_callbacks->pCopyImage( wc->hIcon, IMAGE_ICON,
|
||||
get_system_metrics( SM_CXSMICON ),
|
||||
get_system_metrics( SM_CYSMICON ),
|
||||
LR_COPYFROMRESOURCE );
|
||||
release_class_ptr( class );
|
||||
return atom;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserUnregisterClass (win32u.@)
|
||||
*/
|
||||
BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance,
|
||||
struct client_menu_name *client_menu_name )
|
||||
{
|
||||
CLASS *class = NULL;
|
||||
|
||||
if (user_callbacks) /* create the desktop window to trigger builtin class registration */
|
||||
user_callbacks->pGetDesktopWindow();
|
||||
|
||||
SERVER_START_REQ( destroy_class )
|
||||
{
|
||||
req->instance = wine_server_client_ptr( instance );
|
||||
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 )) class = wine_server_get_ptr( reply->client_ptr );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
if (!class) return FALSE;
|
||||
|
||||
TRACE( "%p\n", class );
|
||||
|
||||
user_lock();
|
||||
if (class->dce && user_callbacks) user_callbacks->free_dce( class->dce, 0 );
|
||||
list_remove( &class->entry );
|
||||
if (class->hbrBackground > (HBRUSH)(COLOR_GRADIENTINACTIVECAPTION + 1))
|
||||
NtGdiDeleteObjectApp( class->hbrBackground );
|
||||
NtUserDestroyCursor( class->hIconSmIntern, 0 );
|
||||
free( class );
|
||||
user_unlock();
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserGetClassInfo (win32u.@)
|
||||
*/
|
||||
ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDCLASSEXW *wc,
|
||||
struct client_menu_name *menu_name, BOOL ansi )
|
||||
{
|
||||
static const WCHAR messageW[] = {'M','e','s','s','a','g','e'};
|
||||
CLASS *class;
|
||||
ATOM atom;
|
||||
|
||||
/* create the desktop window to trigger builtin class registration */
|
||||
if (name->Buffer != (const WCHAR *)DESKTOP_CLASS_ATOM &&
|
||||
(IS_INTRESOURCE(name->Buffer) || name->Length != sizeof(messageW) ||
|
||||
wcsnicmp( name->Buffer, messageW, ARRAYSIZE(messageW) )))
|
||||
user_callbacks->pGetDesktopWindow();
|
||||
|
||||
if (!(class = find_class( instance, name ))) return 0;
|
||||
|
||||
if (wc)
|
||||
{
|
||||
wc->style = class->style;
|
||||
wc->lpfnWndProc = get_winproc( class->winproc, ansi );
|
||||
wc->cbClsExtra = class->cbClsExtra;
|
||||
wc->cbWndExtra = class->cbWndExtra;
|
||||
wc->hInstance = (instance == user32_module) ? 0 : instance;
|
||||
wc->hIcon = class->hIcon;
|
||||
wc->hIconSm = class->hIconSm ? class->hIconSm : class->hIconSmIntern;
|
||||
wc->hCursor = class->hCursor;
|
||||
wc->hbrBackground = class->hbrBackground;
|
||||
wc->lpszMenuName = ansi ? (const WCHAR *)class->menu_name.nameA : class->menu_name.nameW;
|
||||
wc->lpszClassName = name->Buffer;
|
||||
}
|
||||
|
||||
if (menu_name) *menu_name = class->menu_name;
|
||||
atom = class->atomName;
|
||||
release_class_ptr( class );
|
||||
return atom;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* NtUserGetAtomName (win32u.@)
|
||||
*/
|
||||
|
|
|
@ -1165,6 +1165,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtUserEnumDisplayMonitors,
|
||||
NtUserEnumDisplaySettings,
|
||||
NtUserGetAsyncKeyState,
|
||||
NtUserGetClassInfoEx,
|
||||
NtUserGetCursorInfo,
|
||||
NtUserGetDisplayConfigBufferSizes,
|
||||
NtUserGetIconInfo,
|
||||
|
@ -1175,6 +1176,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtUserGetUpdatedClipboardFormats,
|
||||
NtUserIsClipboardFormatAvailable,
|
||||
NtUserMapVirtualKeyEx,
|
||||
NtUserRegisterClassExWOW,
|
||||
NtUserRegisterHotKey,
|
||||
NtUserScrollDC,
|
||||
NtUserSelectPalette,
|
||||
|
@ -1186,6 +1188,7 @@ static struct unix_funcs unix_funcs =
|
|||
NtUserSystemParametersInfo,
|
||||
NtUserSystemParametersInfoForDpi,
|
||||
NtUserToUnicodeEx,
|
||||
NtUserUnregisterClass,
|
||||
NtUserUnregisterHotKey,
|
||||
NtUserVkKeyScanEx,
|
||||
|
||||
|
|
|
@ -25,14 +25,18 @@
|
|||
#include "ntuser.h"
|
||||
#include "wine/list.h"
|
||||
|
||||
struct dce;
|
||||
|
||||
struct user_callbacks
|
||||
{
|
||||
HANDLE (WINAPI *pCopyImage)( HANDLE, UINT, INT, INT, UINT );
|
||||
HWND (WINAPI *pGetDesktopWindow)(void);
|
||||
BOOL (WINAPI *pGetWindowRect)( HWND hwnd, LPRECT rect );
|
||||
BOOL (WINAPI *pIsChild)( HWND, HWND );
|
||||
BOOL (WINAPI *pRedrawWindow)( HWND, const RECT*, HRGN, UINT );
|
||||
LRESULT (WINAPI *pSendMessageTimeoutW)( HWND, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
|
||||
HWND (WINAPI *pWindowFromDC)( HDC );
|
||||
void (WINAPI *free_dce)( struct dce *dce, HWND hwnd );
|
||||
LRESULT (WINAPI *send_ll_message)( DWORD, DWORD, UINT, WPARAM, LPARAM, UINT, UINT, PDWORD_PTR );
|
||||
};
|
||||
|
||||
|
@ -169,6 +173,13 @@ typedef struct tagWINDOWPROC
|
|||
|
||||
#define MAX_ATOM_LEN 255
|
||||
|
||||
/* Built-in class names (see _Undocumented_Windows_ p.418) */
|
||||
#define POPUPMENU_CLASS_ATOM MAKEINTATOM(32768) /* PopupMenu */
|
||||
#define DESKTOP_CLASS_ATOM MAKEINTATOM(32769) /* Desktop */
|
||||
#define DIALOG_CLASS_ATOM MAKEINTATOM(32770) /* Dialog */
|
||||
#define WINSWITCH_CLASS_ATOM MAKEINTATOM(32771) /* WinSwitch */
|
||||
#define ICONTITLE_CLASS_ATOM MAKEINTATOM(32772) /* IconTitle */
|
||||
|
||||
typedef struct tagCLASS
|
||||
{
|
||||
struct list entry; /* Entry in class list */
|
||||
|
|
|
@ -898,7 +898,7 @@
|
|||
@ stub NtUserGetCPD
|
||||
@ stub NtUserGetCaretBlinkTime
|
||||
@ stub NtUserGetCaretPos
|
||||
@ stub NtUserGetClassInfoEx
|
||||
@ stdcall NtUserGetClassInfoEx(ptr ptr ptr ptr long)
|
||||
@ stdcall -syscall NtUserGetClassName(long long ptr)
|
||||
@ stub NtUserGetClipCursor
|
||||
@ stub NtUserGetClipboardAccessToken
|
||||
|
@ -1122,7 +1122,7 @@
|
|||
@ stub NtUserRealWaitMessageEx
|
||||
@ stub NtUserRedrawWindow
|
||||
@ stub NtUserRegisterBSDRWindow
|
||||
@ stub NtUserRegisterClassExWOW
|
||||
@ stdcall NtUserRegisterClassExWOW(ptr ptr ptr ptr long long long)
|
||||
@ stub NtUserRegisterDManipHook
|
||||
@ stub NtUserRegisterEdgy
|
||||
@ stub NtUserRegisterErrorReportingDialog
|
||||
|
@ -1288,7 +1288,7 @@
|
|||
@ stdcall -syscall NtUserUnhookWindowsHookEx(long)
|
||||
@ stub NtUserUnloadKeyboardLayout
|
||||
@ stub NtUserUnlockWindowStation
|
||||
@ stub NtUserUnregisterClass
|
||||
@ stdcall NtUserUnregisterClass(ptr ptr ptr)
|
||||
@ stdcall NtUserUnregisterHotKey(long long)
|
||||
@ stub NtUserUnregisterSessionPort
|
||||
@ stub NtUserUnregisterUserApiHook
|
||||
|
|
|
@ -203,6 +203,8 @@ struct unix_funcs
|
|||
BOOL (WINAPI *pNtUserEnumDisplaySettings)( UNICODE_STRING *device, DWORD mode,
|
||||
DEVMODEW *dev_mode, DWORD flags );
|
||||
SHORT (WINAPI *pNtUserGetAsyncKeyState)( INT key );
|
||||
ATOM (WINAPI *pNtUserGetClassInfoEx)( HINSTANCE instance, UNICODE_STRING *name, WNDCLASSEXW *wc,
|
||||
struct client_menu_name *menu_name, BOOL ansi );
|
||||
BOOL (WINAPI *pNtUserGetCursorInfo)( CURSORINFO *info );
|
||||
LONG (WINAPI *pNtUserGetDisplayConfigBufferSizes)( UINT32 flags, UINT32 *num_path_info,
|
||||
UINT32 *num_mode_info );
|
||||
|
@ -215,6 +217,10 @@ struct unix_funcs
|
|||
BOOL (WINAPI *pNtUserGetUpdatedClipboardFormats)( UINT *formats, UINT size, UINT *out_size );
|
||||
BOOL (WINAPI *pNtUserIsClipboardFormatAvailable)( UINT format );
|
||||
UINT (WINAPI *pNtUserMapVirtualKeyEx)( UINT code, UINT type, HKL layout );
|
||||
ATOM (WINAPI *pNtUserRegisterClassExWOW)( const WNDCLASSEXW *wc, UNICODE_STRING *name,
|
||||
UNICODE_STRING *version,
|
||||
struct client_menu_name *client_menu_name,
|
||||
DWORD fnid, DWORD flags, DWORD *wow );
|
||||
BOOL (WINAPI *pNtUserRegisterHotKey)( HWND hwnd, INT id, UINT modifiers, UINT vk );
|
||||
BOOL (WINAPI *pNtUserScrollDC)( HDC hdc, INT dx, INT dy, const RECT *scroll, const RECT *clip,
|
||||
HRGN ret_update_rgn, RECT *update_rect );
|
||||
|
@ -230,6 +236,8 @@ struct unix_funcs
|
|||
UINT winini, UINT dpi );
|
||||
INT (WINAPI *pNtUserToUnicodeEx)( UINT virt, UINT scan, const BYTE *state,
|
||||
WCHAR *str, int size, UINT flags, HKL layout );
|
||||
BOOL (WINAPI *pNtUserUnregisterClass)( UNICODE_STRING *name, HINSTANCE instance,
|
||||
struct client_menu_name *client_menu_name );
|
||||
BOOL (WINAPI *pNtUserUnregisterHotKey)( HWND hwnd, INT id );
|
||||
WORD (WINAPI *pNtUserVkKeyScanEx)( WCHAR chr, HKL layout );
|
||||
|
||||
|
|
|
@ -795,6 +795,13 @@ SHORT WINAPI NtUserGetAsyncKeyState( INT key )
|
|||
return unix_funcs->pNtUserGetAsyncKeyState( key );
|
||||
}
|
||||
|
||||
ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDCLASSEXW *wc,
|
||||
struct client_menu_name *menu_name, BOOL ansi )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
return unix_funcs->pNtUserGetClassInfoEx( instance, name, wc, menu_name, ansi );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserGetCursorInfo( CURSORINFO *info )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
|
@ -857,6 +864,14 @@ UINT WINAPI NtUserMapVirtualKeyEx( UINT code, UINT type, HKL layout )
|
|||
return unix_funcs->pNtUserMapVirtualKeyEx( code, type, layout );
|
||||
}
|
||||
|
||||
ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version,
|
||||
struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags,
|
||||
DWORD *wow )
|
||||
{
|
||||
if (!unix_funcs) return 0;
|
||||
return unix_funcs->pNtUserRegisterClassExWOW( wc, name, version, client_menu_name, fnid, flags, wow );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserRegisterHotKey( HWND hwnd, INT id, UINT modifiers, UINT vk )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
|
@ -926,6 +941,13 @@ INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state,
|
|||
return unix_funcs->pNtUserToUnicodeEx( virt, scan, state, str, size, flags, layout );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance,
|
||||
struct client_menu_name *client_menu_name )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
return unix_funcs->pNtUserUnregisterClass( name, instance, client_menu_name );
|
||||
}
|
||||
|
||||
BOOL WINAPI NtUserUnregisterHotKey( HWND hwnd, INT id )
|
||||
{
|
||||
if (!unix_funcs) return FALSE;
|
||||
|
|
|
@ -264,6 +264,8 @@ HICON WINAPI NtUserFindExistingCursorIcon( UNICODE_STRING *module, UNICODE_STR
|
|||
void *desc );
|
||||
SHORT WINAPI NtUserGetAsyncKeyState( INT key );
|
||||
ULONG WINAPI NtUserGetAtomName( ATOM atom, UNICODE_STRING *name );
|
||||
ATOM WINAPI NtUserGetClassInfoEx( HINSTANCE instance, UNICODE_STRING *name, WNDCLASSEXW *wc,
|
||||
struct client_menu_name *menu_name, BOOL ansi );
|
||||
INT WINAPI NtUserGetClassName( HWND hwnd, BOOL real, UNICODE_STRING *name );
|
||||
INT WINAPI NtUserGetClipboardFormatName( UINT format, WCHAR *buffer, INT maxlen );
|
||||
HWND WINAPI NtUserGetClipboardOwner(void);
|
||||
|
@ -312,6 +314,9 @@ HWINSTA WINAPI NtUserOpenWindowStation( OBJECT_ATTRIBUTES *attr, ACCESS_MASK acc
|
|||
BOOL WINAPI NtUserSetObjectInformation( HANDLE handle, INT index, void *info, DWORD len );
|
||||
HDESK WINAPI NtUserOpenDesktop( OBJECT_ATTRIBUTES *attr, DWORD flags, ACCESS_MASK access );
|
||||
HDESK WINAPI NtUserOpenInputDesktop( DWORD flags, BOOL inherit, ACCESS_MASK access );
|
||||
ATOM WINAPI NtUserRegisterClassExWOW( const WNDCLASSEXW *wc, UNICODE_STRING *name, UNICODE_STRING *version,
|
||||
struct client_menu_name *client_menu_name, DWORD fnid, DWORD flags,
|
||||
DWORD *wow );
|
||||
BOOL WINAPI NtUserRegisterHotKey( HWND hwnd, INT id, UINT modifiers, UINT vk );
|
||||
BOOL WINAPI NtUserRemoveClipboardFormatListener( HWND hwnd );
|
||||
HANDLE WINAPI NtUserRemoveProp( HWND hwnd, const WCHAR *str );
|
||||
|
@ -340,6 +345,8 @@ INT WINAPI NtUserToUnicodeEx( UINT virt, UINT scan, const BYTE *state,
|
|||
WCHAR *str, int size, UINT flags, HKL layout );
|
||||
BOOL WINAPI NtUserUnhookWinEvent( HWINEVENTHOOK hEventHook );
|
||||
BOOL WINAPI NtUserUnhookWindowsHookEx( HHOOK handle );
|
||||
BOOL WINAPI NtUserUnregisterClass( UNICODE_STRING *name, HINSTANCE instance,
|
||||
struct client_menu_name *client_menu_name );
|
||||
BOOL WINAPI NtUserUnregisterHotKey( HWND hwnd, INT id );
|
||||
WORD WINAPI NtUserVkKeyScanEx( WCHAR chr, HKL layout );
|
||||
|
||||
|
|
Loading…
Reference in a new issue