/*
* PROJECT: ReactOS user32.dll
* COPYRIGHT: GPL - See COPYING in the top level directory
- * FILE: dll/win32/user32/windows/class.c
+ * FILE: win32ss/user/user32/windows/class.c
* PURPOSE: Window classes
* PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
#include <wine/debug.h>
WINE_DEFAULT_DEBUG_CHANNEL(user32);
+#define USE_VERSIONED_CLASSES
+
/* From rtl/actctx.c and must match! */
-struct entity
+struct strsection_header
{
- DWORD kind; // Activation context type
- WCHAR *name; // Class name
- WCHAR *clsid; // Not supported yet but needed for menu name.
+ DWORD magic;
+ ULONG size;
+ DWORD unk1[3];
+ ULONG count;
+ ULONG index_offset;
+ DWORD unk2[2];
+ ULONG global_offset;
+ ULONG global_len;
};
-struct dll_redirect
+struct wndclass_redirect_data
{
- WCHAR *name; // Dll name
- WCHAR *hash;
- DWORD Data; // Junk
+ ULONG size;
+ DWORD res;
+ ULONG name_len;
+ ULONG name_offset; /* versioned name offset */
+ ULONG module_len;
+ ULONG module_offset;/* container name offset */
};
-LPCWSTR
-FASTCALL
-ClassNameToVersion(
- LPCTSTR lpszClass,
- LPCWSTR lpszMenuName,
- LPCWSTR *plpLibFileName,
- HANDLE *pContext,
- BOOL bAnsi)
-{
- NTSTATUS Status;
- UNICODE_STRING SectionName;
- WCHAR SeactionNameBuf[MAX_PATH] = {0};
- ACTCTX_SECTION_KEYED_DATA KeyedData = { sizeof(KeyedData) };
-
- if (IS_ATOM(lpszClass))
- {
- SectionName.Buffer = (LPWSTR)&SeactionNameBuf;
- SectionName.MaximumLength = sizeof(SeactionNameBuf);
- if(!NtUserGetAtomName(LOWORD((DWORD_PTR)lpszClass), &SectionName))
- {
- return NULL;
- }
- }
- else
- {
- if (bAnsi)
- {
- RtlCreateUnicodeStringFromAsciiz(&SectionName, (LPSTR)lpszClass);
- }
- else
- {
- RtlInitUnicodeString(&SectionName, lpszClass);
- }
- }
- Status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
- NULL,
- ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
- &SectionName,
- &KeyedData );
-
- if (NT_SUCCESS(Status) && KeyedData.ulDataFormatVersion == 1)
- {
- struct dll_redirect *dll = KeyedData.lpSectionBase;
-
- if (plpLibFileName) *plpLibFileName = dll->name;
-
- if (lpszMenuName)
- {
- WCHAR * mnubuf;
- LPWSTR mnuNameW;
- LPSTR mnuNameA;
- int len = 0;
- struct entity *entity = KeyedData.lpData;
-
- FIXME("actctx: Needs to support menu name from redirected class!");
-
- if (entity->clsid)
- {
- mnubuf = entity->clsid;
- if (bAnsi)
- {
- mnuNameA = (LPSTR)lpszMenuName;
- RtlUnicodeToMultiByteN( mnuNameA, 255, (PULONG)&len, mnubuf, strlenW(mnubuf) * sizeof(WCHAR) );
- mnuNameA[len] = 0;
- }
- else
- {
- mnuNameW = (LPWSTR)lpszMenuName;
- len = strlenW(mnubuf) * sizeof(WCHAR);
- RtlCopyMemory((void *)mnuNameW, mnubuf, len);
- mnuNameW[len] = 0;
- }
- }
- }
- if (pContext) *pContext = KeyedData.hActCtx;
- }
-
- if (!IS_ATOM(lpszClass) && bAnsi)
- RtlFreeUnicodeString(&SectionName);
- if (KeyedData.hActCtx)
- RtlReleaseActivationContext(KeyedData.hActCtx);
-
- return lpszClass;
-}
-
-//
-// Ref: http://yvs-it.blogspot.com/2010/04/initcommoncontrolsex.html
-//
-BOOL
-FASTCALL
-Real_VersionRegisterClass(
- PCWSTR pszClass,
- LPCWSTR lpLibFileName,
- HANDLE Contex,
- HMODULE * phLibModule)
-{
- BOOL Ret;
- HMODULE hLibModule;
- PREGISTERCLASSNAMEW pRegisterClassNameW;
- UNICODE_STRING ClassName;
- WCHAR ClassNameBuf[MAX_PATH] = {0};
- RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame = { sizeof(Frame), 1 };
-
- RtlActivateActivationContextUnsafeFast(&Frame, Contex);
-
- Ret = FALSE;
- hLibModule = NULL;
-
- _SEH2_TRY
- {
- hLibModule = LoadLibraryW(lpLibFileName);
- if ( hLibModule )
- {
- if ((pRegisterClassNameW = (void*) GetProcAddress(hLibModule, "RegisterClassNameW")))
- {
- if (IS_ATOM(pszClass))
- {
- ClassName.Buffer = (LPWSTR)&ClassNameBuf;
- ClassName.MaximumLength = sizeof(ClassNameBuf);
- if (!NtUserGetAtomName(LOWORD((DWORD_PTR)pszClass), &ClassName))
- {
- _SEH2_YIELD(goto Error_Exit);
- }
- pszClass = (PCWSTR)&ClassNameBuf;
- }
- Ret = pRegisterClassNameW(pszClass);
- }
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- }
- _SEH2_END
-
-Error_Exit:
- if ( Ret || !hLibModule )
- {
- if ( phLibModule ) *phLibModule = hLibModule;
- }
- else
- {
- DWORD save_error = GetLastError();
- FreeLibrary(hLibModule);
- SetLastError(save_error);
- }
-
- return Ret;
-}
-
//
-// Use wine hack to process extened context classes.
+// Use wine hack to process extended context classes.
//
/***********************************************************************
* is_comctl32_class
*/
-static BOOL is_comctl32_class( const WCHAR *name )
+LPCWSTR is_comctl32_class( const WCHAR *name )
{
static const WCHAR classesW[][20] =
{
while (min <= max)
{
int res, pos = (min + max) / 2;
- if (!(res = strcmpiW( name, classesW[pos] ))) return TRUE;
+ if (!(res = strcmpiW( name, classesW[pos] ))) return classesW[pos];
if (res < 0) max = pos - 1;
else min = pos + 1;
}
- return FALSE;
+ return NULL;
}
+LPCWSTR
+FASTCALL
+ClassNameToVersion(
+ const void* lpszClass,
+ LPCWSTR lpszMenuName,
+ LPCWSTR *plpLibFileName,
+ HANDLE *pContext,
+ BOOL bAnsi)
+{
+ LPCWSTR VersionedClass = NULL;
+ NTSTATUS Status;
+ UNICODE_STRING SectionName;
+ WCHAR SectionNameBuf[MAX_PATH] = {0};
+ ACTCTX_SECTION_KEYED_DATA KeyedData = { sizeof(KeyedData) };
+
+ if(!lpszClass)
+ {
+ ERR("Null class given !\n");
+ return NULL;
+ }
+
+ if (IS_ATOM(lpszClass))
+ {
+ RtlInitEmptyUnicodeString(&SectionName, SectionNameBuf, sizeof(SectionNameBuf));
+ if(!NtUserGetAtomName(LOWORD((DWORD_PTR)lpszClass), &SectionName))
+ {
+ ERR("Couldn't get atom name for atom %x !\n", LOWORD((DWORD_PTR)lpszClass));
+ return NULL;
+ }
+ SectionName.Length = wcslen(SectionNameBuf) * sizeof(WCHAR);
+ TRACE("ClassNameToVersion got name %wZ from atom\n", &SectionName);
+ }
+ else
+ {
+ if (bAnsi)
+ {
+ ANSI_STRING AnsiString;
+ RtlInitAnsiString(&AnsiString, lpszClass);
+ RtlInitEmptyUnicodeString(&SectionName, SectionNameBuf, sizeof(SectionNameBuf));
+ RtlAnsiStringToUnicodeString(&SectionName, &AnsiString, FALSE);
+ }
+ else
+ {
+ RtlInitUnicodeString(&SectionName, lpszClass);
+ }
+ }
+ Status = RtlFindActivationContextSectionString( FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX,
+ NULL,
+ ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION,
+ &SectionName,
+ &KeyedData );
+
+#ifdef USE_VERSIONED_CLASSES
+ if (NT_SUCCESS(Status) && KeyedData.ulDataFormatVersion == 1)
+ {
+ struct strsection_header *SectionHeader = KeyedData.lpSectionBase;
+
+ /* Find activation context */
+ if(SectionHeader && SectionHeader->count > 0)
+ {
+ struct wndclass_redirect_data *WindowRedirectionData = KeyedData.lpData;
+ if(WindowRedirectionData && WindowRedirectionData->module_len)
+ {
+ LPCWSTR lpLibFileName;
+
+ VersionedClass = (WCHAR*)((BYTE*)WindowRedirectionData + WindowRedirectionData->name_offset);
+ lpLibFileName = (WCHAR*)((BYTE*)KeyedData.lpSectionBase + WindowRedirectionData->module_offset);
+ TRACE("Returning VersionedClass=%S, plpLibFileName=%S for class %S\n", VersionedClass, lpLibFileName, SectionName.Buffer);
+
+ if (pContext) *pContext = KeyedData.hActCtx;
+ if (plpLibFileName) *plpLibFileName = lpLibFileName;
+
+ }
+ }
+ }
+
+ if (KeyedData.hActCtx)
+ RtlReleaseActivationContext(KeyedData.hActCtx);
+#endif
+
+#ifndef DEFAULT_ACTIVATION_CONTEXTS_SUPPORTED
+ /* This block is a hack! */
+ if (!VersionedClass)
+ {
+ /*
+ * In windows the default activation context always contains comctl32v5
+ * In reactos we don't have a default activation context so we
+ * mimic wine here.
+ */
+ VersionedClass = is_comctl32_class(SectionName.Buffer);
+ if (VersionedClass)
+ {
+ if (pContext) *pContext = 0;
+ if (plpLibFileName) *plpLibFileName = L"comctl32";
+ }
+ }
+#endif
+
+ /*
+ * The returned strings are pointers in the activation context and
+ * will get freed when the activation context gets freed
+ */
+ return VersionedClass;
+}
+
+//
+// Ref: http://yvs-it.blogspot.com/2010/04/initcommoncontrolsex.html
+//
BOOL
FASTCALL
VersionRegisterClass(
HANDLE Contex,
HMODULE * phLibModule)
{
- // Should be lpLibFileName.....
- static const WCHAR comctl32W[] = {'c','o','m','c','t','l','3','2','.','d','l','l',0};
- //
- PREGISTERCLASSNAMEW pRegisterClassNameW;
- UNICODE_STRING ClassName;
- WCHAR ClassNameBuf[MAX_PATH] = {0};
- BOOL Ret = FALSE;
- HMODULE hLibModule = NULL;
-
- if (!IS_ATOM(pszClass) && is_comctl32_class( pszClass ))
- {
- _SEH2_TRY
- {
- hLibModule = LoadLibraryW(comctl32W);
- if ( hLibModule )
- {
- if ((pRegisterClassNameW = (void*) GetProcAddress(hLibModule, "RegisterClassNameW")))
- {
- if (IS_ATOM(pszClass))
+ BOOL Ret = FALSE;
+ HMODULE hLibModule = NULL;
+ PREGISTERCLASSNAMEW pRegisterClassNameW;
+ UNICODE_STRING ClassName;
+ WCHAR ClassNameBuf[MAX_PATH] = {0};
+ RTL_CALLER_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME_EXTENDED Frame = { sizeof(Frame), 1 };
+
+ RtlActivateActivationContextUnsafeFast(&Frame, Contex);
+
+ _SEH2_TRY
+ {
+ hLibModule = LoadLibraryW(lpLibFileName);
+ if ( hLibModule )
+ {
+ if ((pRegisterClassNameW = (void*) GetProcAddress(hLibModule, "RegisterClassNameW")))
+ {
+ if (IS_ATOM(pszClass))
+ {
+ ClassName.Buffer = ClassNameBuf;
+ ClassName.MaximumLength = sizeof(ClassNameBuf);
+ if (!NtUserGetAtomName(LOWORD((DWORD_PTR)pszClass), &ClassName))
+ {
+ ERR("Error while verifying ATOM\n");
+ _SEH2_YIELD(goto Error_Exit);
+ }
+ pszClass = ClassName.Buffer;
+ }
+ Ret = pRegisterClassNameW(pszClass);
+ }
+ else
{
- ClassName.Buffer = (LPWSTR)&ClassNameBuf;
- ClassName.MaximumLength = sizeof(ClassNameBuf);
- if (!NtUserGetAtomName(LOWORD((DWORD_PTR)pszClass), &ClassName))
- {
- ERR("Error while verifying ATOM\n");
- _SEH2_YIELD(goto Error_Exit);
- }
- pszClass = (PCWSTR)&ClassNameBuf;
+ WARN("No RegisterClassNameW PROC\n");
}
- Ret = pRegisterClassNameW(pszClass);
- }
- }
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- }
- _SEH2_END
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ }
+ _SEH2_END
Error_Exit:
- if ( Ret || !hLibModule )
- {
- if ( phLibModule ) *phLibModule = hLibModule;
- }
- else
- {
- DWORD save_error = GetLastError();
- FreeLibrary(hLibModule);
- SetLastError(save_error);
- }
- TRACE( "%s retrying after loading comctl32\n", debugstr_w(pszClass) );
- return Ret;
- }
- TRACE("NO ComCtl32 Class %S!\n",pszClass);
- return FALSE;
+ if ( Ret || !hLibModule )
+ {
+ if ( phLibModule ) *phLibModule = hLibModule;
+ }
+ else
+ {
+ DWORD save_error = GetLastError();
+ FreeLibrary(hLibModule);
+ SetLastError(save_error);
+ }
+
+ RtlDeactivateActivationContextUnsafeFast(&Frame);
+ return Ret;
}
-//
-//
-//
/*
* @implemented
LPCSTR pszMenuName;
HMODULE hLibModule = NULL;
DWORD save_error;
- BOOL Ret, ClassFound = FALSE;
+ BOOL Ret, ClassFound = FALSE, ConvertedString = FALSE;
+ LPCWSTR lpszClsVersion;
+ HANDLE pCtx = NULL;
+ LPCWSTR lpLibFileName = NULL;
TRACE("%p class/atom: %s/%04x %p\n", hInstance,
IS_ATOM(lpszClass) ? NULL : lpszClass,
if (!lpwcx)
{
- SetLastError( ERROR_NOACCESS );
- return FALSE;
+ SetLastError( ERROR_NOACCESS );
+ return FALSE;
}
if (hInstance == User32Instance)
return FALSE;
}
- if (IS_ATOM(lpszClass))
+ lpszClsVersion = ClassNameToVersion(lpszClass, NULL, &lpLibFileName, &pCtx, TRUE);
+ if (lpszClsVersion)
+ {
+ RtlInitUnicodeString(&ClassName, lpszClsVersion);
+ }
+ else if (IS_ATOM(lpszClass))
{
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
}
else
{
- if (!RtlCreateUnicodeStringFromAsciiz(&ClassName,
- lpszClass))
+ ConvertedString = TRUE;
+ if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, lpszClass))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return FALSE;
for(;;)
{
- Ret = NtUserGetClassInfo( hInstance,
- &ClassName,
- (LPWNDCLASSEXW)lpwcx,
- (LPWSTR *)&pszMenuName,
+ Ret = NtUserGetClassInfo( hInstance,
+ &ClassName,
+ (LPWNDCLASSEXW)lpwcx,
+ (LPWSTR *)&pszMenuName,
TRUE);
- if (Ret) break;
- if (!ClassFound)
- {
- save_error = GetLastError();
- if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
- save_error == ERROR_CLASS_DOES_NOT_EXIST )
- {
- ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
- if (ClassFound) continue;
- }
- }
- if (hLibModule)
- {
- save_error = GetLastError();
- FreeLibrary(hLibModule);
- SetLastError(save_error);
- hLibModule = 0;
- }
- break;
+ if (Ret) break;
+ if (!lpLibFileName) break;
+ if (!ClassFound)
+ {
+ save_error = GetLastError();
+ if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
+ save_error == ERROR_CLASS_DOES_NOT_EXIST )
+ {
+ ClassFound = VersionRegisterClass(ClassName.Buffer, lpLibFileName, pCtx, &hLibModule);
+ if (ClassFound) continue;
+ }
+ }
+ if (hLibModule)
+ {
+ save_error = GetLastError();
+ FreeLibrary(hLibModule);
+ SetLastError(save_error);
+ hLibModule = 0;
+ }
+ break;
}
if (Ret)
{
- lpwcx->lpszClassName = lpszClass;
+ lpwcx->lpszClassName = lpszClass;
// lpwcx->lpszMenuName = pszMenuName;
}
- if (!IS_ATOM(lpszClass))
+ if (ConvertedString)
{
RtlFreeUnicodeString(&ClassName);
}
HMODULE hLibModule = NULL;
DWORD save_error;
BOOL Ret, ClassFound = FALSE;
+ LPCWSTR lpszClsVersion;
+ HANDLE pCtx = NULL;
+ LPCWSTR lpLibFileName = NULL;
TRACE("%p class/atom: %S/%04x %p\n", hInstance,
IS_ATOM(lpszClass) ? NULL : lpszClass,
return FALSE;
}
- if (IS_ATOM(lpszClass))
+ lpszClsVersion = ClassNameToVersion(lpszClass, NULL, &lpLibFileName, &pCtx, FALSE);
+ if (lpszClsVersion)
+ {
+ RtlInitUnicodeString(&ClassName, lpszClsVersion);
+ }
+ else if (IS_ATOM(lpszClass))
{
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpszClass);
}
else
{
- RtlInitUnicodeString(&ClassName,
- lpszClass);
+ RtlInitUnicodeString(&ClassName, lpszClass);
}
if (!RegisterDefaultClasses)
for(;;)
{
- Ret = NtUserGetClassInfo( hInstance,
- &ClassName,
- lpwcx,
- &pszMenuName,
- FALSE);
- if (Ret) break;
- if (!ClassFound)
- {
- save_error = GetLastError();
- if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
- save_error == ERROR_CLASS_DOES_NOT_EXIST )
- {
- ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
- if (ClassFound) continue;
- }
- }
- if (hLibModule)
- {
- save_error = GetLastError();
- FreeLibrary(hLibModule);
- SetLastError(save_error);
- hLibModule = 0;
- }
- break;
+ Ret = NtUserGetClassInfo( hInstance,
+ &ClassName,
+ lpwcx,
+ &pszMenuName,
+ FALSE);
+ if (Ret) break;
+ if (!lpLibFileName) break;
+ if (!ClassFound)
+ {
+ save_error = GetLastError();
+ if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
+ save_error == ERROR_CLASS_DOES_NOT_EXIST )
+ {
+ ClassFound = VersionRegisterClass(ClassName.Buffer, lpLibFileName, pCtx, &hLibModule);
+ if (ClassFound) continue;
+ }
+ }
+ if (hLibModule)
+ {
+ save_error = GetLastError();
+ FreeLibrary(hLibModule);
+ SetLastError(save_error);
+ hLibModule = 0;
+ }
+ break;
}
if (Ret)
{
- lpwcx->lpszClassName = lpszClass;
+ lpwcx->lpszClassName = lpszClass;
// lpwcx->lpszMenuName = pszMenuName;
}
return Ret;
ULONG_PTR FASTCALL
IntGetClsWndProc(PWND pWnd, PCLS Class, BOOL Ansi)
{
- INT i;
- ULONG_PTR gcpd, Ret = 0;
+ INT i;
+ ULONG_PTR gcpd, Ret = 0;
// If server side, sweep through proc list and return the client side proc.
- if (Class->CSF_flags & CSF_SERVERSIDEPROC)
- { // Always scan through the list due to wine class "deftest".
- for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
- {
- if (GETPFNSERVER(i) == Class->lpfnWndProc)
- {
- if (Ansi)
- Ret = (ULONG_PTR)GETPFNCLIENTA(i);
- else
- Ret = (ULONG_PTR)GETPFNCLIENTW(i);
- }
- }
- return Ret;
- }
- // Set return proc.
- Ret = (ULONG_PTR)Class->lpfnWndProc;
- // Return the proc if one of the FnId default class type.
- if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
- {
- if (Ansi)
- { // If match return the right proc by type.
- if (GETPFNCLIENTW(Class->fnid) == Class->lpfnWndProc)
- Ret = (ULONG_PTR)GETPFNCLIENTA(Class->fnid);
- }
- else
- {
- if (GETPFNCLIENTA(Class->fnid) == Class->lpfnWndProc)
- Ret = (ULONG_PTR)GETPFNCLIENTW(Class->fnid);
- }
- }
- // Return on change or Ansi/Unicode proc equal.
- if ( Ret != (ULONG_PTR)Class->lpfnWndProc ||
- Ansi == !!(Class->CSF_flags & CSF_ANSIPROC) )
- return Ret;
-
- /* We have an Ansi and Unicode swap! If Ansi create Unicode proc handle.
- This will force CallWindowProc to deal with it. */
- gcpd = NtUserGetCPD( UserHMGetHandle(pWnd),
- (Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWndtoCls,
- Ret);
-
- return (gcpd ? gcpd : Ret);
+ if (Class->CSF_flags & CSF_SERVERSIDEPROC)
+ { // Always scan through the list due to wine class "deftest".
+ for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
+ {
+ if (GETPFNSERVER(i) == Class->lpfnWndProc)
+ {
+ if (Ansi)
+ Ret = (ULONG_PTR)GETPFNCLIENTA(i);
+ else
+ Ret = (ULONG_PTR)GETPFNCLIENTW(i);
+ }
+ }
+ return Ret;
+ }
+ // Set return proc.
+ Ret = (ULONG_PTR)Class->lpfnWndProc;
+ // Return the proc if one of the FnId default class type.
+ if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
+ {
+ if (Ansi)
+ { // If match return the right proc by type.
+ if (GETPFNCLIENTW(Class->fnid) == Class->lpfnWndProc)
+ Ret = (ULONG_PTR)GETPFNCLIENTA(Class->fnid);
+ }
+ else
+ {
+ if (GETPFNCLIENTA(Class->fnid) == Class->lpfnWndProc)
+ Ret = (ULONG_PTR)GETPFNCLIENTW(Class->fnid);
+ }
+ }
+ // Return on change or Ansi/Unicode proc equal.
+ if ( Ret != (ULONG_PTR)Class->lpfnWndProc ||
+ Ansi == !!(Class->CSF_flags & CSF_ANSIPROC) )
+ return Ret;
+
+ /* We have an Ansi and Unicode swap! If Ansi create Unicode proc handle.
+ This will force CallWindowProc to deal with it. */
+ gcpd = NtUserGetCPD( UserHMGetHandle(pWnd),
+ (Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWndtoCls,
+ Ret);
+
+ return (gcpd ? gcpd : Ret);
}
//
WNDPROC FASTCALL
IntGetWndProc(PWND pWnd, BOOL Ansi)
{
- INT i;
- WNDPROC gcpd, Ret = 0;
- PCLS Class = DesktopPtrToUser(pWnd->pcls);
-
- if (!Class) return Ret;
-
- if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
- {
- for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
- {
- if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
- {
- if (Ansi)
- Ret = GETPFNCLIENTA(i);
- else
- Ret = GETPFNCLIENTW(i);
- }
- }
- return Ret;
- }
- // Wine Class tests:
- /* Edit controls are special - they return a wndproc handle when
- GetWindowLongPtr is called with a different A/W.
- On the other hand there is no W->A->W conversion so this control
- is treated specially.
- */
- if (Class->fnid == FNID_EDIT)
- Ret = pWnd->lpfnWndProc;
- else
- {
- // Set return proc.
- Ret = pWnd->lpfnWndProc;
-
- if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
- {
- if (Ansi)
+ INT i;
+ WNDPROC gcpd, Ret = 0;
+ PCLS Class = DesktopPtrToUser(pWnd->pcls);
+
+ if (!Class) return Ret;
+
+ if (pWnd->state & WNDS_SERVERSIDEWINDOWPROC)
+ {
+ for ( i = FNID_FIRST; i <= FNID_SWITCH; i++)
{
- if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
- Ret = GETPFNCLIENTA(Class->fnid);
+ if (GETPFNSERVER(i) == pWnd->lpfnWndProc)
+ {
+ if (Ansi)
+ Ret = GETPFNCLIENTA(i);
+ else
+ Ret = GETPFNCLIENTW(i);
+ }
}
- else
+ return Ret;
+ }
+ // Wine Class tests:
+ /* Edit controls are special - they return a wndproc handle when
+ GetWindowLongPtr is called with a different A/W.
+ On the other hand there is no W->A->W conversion so this control
+ is treated specially.
+ */
+ if (Class->fnid == FNID_EDIT)
+ Ret = pWnd->lpfnWndProc;
+ else
+ {
+ // Set return proc.
+ Ret = pWnd->lpfnWndProc;
+
+ if (Class->fnid <= FNID_GHOST && Class->fnid >= FNID_BUTTON)
{
- if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
- Ret = GETPFNCLIENTW(Class->fnid);
+ if (Ansi)
+ {
+ if (GETPFNCLIENTW(Class->fnid) == pWnd->lpfnWndProc)
+ Ret = GETPFNCLIENTA(Class->fnid);
+ }
+ else
+ {
+ if (GETPFNCLIENTA(Class->fnid) == pWnd->lpfnWndProc)
+ Ret = GETPFNCLIENTW(Class->fnid);
+ }
}
- }
- // Return on the change.
- if ( Ret != pWnd->lpfnWndProc)
- return Ret;
- }
+ // Return on the change.
+ if ( Ret != pWnd->lpfnWndProc)
+ return Ret;
+ }
- if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
- return Ret;
+ if ( Ansi == !!(pWnd->state & WNDS_ANSIWINDOWPROC) )
+ return Ret;
- gcpd = (WNDPROC)NtUserGetCPD( UserHMGetHandle(pWnd),
- (Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
- (ULONG_PTR)Ret);
+ gcpd = (WNDPROC)NtUserGetCPD( UserHMGetHandle(pWnd),
+ (Ansi ? UserGetCPDA2U : UserGetCPDU2A )|UserGetCPDWindow,
+ (ULONG_PTR)Ret);
- return (gcpd ? gcpd : Ret);
+ return (gcpd ? gcpd : Ret);
}
static ULONG_PTR FASTCALL
IntGetClassLongA(PWND Wnd, PCLS Class, int nIndex)
{
- ULONG_PTR Ret = 0;
+ ULONG_PTR Ret = 0;
if (nIndex >= 0)
{
break;
case GCW_ATOM:
- Ret = (ULONG_PTR)Class->atomClassName;
+ Ret = (ULONG_PTR)Class->atomNVClassName;
break;
case GCLP_HCURSOR:
- /* FIXME - get handle from pointer to CURSOR object */
- Ret = (ULONG_PTR)Class->hCursor;
+ Ret = Class->spcur ? (ULONG_PTR)((PPROCMARKHEAD)SharedPtrToUser(Class->spcur))->h : 0;
break;
case GCLP_HICON:
- /* FIXME - get handle from pointer to ICON object */
- Ret = (ULONG_PTR)Class->hIcon;
+ Ret = Class->spicn ? (ULONG_PTR)((PPROCMARKHEAD)SharedPtrToUser(Class->spicn))->h : 0;
break;
case GCLP_HICONSM:
- /* FIXME - get handle from pointer to ICON object */
- Ret = (ULONG_PTR)(Class->hIconSm ? Class->hIconSm : Class->hIconSmIntern);
+ Ret = Class->spicnSm ? (ULONG_PTR)((PPROCMARKHEAD)SharedPtrToUser(Class->spicnSm))->h : 0;
break;
case GCLP_WNDPROC:
}
}
- return Ret;
+ return Ret;
}
static ULONG_PTR FASTCALL
IntGetClassLongW (PWND Wnd, PCLS Class, int nIndex)
{
- ULONG_PTR Ret = 0;
+ ULONG_PTR Ret = 0;
if (nIndex >= 0)
{
break;
case GCW_ATOM:
- Ret = (ULONG_PTR)Class->atomClassName;
+ Ret = (ULONG_PTR)Class->atomNVClassName;
break;
case GCLP_HCURSOR:
- /* FIXME - get handle from pointer to CURSOR object */
- Ret = (ULONG_PTR)Class->hCursor;
+ Ret = Class->spcur ? (ULONG_PTR)((PPROCMARKHEAD)SharedPtrToUser(Class->spcur))->h : 0;
break;
case GCLP_HICON:
- /* FIXME - get handle from pointer to ICON object */
- Ret = (ULONG_PTR)Class->hIcon;
+ Ret = Class->spicn ? (ULONG_PTR)((PPROCMARKHEAD)SharedPtrToUser(Class->spicn))->h : 0;
break;
case GCLP_HICONSM:
- /* FIXME - get handle from pointer to ICON object */
- Ret = (ULONG_PTR)(Class->hIconSm ? Class->hIconSm : Class->hIconSmIntern);
+ Ret = Class->spicnSm ? (ULONG_PTR)((PPROCMARKHEAD)SharedPtrToUser(Class->spicnSm))->h : 0;
break;
case GCLP_WNDPROC:
}
}
- return Ret;
+ return Ret;
}
/*
if (Class != NULL)
{
#ifdef _WIN64
- switch (nIndex)
- {
- case GCLP_HBRBACKGROUND:
- case GCLP_HCURSOR:
- case GCLP_HICON:
- case GCLP_HICONSM:
- case GCLP_HMODULE:
- case GCLP_MENUNAME:
- case GCLP_WNDPROC:
- SetLastError(ERROR_INVALID_INDEX);
- break;
-
- default:
- Ret = IntGetClassLongA(Wnd, Class, nIndex);
- break;
- }
+ switch (nIndex)
+ {
+ case GCLP_HBRBACKGROUND:
+ case GCLP_HCURSOR:
+ case GCLP_HICON:
+ case GCLP_HICONSM:
+ case GCLP_HMODULE:
+ case GCLP_MENUNAME:
+ case GCLP_WNDPROC:
+ SetLastError(ERROR_INVALID_INDEX);
+ break;
+
+ default:
+ Ret = IntGetClassLongA(Wnd, Class, nIndex);
+ break;
+ }
#else
- Ret = IntGetClassLongA(Wnd, Class, nIndex);
+ Ret = IntGetClassLongA(Wnd, Class, nIndex);
#endif
}
else
if (Class != NULL)
{
#ifdef _WIN64
- switch (nIndex)
- {
- case GCLP_HBRBACKGROUND:
- case GCLP_HCURSOR:
- case GCLP_HICON:
- case GCLP_HICONSM:
- case GCLP_HMODULE:
- case GCLP_MENUNAME:
- case GCLP_WNDPROC:
- SetLastError(ERROR_INVALID_INDEX);
- break;
-
- default:
- Ret = IntGetClassLongW(Wnd, Class, nIndex);
- break;
- }
+ switch (nIndex)
+ {
+ case GCLP_HBRBACKGROUND:
+ case GCLP_HCURSOR:
+ case GCLP_HICON:
+ case GCLP_HICONSM:
+ case GCLP_HMODULE:
+ case GCLP_MENUNAME:
+ case GCLP_WNDPROC:
+ SetLastError(ERROR_INVALID_INDEX);
+ break;
+
+ default:
+ Ret = IntGetClassLongW(Wnd, Class, nIndex);
+ break;
+ }
#else
- Ret = IntGetClassLongW(Wnd, Class, nIndex);
+ Ret = IntGetClassLongW(Wnd, Class, nIndex);
#endif
}
else
Class = DesktopPtrToUser(Wnd->pcls);
if (Class != NULL)
{
- Ret = IntGetClassLongA(Wnd, Class, nIndex);
+ Ret = IntGetClassLongA(Wnd, Class, nIndex);
}
else
{
Class = DesktopPtrToUser(Wnd->pcls);
if (Class != NULL)
{
- Ret = IntGetClassLongW(Wnd, Class, nIndex);
+ Ret = IntGetClassLongW(Wnd, Class, nIndex);
}
else
{
{
WCHAR tmpbuf[MAX_ATOM_LEN + 1];
int len;
-
+
if (nMaxCount <= 0) return 0;
if (!GetClassNameW( hWnd, tmpbuf, sizeof(tmpbuf)/sizeof(WCHAR) )) return 0;
RtlUnicodeToMultiByteN( lpClassName, nMaxCount - 1, (PULONG)&len, tmpbuf, strlenW(tmpbuf) * sizeof(WCHAR) );
case GWLP_ID: retvalue = wndPtr->IDMenu; break;
case GWLP_HINSTANCE: retvalue = (ULONG_PTR)wndPtr->hModule; break;
case GWLP_WNDPROC:
- {
- if (!TestWindowProcess(wndPtr))
- {
- SetLastError(ERROR_ACCESS_DENIED);
- retvalue = 0;
- }
- retvalue = (ULONG_PTR)IntGetWndProc(wndPtr, !unicode);
+ {
+ if (!TestWindowProcess(wndPtr))
+ {
+ SetLastError(ERROR_ACCESS_DENIED);
+ retvalue = 0;
+ }
+ retvalue = (ULONG_PTR)IntGetWndProc(wndPtr, !unicode);
break;
- }
+ }
default:
WARN("Unknown offset %d\n", offset );
SetLastError( ERROR_INVALID_INDEX );
{
WCHAR tmpbuf[MAX_ATOM_LEN + 1];
UINT len;
-
+
if ((INT)cchType <= 0) return 0;
if (!RealGetWindowClassW( hwnd, tmpbuf, sizeof(tmpbuf)/sizeof(WCHAR) )) return 0;
RtlUnicodeToMultiByteN( pszType, cchType - 1, (PULONG)&len, tmpbuf, strlenW(tmpbuf) * sizeof(WCHAR) );
static HICON
CreateSmallIcon(HICON StdIcon)
{
- HICON SmallIcon = NULL;
- ICONINFO StdInfo;
- int SmallIconWidth;
- int SmallIconHeight;
- BITMAP StdBitmapInfo;
- HDC hSourceDc = NULL;
- HDC hDestDc = NULL;
- ICONINFO SmallInfo;
- HBITMAP OldSourceBitmap = NULL;
- HBITMAP OldDestBitmap = NULL;
-
- SmallInfo.hbmColor = NULL;
- SmallInfo.hbmMask = NULL;
-
- /* We need something to work with... */
- if (NULL == StdIcon)
- {
- goto cleanup;
- }
-
- SmallIconWidth = GetSystemMetrics(SM_CXSMICON);
- SmallIconHeight = GetSystemMetrics(SM_CYSMICON);
- if (! GetIconInfo(StdIcon, &StdInfo))
- {
- ERR("Failed to get icon info for icon 0x%x\n", StdIcon);
- goto cleanup;
- }
+ HICON SmallIcon = NULL;
+ ICONINFO StdInfo;
+ int SmallIconWidth;
+ int SmallIconHeight;
+ BITMAP StdBitmapInfo;
+ HDC hSourceDc = NULL;
+ HDC hDestDc = NULL;
+ ICONINFO SmallInfo;
+ HBITMAP OldSourceBitmap = NULL;
+ HBITMAP OldDestBitmap = NULL;
+
+ SmallInfo.hbmColor = NULL;
+ SmallInfo.hbmMask = NULL;
+
+ /* We need something to work with... */
+ if (NULL == StdIcon)
+ {
+ goto cleanup;
+ }
+
+ SmallIconWidth = GetSystemMetrics(SM_CXSMICON);
+ SmallIconHeight = GetSystemMetrics(SM_CYSMICON);
+ if (! GetIconInfo(StdIcon, &StdInfo))
+ {
+ ERR("Failed to get icon info for icon 0x%x\n", StdIcon);
+ goto cleanup;
+ }
if (! GetObjectW(StdInfo.hbmMask, sizeof(BITMAP), &StdBitmapInfo))
- {
- ERR("Failed to get bitmap info for icon 0x%x bitmap 0x%x\n",
- StdIcon, StdInfo.hbmColor);
- goto cleanup;
- }
- if (StdBitmapInfo.bmWidth == SmallIconWidth &&
- StdBitmapInfo.bmHeight == SmallIconHeight)
- {
- /* Icon already has the correct dimensions */
- return StdIcon;
- }
-
- hSourceDc = CreateCompatibleDC(NULL);
- if (NULL == hSourceDc)
- {
- ERR("Failed to create source DC\n");
- goto cleanup;
- }
- hDestDc = CreateCompatibleDC(NULL);
- if (NULL == hDestDc)
- {
- ERR("Failed to create dest DC\n");
- goto cleanup;
- }
-
- OldSourceBitmap = SelectObject(hSourceDc, StdInfo.hbmColor);
- if (NULL == OldSourceBitmap)
- {
- ERR("Failed to select source color bitmap\n");
- goto cleanup;
- }
- SmallInfo.hbmColor = CreateCompatibleBitmap(hSourceDc, SmallIconWidth,
- SmallIconHeight);
- if (NULL == SmallInfo.hbmColor)
- {
- ERR("Failed to create color bitmap\n");
- goto cleanup;
- }
- OldDestBitmap = SelectObject(hDestDc, SmallInfo.hbmColor);
- if (NULL == OldDestBitmap)
- {
- ERR("Failed to select dest color bitmap\n");
- goto cleanup;
- }
- if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
- hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
- StdBitmapInfo.bmHeight, SRCCOPY))
- {
- ERR("Failed to stretch color bitmap\n");
- goto cleanup;
- }
-
- if (NULL == SelectObject(hSourceDc, StdInfo.hbmMask))
- {
- ERR("Failed to select source mask bitmap\n");
- goto cleanup;
- }
- SmallInfo.hbmMask = CreateCompatibleBitmap(hSourceDc, SmallIconWidth, SmallIconHeight);
- if (NULL == SmallInfo.hbmMask)
- {
- ERR("Failed to create mask bitmap\n");
- goto cleanup;
- }
- if (NULL == SelectObject(hDestDc, SmallInfo.hbmMask))
- {
- ERR("Failed to select dest mask bitmap\n");
- goto cleanup;
- }
- if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
- hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
- StdBitmapInfo.bmHeight, SRCCOPY))
- {
- ERR("Failed to stretch mask bitmap\n");
- goto cleanup;
- }
-
- SmallInfo.fIcon = TRUE;
- SmallInfo.xHotspot = SmallIconWidth / 2;
- SmallInfo.yHotspot = SmallIconHeight / 2;
- SmallIcon = CreateIconIndirect(&SmallInfo);
- if (NULL == SmallIcon)
- {
- ERR("Failed to create icon\n");
- goto cleanup;
- }
+ {
+ ERR("Failed to get bitmap info for icon 0x%x bitmap 0x%x\n",
+ StdIcon, StdInfo.hbmColor);
+ goto cleanup;
+ }
+ if (StdBitmapInfo.bmWidth == SmallIconWidth &&
+ StdBitmapInfo.bmHeight == SmallIconHeight)
+ {
+ /* Icon already has the correct dimensions */
+ return StdIcon;
+ }
+
+ hSourceDc = CreateCompatibleDC(NULL);
+ if (NULL == hSourceDc)
+ {
+ ERR("Failed to create source DC\n");
+ goto cleanup;
+ }
+ hDestDc = CreateCompatibleDC(NULL);
+ if (NULL == hDestDc)
+ {
+ ERR("Failed to create dest DC\n");
+ goto cleanup;
+ }
+
+ OldSourceBitmap = SelectObject(hSourceDc, StdInfo.hbmColor);
+ if (NULL == OldSourceBitmap)
+ {
+ ERR("Failed to select source color bitmap\n");
+ goto cleanup;
+ }
+ SmallInfo.hbmColor = CreateCompatibleBitmap(hSourceDc, SmallIconWidth,
+ SmallIconHeight);
+ if (NULL == SmallInfo.hbmColor)
+ {
+ ERR("Failed to create color bitmap\n");
+ goto cleanup;
+ }
+ OldDestBitmap = SelectObject(hDestDc, SmallInfo.hbmColor);
+ if (NULL == OldDestBitmap)
+ {
+ ERR("Failed to select dest color bitmap\n");
+ goto cleanup;
+ }
+ if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
+ hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
+ StdBitmapInfo.bmHeight, SRCCOPY))
+ {
+ ERR("Failed to stretch color bitmap\n");
+ goto cleanup;
+ }
+
+ if (NULL == SelectObject(hSourceDc, StdInfo.hbmMask))
+ {
+ ERR("Failed to select source mask bitmap\n");
+ goto cleanup;
+ }
+ SmallInfo.hbmMask = CreateCompatibleBitmap(hSourceDc, SmallIconWidth, SmallIconHeight);
+ if (NULL == SmallInfo.hbmMask)
+ {
+ ERR("Failed to create mask bitmap\n");
+ goto cleanup;
+ }
+ if (NULL == SelectObject(hDestDc, SmallInfo.hbmMask))
+ {
+ ERR("Failed to select dest mask bitmap\n");
+ goto cleanup;
+ }
+ if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
+ hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
+ StdBitmapInfo.bmHeight, SRCCOPY))
+ {
+ ERR("Failed to stretch mask bitmap\n");
+ goto cleanup;
+ }
+
+ SmallInfo.fIcon = TRUE;
+ SmallInfo.xHotspot = SmallIconWidth / 2;
+ SmallInfo.yHotspot = SmallIconHeight / 2;
+ SmallIcon = CreateIconIndirect(&SmallInfo);
+ if (NULL == SmallIcon)
+ {
+ ERR("Failed to create icon\n");
+ goto cleanup;
+ }
cleanup:
- if (NULL != SmallInfo.hbmMask)
- {
- DeleteObject(SmallInfo.hbmMask);
- }
- if (NULL != OldDestBitmap)
- {
- SelectObject(hDestDc, OldDestBitmap);
- }
- if (NULL != SmallInfo.hbmColor)
- {
- DeleteObject(SmallInfo.hbmColor);
- }
- if (NULL != hDestDc)
- {
- DeleteDC(hDestDc);
- }
- if (NULL != OldSourceBitmap)
- {
- SelectObject(hSourceDc, OldSourceBitmap);
- }
- if (NULL != hSourceDc)
- {
- DeleteDC(hSourceDc);
- }
-
- return SmallIcon;
+ if (NULL != SmallInfo.hbmMask)
+ {
+ DeleteObject(SmallInfo.hbmMask);
+ }
+ if (NULL != OldDestBitmap)
+ {
+ SelectObject(hDestDc, OldDestBitmap);
+ }
+ if (NULL != SmallInfo.hbmColor)
+ {
+ DeleteObject(SmallInfo.hbmColor);
+ }
+ if (NULL != hDestDc)
+ {
+ DeleteDC(hDestDc);
+ }
+ if (NULL != OldSourceBitmap)
+ {
+ SelectObject(hSourceDc, OldSourceBitmap);
+ }
+ if (NULL != hSourceDc)
+ {
+ DeleteDC(hSourceDc);
+ }
+
+ return SmallIcon;
}
#endif
DWORD dwFlags,
BOOL ChkRegCls)
{
- ATOM Atom;
- WNDCLASSEXW WndClass;
- UNICODE_STRING ClassName;
- UNICODE_STRING MenuName = {0};
- CLSMENUNAME clsMenuName;
- ANSI_STRING AnsiMenuName;
- HMODULE hLibModule = NULL;
- DWORD save_error;
- BOOL ClassFound = FALSE;
-
- if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
- lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
- lpwcx->lpszClassName == NULL)
- {
- TRACE("RegisterClassExWOWW Invalid Parameter Error!\n");
- SetLastError(ERROR_INVALID_PARAMETER);
- return 0;
- }
-
- if (ChkRegCls)
- {
- if (!RegisterDefaultClasses) RegisterSystemControls();
- }
- /*
- * 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
-
- GetWin32ClientInfo()->dwExpWinVer & (WINVER == 0x400)
- */
- if (lpwcx->hInstance == User32Instance)
- {
- TRACE("RegisterClassExWOWW User32Instance!\n");
- 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));
+ ATOM Atom;
+ WNDCLASSEXW WndClass;
+ UNICODE_STRING ClassName;
+ UNICODE_STRING ClassVersion;
+ UNICODE_STRING MenuName = {0};
+ CLSMENUNAME clsMenuName;
+ ANSI_STRING AnsiMenuName;
+ LPCWSTR lpszClsVersion;
+
+ if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
+ lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
+ lpwcx->lpszClassName == NULL)
+ {
+ TRACE("RegisterClassExWOWW Invalid Parameter Error!\n");
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return 0;
+ }
+
+ if (ChkRegCls)
+ {
+ if (!RegisterDefaultClasses) RegisterSystemControls();
+ }
+ /*
+ * 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
+
+ GetWin32ClientInfo()->dwExpWinVer & (WINVER == 0x400)
+ */
+ if (lpwcx->hInstance == User32Instance)
+ {
+ TRACE("RegisterClassExWOWW User32Instance!\n");
+ 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 (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);
- RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
- }
- }
- else
- {
- MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
- AnsiMenuName.Buffer = (PCHAR)WndClass.lpszMenuName;
- }
- }
-
- if (IS_ATOM(WndClass.lpszClassName))
- {
- ClassName.Length =
- ClassName.MaximumLength = 0;
- ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
- }
- else
- {
- RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
- }
-
- clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
- clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
- clsMenuName.pusMenuName = &MenuName;
-
- for(;;)
- {
- Atom = NtUserRegisterClassExWOW( &WndClass,
- &ClassName,
- NULL, //PUNICODE_STRING ClsNVersion,
- &clsMenuName,
- fnID,
- dwFlags,
- pdwWowData);
-
- if (Atom) break;
- if (!ClassFound)
- {
- save_error = GetLastError();
- if ( save_error == ERROR_CANNOT_FIND_WND_CLASS ||
- save_error == ERROR_CLASS_DOES_NOT_EXIST )
- {
- ClassFound = VersionRegisterClass(ClassName.Buffer, NULL, NULL, &hLibModule);
- if (ClassFound) continue;
- }
- }
- if (hLibModule)
- {
- save_error = GetLastError();
- FreeLibrary(hLibModule);
- SetLastError(save_error);
- hLibModule = 0;
- }
- break;
- }
-
- 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);
+ RtlInitEmptyAnsiString(&AnsiMenuName, NULL, 0);
+ if (WndClass.lpszMenuName != NULL)
+ {
+ if (!IS_INTRESOURCE(WndClass.lpszMenuName))
+ {
+ if (WndClass.lpszMenuName[0])
+ {
+ RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
+ RtlUnicodeStringToAnsiString( &AnsiMenuName, &MenuName, TRUE);
+ }
+ }
+ else
+ {
+ MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
+ AnsiMenuName.Buffer = (PCHAR)WndClass.lpszMenuName;
+ }
+ }
+
+ if (IS_ATOM(WndClass.lpszClassName))
+ {
+ ClassName.Length =
+ ClassName.MaximumLength = 0;
+ ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
+ }
+ else
+ {
+ RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
+ }
- return Atom;
+ ClassVersion = ClassName;
+ if (fnID == 0)
+ {
+ lpszClsVersion = ClassNameToVersion(lpwcx->lpszClassName, NULL, NULL, NULL, FALSE);
+ if (lpszClsVersion)
+ {
+ RtlInitUnicodeString(&ClassVersion, lpszClsVersion);
+ }
+ }
+
+ clsMenuName.pszClientAnsiMenuName = AnsiMenuName.Buffer;
+ clsMenuName.pwszClientUnicodeMenuName = MenuName.Buffer;
+ clsMenuName.pusMenuName = &MenuName;
+
+ Atom = NtUserRegisterClassExWOW( &WndClass,
+ &ClassName,
+ &ClassVersion,
+ &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;
}
/*
ATOM WINAPI
RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
{
- RTL_ATOM Atom;
- WNDCLASSEXW WndClass;
- WCHAR mname[MAX_BUFFER_LEN];
- WCHAR cname[MAX_BUFFER_LEN];
-
- RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXA));
-
- if (WndClass.lpszMenuName != NULL)
- {
- if (!IS_INTRESOURCE(WndClass.lpszMenuName))
- {
- if (WndClass.lpszMenuName[0])
- {
- if (!MultiByteToWideChar( CP_ACP, 0, lpwcx->lpszMenuName, -1, mname, MAX_ATOM_LEN + 1 )) return 0;
-
- WndClass.lpszMenuName = mname;
- }
- }
- }
-
- if (!IS_ATOM(WndClass.lpszClassName))
- {
- if (!MultiByteToWideChar( CP_ACP, 0, lpwcx->lpszClassName, -1, cname, MAX_ATOM_LEN + 1 )) return 0;
-
- WndClass.lpszClassName = cname;
- }
-
- Atom = RegisterClassExWOWW( &WndClass,
+ RTL_ATOM Atom;
+ WNDCLASSEXW WndClass;
+ WCHAR mname[MAX_BUFFER_LEN];
+ WCHAR cname[MAX_BUFFER_LEN];
+
+ RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXA));
+
+ if (WndClass.lpszMenuName != NULL)
+ {
+ if (!IS_INTRESOURCE(WndClass.lpszMenuName))
+ {
+ if (WndClass.lpszMenuName[0])
+ {
+ if (!MultiByteToWideChar( CP_ACP, 0, lpwcx->lpszMenuName, -1, mname, MAX_ATOM_LEN + 1 )) return 0;
+
+ WndClass.lpszMenuName = mname;
+ }
+ }
+ }
+
+ if (!IS_ATOM(WndClass.lpszClassName))
+ {
+ if (!MultiByteToWideChar( CP_ACP, 0, lpwcx->lpszClassName, -1, cname, MAX_ATOM_LEN + 1 )) return 0;
+
+ WndClass.lpszClassName = cname;
+ }
+
+ Atom = RegisterClassExWOWW( &WndClass,
0,
0,
CSF_ANSIPROC,
TRUE);
- 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);
+ 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);
- return (ATOM)Atom;
+ return (ATOM)Atom;
}
/*
ATOM WINAPI
RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
{
- ATOM Atom;
+ ATOM Atom;
- Atom = RegisterClassExWOWW( (WNDCLASSEXW *)lpwcx, 0, 0, 0, TRUE);
+ Atom = RegisterClassExWOWW( (WNDCLASSEXW *)lpwcx, 0, 0, 0, TRUE);
- TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d\n",
+ TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d\n",
Atom, lpwcx->lpfnWndProc, lpwcx->hInstance, lpwcx->hbrBackground,
lpwcx->style, lpwcx->cbClsExtra, lpwcx->cbWndExtra);
- return Atom;
+ return Atom;
}
/*
ATOM WINAPI
RegisterClassA(CONST WNDCLASSA *lpWndClass)
{
- WNDCLASSEXA Class;
+ WNDCLASSEXA Class;
- if (lpWndClass == NULL)
- return 0;
+ if (lpWndClass == NULL)
+ return 0;
- RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSA));
- Class.cbSize = sizeof(WNDCLASSEXA);
- Class.hIconSm = NULL;
+ RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSA));
+ Class.cbSize = sizeof(WNDCLASSEXA);
+ Class.hIconSm = NULL;
- return RegisterClassExA(&Class);
+ return RegisterClassExA(&Class);
}
/*
ATOM WINAPI
RegisterClassW(CONST WNDCLASSW *lpWndClass)
{
- WNDCLASSEXW Class;
+ WNDCLASSEXW Class;
- if (lpWndClass == NULL)
- return 0;
+ if (lpWndClass == NULL)
+ return 0;
- RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSW));
- Class.cbSize = sizeof(WNDCLASSEXW);
- Class.hIconSm = NULL;
+ RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSW));
+ Class.cbSize = sizeof(WNDCLASSEXW);
+ Class.hIconSm = NULL;
- return RegisterClassExW(&Class);
+ return RegisterClassExW(&Class);
}
/*
int nIndex,
LONG dwNewLong)
{
- return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, TRUE);
+ return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, TRUE);
}
/*
int nIndex,
LONG dwNewLong)
{
- return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
+ return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
}
#ifdef _WIN64
INT nIndex,
LONG_PTR dwNewLong)
{
- return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
+ return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
}
/*
INT nIndex,
LONG_PTR dwNewLong)
{
- return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
+ return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
}
#endif
{
UNICODE_STRING ClassName = {0};
BOOL Ret;
+ LPCWSTR lpszClsVersion;
+ BOOL ConvertedString = FALSE;
TRACE("class/atom: %s/%04x %p\n",
IS_ATOM(lpClassName) ? NULL : lpClassName,
IS_ATOM(lpClassName) ? lpClassName : 0,
hInstance);
- if (!IS_ATOM(lpClassName))
+ lpszClsVersion = ClassNameToVersion(lpClassName, NULL, NULL, NULL, TRUE);
+ if (lpszClsVersion)
{
- if (!RtlCreateUnicodeStringFromAsciiz(&ClassName,
- lpClassName))
+ RtlInitUnicodeString(&ClassName, lpszClsVersion);
+ }
+ else if (!IS_ATOM(lpClassName))
+ {
+ ConvertedString = TRUE;
+ if (!RtlCreateUnicodeStringFromAsciiz(&ClassName, lpClassName))
{
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
return 0;
else
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
- Ret = NtUserUnregisterClass(&ClassName,
- hInstance,
- 0);
+ Ret = NtUserUnregisterClass(&ClassName, hInstance, 0);
- if (!IS_ATOM(lpClassName))
+ if (ConvertedString)
RtlFreeUnicodeString(&ClassName);
return Ret;
HINSTANCE hInstance)
{
UNICODE_STRING ClassName = {0};
+ LPCWSTR lpszClsVersion;
TRACE("class/atom: %S/%04x %p\n",
IS_ATOM(lpClassName) ? NULL : lpClassName,
IS_ATOM(lpClassName) ? lpClassName : 0,
hInstance);
- if (!IS_ATOM(lpClassName))
+ lpszClsVersion = ClassNameToVersion(lpClassName, NULL, NULL, NULL, FALSE);
+ if (lpszClsVersion)
+ {
+ RtlInitUnicodeString(&ClassName, lpszClsVersion);
+ }
+ else if (!IS_ATOM(lpClassName))
{
- RtlInitUnicodeString(&ClassName,
- lpClassName);
+ RtlInitUnicodeString(&ClassName, lpClassName);
}
else
+ {
ClassName.Buffer = (PWSTR)((ULONG_PTR)lpClassName);
+ }
- return NtUserUnregisterClass(&ClassName,
- hInstance,
- 0);
+ return NtUserUnregisterClass(&ClassName, hInstance, 0);
}
/* EOF */