diff --git a/reactos/dll/win32/user32/misc/dllmain.c b/reactos/dll/win32/user32/misc/dllmain.c index 833d99c5deb..ad93bf773d1 100644 --- a/reactos/dll/win32/user32/misc/dllmain.c +++ b/reactos/dll/win32/user32/misc/dllmain.c @@ -230,6 +230,8 @@ Init(VOID) (PVOID)User32CallHookProcFromKernel; NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_EVENTPROC] = (PVOID)User32CallEventProcFromKernel; + NtCurrentPeb()->KernelCallbackTable[USER32_CALLBACK_LOADMENU] = + (PVOID)User32CallLoadMenuFromKernel; NtUserProcessConnect( NtCurrentProcess(), &UserCon, diff --git a/reactos/dll/win32/user32/windows/class.c b/reactos/dll/win32/user32/windows/class.c index 3607e675bb4..1bed4ac1033 100644 --- a/reactos/dll/win32/user32/windows/class.c +++ b/reactos/dll/win32/user32/windows/class.c @@ -826,8 +826,83 @@ RegisterClassExWOWW(WNDCLASSEXW *lpwcx, WORD fnID, DWORD dwFlags) { - RTL_ATOM Atom = 0; - return (ATOM)Atom; + ATOM Atom; + WNDCLASSEXW WndClass; + UNICODE_STRING ClassName; + UNICODE_STRING MenuName = {0}; + CLSMENUNAME clsMenuName; + ANSI_STRING AnsiMenuName; + + if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) || + lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 || + lpwcx->lpszClassName == NULL) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + if (lpwcx->hInstance == User32Instance) + { + SetLastError(ERROR_INVALID_PARAMETER); + return 0; + } + + /* Yes, this is correct. We should modify the passed structure. */ + if (lpwcx->hInstance == NULL) + ((WNDCLASSEXW*)lpwcx)->hInstance = GetModuleHandleW(NULL); + + RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXW)); + + if (NULL == WndClass.hIconSm) + { + WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon); + } + + if (WndClass.lpszMenuName != NULL) + { + if (!IS_INTRESOURCE(WndClass.lpszMenuName)) + { + if (WndClass.lpszMenuName[0]) + { + RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName); + } + } + else + { + MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName; + } + } + + if (IS_ATOM(WndClass.lpszClassName)) + { + ClassName.Length = + ClassName.MaximumLength = 0; + ClassName.Buffer = (LPWSTR)WndClass.lpszClassName; + } + else + { + RtlInitUnicodeString(&ClassName, WndClass.lpszClassName); + } + + RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE); + + clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer; + clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer; + clsMenuName.pusMenuName = &MenuName; + + Atom = NtUserRegisterClassExWOW( &WndClass, + &ClassName, + NULL, //PUNICODE_STRING ClsNVersion, + &clsMenuName, + fnID, + dwFlags, + pdwWowData); + + TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n", + Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground, + lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass); + + return Atom; } /* @@ -840,7 +915,8 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) WNDCLASSEXA WndClass; UNICODE_STRING ClassName; UNICODE_STRING MenuName = {0}; - HMENU hMenu = NULL; + CLSMENUNAME clsMenuName; + ANSI_STRING AnsiMenuName; if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) || lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 || @@ -850,14 +926,6 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) return 0; } - /* - * On real Windows this looks more like: - * if (lpwcx->hInstance == User32Instance && - * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400) - * But since I have no idea what the magic field in the - * TEB structure means, I rather decided to omit that. - * -- Filip Navara - */ if (lpwcx->hInstance == User32Instance) { SetLastError(ERROR_INVALID_PARAMETER); @@ -888,9 +956,6 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) { MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName; } - - if (MenuName.Buffer != NULL) - hMenu = LoadMenuA(WndClass.hInstance, WndClass.lpszMenuName); } if (IS_ATOM(WndClass.lpszClassName)) @@ -904,19 +969,29 @@ RegisterClassExA(CONST WNDCLASSEXA *lpwcx) RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName); } - Atom = NtUserRegisterClassEx((WNDCLASSEXW*)&WndClass, - &ClassName, - &MenuName, - NULL, - REGISTERCLASS_ANSI, - hMenu); + RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE); - TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n", + clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer; + clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer; + clsMenuName.pusMenuName = &MenuName; + + Atom = NtUserRegisterClassExWOW( (WNDCLASSEXW*)&WndClass, + &ClassName, + NULL, //PUNICODE_STRING ClsNVersion, + &clsMenuName, + 0, + CSF_ANSIPROC, + 0); + + TRACE("A atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n", Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground, lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass); if (!IS_INTRESOURCE(WndClass.lpszMenuName)) + { RtlFreeUnicodeString(&MenuName); + RtlFreeAnsiString(&AnsiMenuName); + } if (!IS_ATOM(WndClass.lpszClassName)) RtlFreeUnicodeString(&ClassName); @@ -933,7 +1008,8 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx) WNDCLASSEXW WndClass; UNICODE_STRING ClassName; UNICODE_STRING MenuName = {0}; - HMENU hMenu = NULL; + CLSMENUNAME clsMenuName; + ANSI_STRING AnsiMenuName; if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) || lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 || @@ -950,6 +1026,8 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx) * But since I have no idea what the magic field in the * TEB structure means, I rather decided to omit that. * -- Filip Navara + + GetWin32ClientInfo()->ulWindowsVersion & (WINVER == 400) */ if (lpwcx->hInstance == User32Instance) { @@ -981,9 +1059,6 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx) { MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName; } - - if (MenuName.Buffer != NULL) - hMenu = LoadMenuW(WndClass.hInstance, WndClass.lpszMenuName); } if (IS_ATOM(WndClass.lpszClassName)) @@ -997,14 +1072,21 @@ RegisterClassExW(CONST WNDCLASSEXW *lpwcx) RtlInitUnicodeString(&ClassName, WndClass.lpszClassName); } - Atom = (ATOM)NtUserRegisterClassEx(&WndClass, - &ClassName, - &MenuName, - NULL, - 0, - hMenu); + RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE); - TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n", + clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer; + clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer; + clsMenuName.pusMenuName = &MenuName; + + Atom = NtUserRegisterClassExWOW( &WndClass, + &ClassName, + NULL, //PUNICODE_STRING ClsNVersion, + &clsMenuName, + 0, + 0, + 0); + + TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n", Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground, lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra, WndClass); diff --git a/reactos/dll/win32/user32/windows/menu.c b/reactos/dll/win32/user32/windows/menu.c index 3dd99a4dc97..c32a55ec7c3 100644 --- a/reactos/dll/win32/user32/windows/menu.c +++ b/reactos/dll/win32/user32/windows/menu.c @@ -3945,6 +3945,19 @@ MenuSetItemData( return TRUE; } +NTSTATUS WINAPI +User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength) +{ + PLOADMENU_CALLBACK_ARGUMENTS Common; + LRESULT Result; + + Common = (PLOADMENU_CALLBACK_ARGUMENTS) Arguments; + + Result = (LRESULT)LoadMenuW(Common->hModule, (LPCWSTR)&Common->MenuName); + + return ZwCallbackReturn(&Result, sizeof(LRESULT), STATUS_SUCCESS); +} + /* FUNCTIONS *****************************************************************/ diff --git a/reactos/dll/win32/user32/windows/window.c b/reactos/dll/win32/user32/windows/window.c index a8ef483641f..92fab7abab6 100644 --- a/reactos/dll/win32/user32/windows/window.c +++ b/reactos/dll/win32/user32/windows/window.c @@ -241,7 +241,7 @@ User32CreateWindowEx(DWORD dwExStyle, hInstance, lpParam, SW_SHOW, - FALSE, + Unicode, 0); #if 0 @@ -1762,13 +1762,7 @@ SetWindowContextHelpId(HWND hwnd, DWORD WINAPI GetWindowContextHelpId(HWND hwnd) { - PWINDOW Wnd = ValidateHwnd(hwnd); - if (Wnd != NULL) - { - return Wnd->ContextHelpId; - } - - return 0; + return NtUserCallHwnd(hwnd, HWND_ROUTINE_GETWNDCONTEXTHLPID); } /* diff --git a/reactos/include/reactos/win32k/callback.h b/reactos/include/reactos/win32k/callback.h index b28d7355716..74a405cc9d7 100644 --- a/reactos/include/reactos/win32k/callback.h +++ b/reactos/include/reactos/win32k/callback.h @@ -7,7 +7,8 @@ #define USER32_CALLBACK_LOADDEFAULTCURSORS (3) #define USER32_CALLBACK_HOOKPROC (4) #define USER32_CALLBACK_EVENTPROC (5) -#define USER32_CALLBACK_MAXIMUM (5) +#define USER32_CALLBACK_LOADMENU (6) +#define USER32_CALLBACK_MAXIMUM (6) typedef struct _WINDOWPROC_CALLBACK_ARGUMENTS { @@ -63,6 +64,12 @@ typedef struct _EVENTPROC_CALLBACK_ARGUMENTS WINEVENTPROC Proc; } EVENTPROC_CALLBACK_ARGUMENTS, *PEVENTPROC_CALLBACK_ARGUMENTS; +typedef struct _LOADMENU_CALLBACK_ARGUMENTS +{ + HINSTANCE hModule; + WCHAR MenuName[1]; +} LOADMENU_CALLBACK_ARGUMENTS, *PLOADMENU_CALLBACK_ARGUMENTS; + NTSTATUS WINAPI User32CallWindowProcFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI @@ -75,5 +82,7 @@ NTSTATUS WINAPI User32CallHookProcFromKernel(PVOID Arguments, ULONG ArgumentLength); NTSTATUS WINAPI User32CallEventProcFromKernel(PVOID Arguments, ULONG ArgumentLength); +NTSTATUS WINAPI +User32CallLoadMenuFromKernel(PVOID Arguments, ULONG ArgumentLength); #endif /* __INCLUDE_USER32_CALLBACK_H */ diff --git a/reactos/include/reactos/win32k/ntuser.h b/reactos/include/reactos/win32k/ntuser.h index 46d2b67a291..b80b4aaaf9e 100644 --- a/reactos/include/reactos/win32k/ntuser.h +++ b/reactos/include/reactos/win32k/ntuser.h @@ -118,7 +118,6 @@ typedef struct _WINDOWCLASS DWORD CSF_flags; PSTR lpszClientAnsiMenuName; PWSTR lpszClientUnicodeMenuName; - HANDLE hMenu; /* FIXME - Use pointer! */ PCALLPROC spcpdFirst; struct _WINDOWCLASS *pclsBase; struct _WINDOWCLASS *pclsClone; @@ -283,7 +282,7 @@ typedef struct _WINDOW LIST_ENTRY PropListHead; ULONG PropListItems; /* Window menu handle or window id */ - UINT IDMenu; + UINT IDMenu; // Use spmenu //PMENU spmenuSys; //PMENU spmenu; HRGN hrgnClip; @@ -300,9 +299,6 @@ typedef struct _WINDOW struct _WINDOW *spwndClipboardListener; DWORD ExStyle2; - /* Context help id */ - DWORD ContextHelpId; - struct { RECT NormalRect; @@ -310,7 +306,7 @@ typedef struct _WINDOW POINT MaxPos; } InternalPos; - UINT Unicode : 1; // !WNDS_ANSICREATOR ? + UINT Unicode : 1; // !(WNDS_ANSICREATOR|WNDS_ANSIWINDOWPROC) ? /* Indicates whether the window is derived from a system class */ UINT IsSystem : 1; // System class ? UINT InternalPosInitialized : 1; @@ -1344,7 +1340,7 @@ NtUserCreateWindowEx( HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam, - DWORD dwFlags, + DWORD dwFlags, // |= 1 == Ansi PVOID acbiBuffer); #endif @@ -2993,7 +2989,6 @@ typedef struct tagKMDDELPARAM #define ONEPARAM_ROUTINE_CREATECURICONHANDLE 0xfffe0025 // CREATE_EMPTY_CURSOR_OBJECT ? #define ONEPARAM_ROUTINE_MSQSETWAKEMASK 0xfffe0027 #define ONEPARAM_ROUTINE_REGISTERUSERMODULE 0xfffe0031 -#define ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID 0xfffe0047 // use HWND_ROUTINE_GETWNDCONTEXTHLPID #define ONEPARAM_ROUTINE_GETCURSORPOSITION 0xfffe0048 // use ONEPARAM_ or TWOPARAM routine ? #define TWOPARAM_ROUTINE_GETWINDOWRGNBOX 0xfffd0048 // user mode #define TWOPARAM_ROUTINE_GETWINDOWRGN 0xfffd0049 // user mode @@ -3165,22 +3160,6 @@ NtUserMonitorFromWindow( IN DWORD dwFlags); -/* FIXME: These flag constans aren't what Windows uses. */ -#define REGISTERCLASS_ANSI 2 -#define REGISTERCLASS_ALL (REGISTERCLASS_ANSI) - -RTL_ATOM -NTAPI -NtUserRegisterClassEx( // Need to use NtUserRegisterClassExWOW. - CONST WNDCLASSEXW* lpwcx, - PUNICODE_STRING ClassName, - PUNICODE_STRING MenuName, - WNDPROC wpExtra, - DWORD Flags, - HMENU hMenu); - - - typedef struct tagNTUSERSENDMESSAGEINFO { BOOL HandledByKernel; diff --git a/reactos/subsystems/win32/win32k/include/callback.h b/reactos/subsystems/win32/win32k/include/callback.h index d99f1e9a004..48136d8c280 100644 --- a/reactos/subsystems/win32/win32k/include/callback.h +++ b/reactos/subsystems/win32/win32k/include/callback.h @@ -54,4 +54,6 @@ IntCbAllocateMemory(ULONG Size); VOID FASTCALL IntCbFreeMemory(PVOID Data); +HMENU APIENTRY co_IntCallLoadMenu(HINSTANCE,PUNICODE_STRING); + #endif /* _WIN32K_CALLBACK_H */ diff --git a/reactos/subsystems/win32/win32k/include/class.h b/reactos/subsystems/win32/win32k/include/class.h index b086971ec84..8cb81d3039b 100644 --- a/reactos/subsystems/win32/win32k/include/class.h +++ b/reactos/subsystems/win32/win32k/include/class.h @@ -58,7 +58,6 @@ RTL_ATOM UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx, IN PUNICODE_STRING ClassName, IN PUNICODE_STRING MenuName, - IN HANDLE hMenu, IN WNDPROC wpExtra, IN DWORD dwFlags); @@ -78,8 +77,6 @@ IntGetClassAtom(IN PUNICODE_STRING ClassName, OUT PWINDOWCLASS *BaseClass OPTIONAL, OUT PWINDOWCLASS **Link OPTIONAL); -#define REGISTERCLASS_SYSTEM 0x4 - PWINDOWCLASS FASTCALL IntCreateClass(IN CONST WNDCLASSEXW* lpwcx, diff --git a/reactos/subsystems/win32/win32k/include/prop.h b/reactos/subsystems/win32/win32k/include/prop.h index 27a021a7a0e..2d33df9971d 100644 --- a/reactos/subsystems/win32/win32k/include/prop.h +++ b/reactos/subsystems/win32/win32k/include/prop.h @@ -1,6 +1,9 @@ #ifndef _WIN32K_PROP_H #define _WIN32K_PROP_H +PPROPERTY FASTCALL IntGetProp(PWINDOW_OBJECT,ATOM); +BOOL FASTCALL IntRemoveProp(PWINDOW_OBJECT,ATOM); +BOOL FASTCALL IntSetProp(PWINDOW_OBJECT, ATOM, HANDLE); #endif /* _WIN32K_PROP_H */ diff --git a/reactos/subsystems/win32/win32k/ntuser/callback.c b/reactos/subsystems/win32/win32k/ntuser/callback.c index d32a047ed1f..deb75a00e10 100644 --- a/reactos/subsystems/win32/win32k/ntuser/callback.c +++ b/reactos/subsystems/win32/win32k/ntuser/callback.c @@ -666,4 +666,57 @@ co_IntCallEventProc(HWINEVENTHOOK hook, return Result; } +// +// Callback Load Menu and results. +// +HMENU +APIENTRY +co_IntCallLoadMenu( HINSTANCE hModule, + PUNICODE_STRING pMenuName ) +{ + LRESULT Result = 0; + NTSTATUS Status; + PLOADMENU_CALLBACK_ARGUMENTS Common; + ULONG ArgumentLength, ResultLength; + PVOID Argument, ResultPointer; + + ArgumentLength = sizeof(LOADMENU_CALLBACK_ARGUMENTS); + + ArgumentLength += pMenuName->Length + sizeof(WCHAR); + + Argument = IntCbAllocateMemory(ArgumentLength); + if (NULL == Argument) + { + DPRINT1("EventProc callback failed: out of memory\n"); + return 0; + } + Common = (PLOADMENU_CALLBACK_ARGUMENTS) Argument; + + + Common->hModule = hModule; + RtlCopyMemory(&Common->MenuName, pMenuName->Buffer, pMenuName->Length); + + ResultPointer = NULL; + ResultLength = sizeof(LRESULT); + + UserLeaveCo(); + + Status = KeUserModeCallback(USER32_CALLBACK_LOADMENU, + Argument, + ArgumentLength, + &ResultPointer, + &ResultLength); + + UserEnterCo(); + + IntCbFreeMemory(Argument); + + if (!NT_SUCCESS(Status)) + { + return 0; + } + + return (HMENU)Result; +} + /* EOF */ diff --git a/reactos/subsystems/win32/win32k/ntuser/class.c b/reactos/subsystems/win32/win32k/ntuser/class.c index f1d0ce98726..51a3c7f0baa 100644 --- a/reactos/subsystems/win32/win32k/ntuser/class.c +++ b/reactos/subsystems/win32/win32k/ntuser/class.c @@ -892,9 +892,9 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx, Class->pclsBase = Class; Class->atomClassName = Atom; - if (dwFlags & REGISTERCLASS_SYSTEM) + if (dwFlags & CSF_SYSTEMCLASS) { - dwFlags &= ~REGISTERCLASS_ANSI; + dwFlags &= ~CSF_ANSIPROC; Class->WndProcExtra = wpExtra; Class->System = TRUE; } @@ -954,7 +954,7 @@ IntCreateClass(IN CONST WNDCLASSEXW* lpwcx, else Class->AnsiMenuName = (PSTR)MenuName->Buffer; - if (!(dwFlags & REGISTERCLASS_ANSI)) + if (!(dwFlags & CSF_ANSIPROC)) Class->Unicode = TRUE; if (Class->style & CS_GLOBALCLASS) @@ -1177,7 +1177,6 @@ RTL_ATOM UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx, IN PUNICODE_STRING ClassName, IN PUNICODE_STRING MenuName, - IN HANDLE hMenu, /* FIXME */ IN WNDPROC wpExtra, IN DWORD dwFlags) { @@ -1239,9 +1238,6 @@ UserRegisterClass(IN CONST WNDCLASSEXW* lpwcx, { PWINDOWCLASS *List; - /* FIXME - pass the PMENU pointer to IntCreateClass instead! */ - Class->hMenu = hMenu; - /* Register the class */ if (Class->System) List = &pi->SystemClassList; @@ -1901,7 +1897,7 @@ UserRegisterSystemClasses(IN ULONG Count, &ClassName, &MenuName, SystemClasses[i].ProcA, - REGISTERCLASS_SYSTEM, + CSF_SYSTEMCLASS, NULL, pi); if (Class != NULL) @@ -1933,15 +1929,16 @@ UserRegisterSystemClasses(IN ULONG Count, /* SYSCALLS *****************************************************************/ - -RTL_ATOM APIENTRY -NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx, - IN PUNICODE_STRING ClassName, - IN PUNICODE_STRING MenuName, - IN WNDPROC wpExtra, - IN DWORD Flags, - IN HMENU hMenu) - +RTL_ATOM +APIENTRY +NtUserRegisterClassExWOW( + WNDCLASSEXW* lpwcx, + PUNICODE_STRING ClassName, + PUNICODE_STRING ClsNVersion, + PCLSMENUNAME pClassMenuName, + DWORD fnID, + DWORD Flags, + LPDWORD pWow) /* * FUNCTION: * Registers a new class with the window manager @@ -1949,7 +1946,6 @@ NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx, * lpwcx = Win32 extended window class structure * bUnicodeClass = Whether to send ANSI or unicode strings * to window procedures - * wpExtra = Extra window procedure, if this is not null, its used for the second window procedure for standard controls. * RETURNS: * Atom identifying the new class */ @@ -1957,8 +1953,9 @@ NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx, WNDCLASSEXW CapturedClassInfo = {0}; UNICODE_STRING CapturedName = {0}, CapturedMenuName = {0}; RTL_ATOM Ret = (RTL_ATOM)0; + WNDPROC wpExtra = NULL; - if (Flags & ~REGISTERCLASS_ALL) + if (Flags & ~(CSF_ANSIPROC)) { SetLastWin32Error(ERROR_INVALID_FLAGS); return Ret; @@ -1982,14 +1979,22 @@ NtUserRegisterClassEx(IN CONST WNDCLASSEXW* lpwcx, sizeof(WNDCLASSEXW)); CapturedName = ProbeForReadUnicodeString(ClassName); - CapturedMenuName = ProbeForReadUnicodeString(MenuName); - if (CapturedName.Length & 1 || CapturedMenuName.Length & 1 || - CapturedClassInfo.cbClsExtra < 0 || - CapturedClassInfo.cbClsExtra + CapturedName.Length + - CapturedMenuName.Length + sizeof(WINDOWCLASS) < CapturedClassInfo.cbClsExtra || - CapturedClassInfo.cbWndExtra < 0 || - CapturedClassInfo.hInstance == NULL) + ProbeForRead(pClassMenuName, + sizeof(CLSMENUNAME), + 1); + + CapturedMenuName = ProbeForReadUnicodeString(pClassMenuName->pusMenuName); + + if ( CapturedName.Length & 1 || + CapturedMenuName.Length & 1 || + CapturedClassInfo.cbClsExtra < 0 || + CapturedClassInfo.cbClsExtra + + CapturedName.Length + + CapturedMenuName.Length + + sizeof(WINDOWCLASS) < CapturedClassInfo.cbClsExtra || + CapturedClassInfo.cbWndExtra < 0 || + CapturedClassInfo.hInstance == NULL) { goto InvalidParameter; } @@ -2021,12 +2026,10 @@ InvalidParameter: SetLastWin32Error(ERROR_INVALID_PARAMETER); _SEH2_LEAVE; } - /* Register the class */ Ret = UserRegisterClass(&CapturedClassInfo, &CapturedName, &CapturedMenuName, - hMenu, /* FIXME - pass pointer */ wpExtra, Flags); @@ -2042,113 +2045,6 @@ InvalidParameter: return Ret; } - -RTL_ATOM -APIENTRY -NtUserRegisterClassExWOW( - WNDCLASSEXW* lpwcx, - PUNICODE_STRING ClassName, - PUNICODE_STRING ClsNVersion, - PCLSMENUNAME pClassMenuName, - DWORD fnID, - DWORD Flags, - LPDWORD pWow) -{ - WNDCLASSEXW CapturedClassInfo = {0}; - UNICODE_STRING CapturedName = {0}, ClassnametoVersion = {0}; - RTL_ATOM Ret = (RTL_ATOM)0; - - UserEnterExclusive(); - - _SEH2_TRY - { - /* Probe the parameters and basic parameter checks */ - if (ProbeForReadUint(&lpwcx->cbSize) != sizeof(WNDCLASSEXW)) - { - goto InvalidParameter; - } - if (!pClassMenuName) - { - goto InvalidParameter; - } - - ProbeForRead(lpwcx, - sizeof(WNDCLASSEXW), - sizeof(ULONG)); - RtlCopyMemory(&CapturedClassInfo, - lpwcx, - sizeof(WNDCLASSEXW)); - /* - Need to watch this. When UnregisterClass is called these pointers - are freed by the caller in user space. So, we just probe the data - for now and pass it on and copy it to the shared class structure. - */ - ProbeForRead(pClassMenuName, - sizeof(CLSMENUNAME), - sizeof(ULONG)); - - CapturedName = ProbeForReadUnicodeString(ClassName); - ClassnametoVersion = ProbeForReadUnicodeString(ClsNVersion); - - if (CapturedName.Length & 1 || ClassnametoVersion.Length & 1 || - CapturedClassInfo.cbClsExtra < 0 || - CapturedClassInfo.cbClsExtra + CapturedName.Length + - ClassnametoVersion.Length + sizeof(WINDOWCLASS) < CapturedClassInfo.cbClsExtra || - CapturedClassInfo.cbWndExtra < 0 || - CapturedClassInfo.hInstance == NULL) - { - goto InvalidParameter; - } - - if (CapturedName.Length != 0) - { - ProbeForRead(CapturedName.Buffer, - CapturedName.Length, - sizeof(WCHAR)); - } - else - { - if (!IS_ATOM(CapturedName.Buffer)) - { - goto InvalidParameter; - } - } - - if (ClassnametoVersion.Length != 0) - { - ProbeForRead(ClassnametoVersion.Buffer, - ClassnametoVersion.Length, - sizeof(WCHAR)); - } - else if (ClassnametoVersion.Buffer != NULL && - !IS_INTRESOURCE(ClassnametoVersion.Buffer)) - { -InvalidParameter: - SetLastWin32Error(ERROR_INVALID_PARAMETER); - _SEH2_LEAVE; - } - - /* Register the class */ -// Ret = UserRegisterClass(&CapturedClassInfo, -// &CapturedName, -// &ClassnametoVersion, -// hMenu, /* FIXME - pass pointer */ -// wpExtra, -// Flags); - - } - _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) - { - SetLastNtError(_SEH2_GetExceptionCode()); - } - _SEH2_END; - - UserLeave(); - - return Ret; -} - - ULONG_PTR APIENTRY NtUserGetClassLong(IN HWND hWnd, IN INT Offset, diff --git a/reactos/subsystems/win32/win32k/ntuser/desktop.c b/reactos/subsystems/win32/win32k/ntuser/desktop.c index c4148fdeb49..074b85a9b41 100644 --- a/reactos/subsystems/win32/win32k/ntuser/desktop.c +++ b/reactos/subsystems/win32/win32k/ntuser/desktop.c @@ -1134,7 +1134,7 @@ NtUserCreateDesktop( &ClassName, &MenuName, NULL, - REGISTERCLASS_SYSTEM, + CSF_SYSTEMCLASS, NULL, pi); if (Class != NULL) diff --git a/reactos/subsystems/win32/win32k/ntuser/ntuser.c b/reactos/subsystems/win32/win32k/ntuser/ntuser.c index 6bb01b58e2a..ab9c66d0dce 100644 --- a/reactos/subsystems/win32/win32k/ntuser/ntuser.c +++ b/reactos/subsystems/win32/win32k/ntuser/ntuser.c @@ -37,10 +37,12 @@ InitUserAtoms(VOID) gpsi->atomSysClass[ICLS_ICONTITLE] = 32772; gpsi->atomSysClass[ICLS_TOOLTIPS] = 32774; + /* System Message Atom */ AtomMessage = IntAddGlobalAtom(L"Message", TRUE); gpsi->atomSysClass[ICLS_HWNDMESSAGE] = AtomMessage; - DPRINT("AtomMessage -> %x\n", AtomMessage); + /* System Context Help Id Atom */ + gpsi->atomContextHelpIdProp = IntAddGlobalAtom(L"SysCH", TRUE); return STATUS_SUCCESS; } diff --git a/reactos/subsystems/win32/win32k/ntuser/prop.c b/reactos/subsystems/win32/win32k/ntuser/prop.c index 9098aa5b8d0..311e589c0be 100644 --- a/reactos/subsystems/win32/win32k/ntuser/prop.c +++ b/reactos/subsystems/win32/win32k/ntuser/prop.c @@ -34,9 +34,6 @@ /* STATIC FUNCTIONS **********************************************************/ -/* FUNCTIONS *****************************************************************/ - -static PPROPERTY FASTCALL IntGetProp(PWINDOW_OBJECT Window, ATOM Atom) { @@ -56,6 +53,49 @@ IntGetProp(PWINDOW_OBJECT Window, ATOM Atom) return(NULL); } +BOOL FASTCALL +IntRemoveProp(PWINDOW_OBJECT Window, ATOM Atom) +{ + PPROPERTY Prop; + HANDLE Data; + Prop = IntGetProp(Window, Atom); + + if (Prop == NULL) + { + return FALSE; + } + Data = Prop->Data; + RemoveEntryList(&Prop->PropListEntry); + UserHeapFree(Prop); + Window->Wnd->PropListItems--; + return TRUE; +} + +BOOL FASTCALL +IntSetProp(PWINDOW_OBJECT pWnd, ATOM Atom, HANDLE Data) +{ + PPROPERTY Prop; + + Prop = IntGetProp(pWnd, Atom); + + if (Prop == NULL) + { + Prop = UserHeapAlloc(sizeof(PROPERTY)); + if (Prop == NULL) + { + return FALSE; + } + Prop->Atom = Atom; + InsertTailList(&pWnd->Wnd->PropListHead, &Prop->PropListEntry); + pWnd->Wnd->PropListItems++; + } + + Prop->Data = Data; + return TRUE; +} + +/* FUNCTIONS *****************************************************************/ + NTSTATUS APIENTRY NtUserBuildPropList(HWND hWnd, LPVOID Buffer, @@ -164,32 +204,6 @@ CLEANUP: END_CLEANUP; } - -static -BOOL FASTCALL -IntSetProp(PWINDOW_OBJECT pWnd, ATOM Atom, HANDLE Data) -{ - PPROPERTY Prop; - - Prop = IntGetProp(pWnd, Atom); - - if (Prop == NULL) - { - Prop = UserHeapAlloc(sizeof(PROPERTY)); - if (Prop == NULL) - { - return FALSE; - } - Prop->Atom = Atom; - InsertTailList(&pWnd->Wnd->PropListHead, &Prop->PropListEntry); - pWnd->Wnd->PropListItems++; - } - - Prop->Data = Data; - return TRUE; -} - - BOOL APIENTRY NtUserSetProp(HWND hWnd, ATOM Atom, HANDLE Data) { diff --git a/reactos/subsystems/win32/win32k/ntuser/simplecall.c b/reactos/subsystems/win32/win32k/ntuser/simplecall.c index cf90e7e29b0..2dd323b0d31 100644 --- a/reactos/subsystems/win32/win32k/ntuser/simplecall.c +++ b/reactos/subsystems/win32/win32k/ntuser/simplecall.c @@ -210,22 +210,6 @@ NtUserCallOneParam( case ONEPARAM_ROUTINE_WINDOWFROMDC: RETURN( (DWORD)IntWindowFromDC((HDC)Param)); - case ONEPARAM_ROUTINE_GETWNDCONTEXTHLPID: - { - PWINDOW_OBJECT Window; - DWORD Result; - - Window = UserGetWindowObject((HWND)Param); - if(!Window) - { - RETURN( FALSE); - } - - Result = Window->Wnd->ContextHelpId; - - RETURN( Result); - } - case ONEPARAM_ROUTINE_SWAPMOUSEBUTTON: { DWORD Result; @@ -556,7 +540,10 @@ NtUserCallTwoParam( RETURN( (DWORD)FALSE); } - Window->Wnd->ContextHelpId = Param2; + if ( Param2 ) + IntSetProp(Window, gpsi->atomContextHelpIdProp, (HANDLE)Param2); + else + IntRemoveProp(Window, gpsi->atomContextHelpIdProp); RETURN( (DWORD)TRUE); @@ -786,6 +773,27 @@ NtUserCallHwnd( { switch (Routine) { + case HWND_ROUTINE_GETWNDCONTEXTHLPID: + { + PWINDOW_OBJECT Window; + PPROPERTY HelpId; + USER_REFERENCE_ENTRY Ref; + + UserEnterExclusive(); + + if (!(Window = UserGetWindowObject(hWnd)) || !Window->Wnd) + { + UserLeave(); + return 0; + } + UserRefObjectCo(Window, &Ref); + + HelpId = IntGetProp(Window, gpsi->atomContextHelpIdProp); + + UserDerefObjectCo(Window); + UserLeave(); + return (DWORD)HelpId; + } case HWND_ROUTINE_REGISTERSHELLHOOKWINDOW: if (IntIsWindow(hWnd)) return IntRegisterShellHookWindow(hWnd); diff --git a/reactos/subsystems/win32/win32k/ntuser/window.c b/reactos/subsystems/win32/win32k/ntuser/window.c index d5f2f2992cc..1425a8e71e8 100644 --- a/reactos/subsystems/win32/win32k/ntuser/window.c +++ b/reactos/subsystems/win32/win32k/ntuser/window.c @@ -1706,7 +1706,6 @@ AllocErr: Class = NULL; Window->SystemMenu = (HMENU)0; - Wnd->ContextHelpId = 0; Wnd->IDMenu = 0; Wnd->hModule = hInstance; Window->hSelf = hWnd; @@ -1835,14 +1834,19 @@ AllocErr: { if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged); - else + else // Take it from the parent. { - hMenu = Wnd->pcls->hMenu; + UNICODE_STRING MenuName; + + RtlInitUnicodeString( &MenuName, Wnd->pcls->MenuName); + + hMenu = co_IntCallLoadMenu( Wnd->pcls->hModule, &MenuName); if (hMenu) IntSetMenu(Window, hMenu, &MenuChanged); + if (MenuName.Buffer) RtlFreeUnicodeString(&MenuName); } } - else - Wnd->IDMenu = (UINT) hMenu; + else // Not a child + Wnd->IDMenu = (UINT) hMenu; /* Insert the window into the thread's window list. */ InsertTailList (&pti->WindowListHead, &Window->ThreadListEntry); diff --git a/reactos/subsystems/win32/win32k/w32ksvc.db b/reactos/subsystems/win32/win32k/w32ksvc.db index 7ffc925bb03..719d70ad4a4 100644 --- a/reactos/subsystems/win32/win32k/w32ksvc.db +++ b/reactos/subsystems/win32/win32k/w32ksvc.db @@ -696,7 +696,6 @@ NtUserMenuInfo 3 NtUserMenuItemInfo 5 NtUserMonitorFromPoint 3 NtUserMonitorFromRect 2 -NtUserRegisterClassEx 6 NtUserMonitorFromWindow 2 NtUserSendMessage 5 NtUserSendMessageTimeout 8