-/*
- * COPYRIGHT: See COPYING in the top level directory
- * PROJECT: ReactOS system libraries
- * FILE: lib/user32/windows/class.c
- * PURPOSE: Registers a window class
- * PROGRAMER: Boudewijn Dekker
+/* $Id$
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS user32.dll
+ * FILE: lib/user32/windows/class.c
+ * PURPOSE: Window classes
+ * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
* UPDATE HISTORY:
- * 28/05/99: Created
+ * 09-05-2001 CSH Created
*/
-#include <windows.h>
-#include <user32/class.h>
-#include <user32/win.h>
-#include <user32/dce.h>
-#include <user32/heapdup.h>
-
-CLASS *rootClass;
-ATOM STDCALL
-RegisterClassA(const WNDCLASS* wc)
-{
- WNDCLASSEX wcex;
-
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = wc->style;
- wcex.lpfnWndProc = wc->lpfnWndProc;
- wcex.cbClsExtra = wc->cbClsExtra;
- wcex.cbWndExtra = wc->cbWndExtra;
- wcex.hInstance = wc->hInstance;
- wcex.hIcon = wc->hIcon;
- wcex.hCursor = wc->hCursor;
- wcex.hbrBackground = wc->hbrBackground;
- wcex.lpszMenuName = wc->lpszMenuName;
- wcex.lpszClassName = wc->lpszClassName;
- wcex.hIconSm = NULL;
- return RegisterClassExA(&wcex);
-}
+#include <user32.h>
-ATOM STDCALL
-RegisterClassW(const WNDCLASS* wc)
+static BOOL GetClassInfoExCommon(
+ HINSTANCE hInst,
+ LPCWSTR lpszClass,
+ LPWNDCLASSEXW lpwcx,
+ BOOL unicode)
{
- WNDCLASSEX wcex;
-
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.style = wc->style;
- wcex.lpfnWndProc = wc->lpfnWndProc;
- wcex.cbClsExtra = wc->cbClsExtra;
- wcex.cbWndExtra = wc->cbWndExtra;
- wcex.hInstance = wc->hInstance;
- wcex.hIcon = wc->hIcon;
- wcex.hCursor = wc->hCursor;
- wcex.hbrBackground = wc->hbrBackground;
- wcex.lpszMenuName = wc->lpszMenuName;
- wcex.lpszClassName = wc->lpszClassName;
- wcex.hIconSm = NULL;
- return RegisterClassExW(&wcex);
-}
+ LPWSTR str;
+ UNICODE_STRING str2, str3;
+ WNDCLASSEXW w;
+ BOOL retval;
+ NTSTATUS Status;
+
+ if ( !lpszClass || !lpwcx )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ if(IS_ATOM(lpszClass))
+ str = (LPWSTR)lpszClass;
+ else
+ {
+ extern BOOL ControlsInitialized;
+
+ if (unicode)
+ {
+ str = HEAP_strdupW ( lpszClass, wcslen(lpszClass) );
-ATOM STDCALL
-RegisterClassExA(const WNDCLASSEX* wc)
-{
- ATOM atom;
- CLASS *classPtr;
- INT classExtra, winExtra;
- int len;
-
- if (wc == NULL || wc->cbSize != sizeof(WNDCLASSEX))
- {
- SetLastError(ERROR_INVALID_DATA);
- return FALSE;
- }
-
- atom = GlobalAddAtomA(wc->lpszClassName);
- if (!atom)
- {
- SetLastError(ERROR_CLASS_ALREADY_EXISTS);
- return FALSE;
- }
-
- classExtra = wc->cbClsExtra;
- if (classExtra < 0)
- classExtra = 0;
- else if (classExtra > 40)
- classExtra = 40;
-
- winExtra = wc->cbClsExtra;
- if (winExtra < 0)
- winExtra = 0;
- else if (winExtra > 40)
- winExtra = 40;
-
- classPtr = (CLASS *)HeapAlloc( GetProcessHeap(), 0, sizeof(CLASS) +
- classExtra - sizeof(classPtr->wExtra) );
-
-
- if (classExtra)
- HEAP_memset( classPtr->wExtra, 0, classExtra );
-
- if (!classPtr) {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- GlobalDeleteAtom( atom );
- return FALSE;
- }
- classPtr->magic = CLASS_MAGIC;
- classPtr->cWindows = 0;
- classPtr->style = wc->style;
- classPtr->winproc = wc->lpfnWndProc;
- classPtr->cbWndExtra = winExtra;
- classPtr->cbClsExtra = classExtra;
- classPtr->hInstance = wc->hInstance;
- classPtr->atomName = atom;
- classPtr->hIcon = (HICON)wc->hIcon;
- classPtr->hIconSm = (HICON)wc->hIconSm;
- classPtr->hCursor = (HCURSOR)wc->hCursor;
- classPtr->hbrBackground = (HBRUSH)wc->hbrBackground;
- classPtr->bUnicode = FALSE;
-
- if (wc->style & CS_CLASSDC)
- classPtr->dce = DCE_AllocDCE( 0, DCE_CLASS_DC ) ;
- else
- classPtr->dce = NULL;
-
-
- if ( wc->lpszMenuName != NULL ) {
- len = lstrlenA(wc->lpszMenuName);
- classPtr->menuName = HeapAlloc(GetProcessHeap(),0,len+1);
- lstrcpyA(classPtr->menuName,wc->lpszMenuName);
+ if ( !str )
+ {
+ SetLastError (ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
}
- else
- classPtr->menuName = NULL;
-
-
-
- len = lstrlenA(wc->lpszClassName);
- classPtr->className = HeapAlloc(GetProcessHeap(),0,len+1);
- lstrcpyA(classPtr->className,wc->lpszClassName);
-
-
-
- classPtr->next = rootClass;
- rootClass = classPtr;
-
- return atom;
-}
+ else
+ {
+ Status = HEAP_strdupAtoW(&str, (LPCSTR)lpszClass, NULL);
-ATOM STDCALL RegisterClassExW( const WNDCLASSEX* wc )
-{
- ATOM atom;
- CLASS *classPtr;
- INT classExtra, winExtra;
-
- int len;
- if ( wc == NULL || wc->cbSize != sizeof(WNDCLASSEX)) {
- SetLastError(ERROR_INVALID_DATA);
- return FALSE;
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
}
- if (!(atom = GlobalAddAtomW( (LPWSTR)wc->lpszClassName )))
+ /* Register built-in controls if not already done */
+ if ( !ControlsInitialized )
{
- SetLastError(ERROR_CLASS_ALREADY_EXISTS);
- return FALSE;
+ ControlsInitialized = ControlsInit(str);
}
+ }
+
+ str2.Length = str3.Length = 0;
+ str2.MaximumLength = str3.MaximumLength = 255;
+ str2.Buffer = (PWSTR)HEAP_alloc ( str2.MaximumLength * sizeof(WCHAR) );
+ if ( !str2.Buffer )
+ {
+ SetLastError (ERROR_OUTOFMEMORY);
+ if ( !IS_ATOM(str) )
+ HEAP_free ( str );
+ return FALSE;
+ }
+
+ str3.Buffer = (PWSTR)HEAP_alloc ( str3.MaximumLength * sizeof(WCHAR) );
+ if ( !str3.Buffer )
+ {
+ SetLastError (ERROR_OUTOFMEMORY);
+ HEAP_free ( str2.Buffer );
+ if ( !IS_ATOM(str) )
+ HEAP_free ( str );
+ return FALSE;
+ }
+
+ w.lpszMenuName = (LPCWSTR)&str2;
+ w.lpszClassName = (LPCWSTR)&str3;
+
+ /* get info about system classes? */
+ if (!hInst) hInst = User32Instance;
+
+ retval = (BOOL)NtUserGetClassInfo(hInst, str, &w, TRUE, 0);
+
+ w.hInstance = (hInst == User32Instance) ? 0 : hInst;
+
+ if ( !IS_ATOM(str) )
+ HEAP_free(str);
+
+ RtlCopyMemory ( lpwcx, &w, sizeof(WNDCLASSEXW) );
+
+ if ( !IS_INTRESOURCE(w.lpszMenuName) && w.lpszMenuName )
+ {
+ if (unicode)
+ lpwcx->lpszMenuName = heap_string_poolW ( str2.Buffer, str2.Length );
+ else
+ ((LPWNDCLASSEXA) lpwcx)->lpszMenuName = heap_string_poolA ( str2.Buffer, str2.Length );
+ }
- classExtra = wc->cbClsExtra;
- if (classExtra < 0)
- classExtra = 0;
- else if (classExtra > 40)
- classExtra = 40;
-
- winExtra = wc->cbClsExtra;
- if (winExtra < 0)
- winExtra = 0;
- else if (winExtra > 40)
- winExtra = 40;
+ if ( !IS_ATOM(w.lpszClassName) && w.lpszClassName )
+ {
+ if (unicode)
+ lpwcx->lpszClassName = heap_string_poolW ( str3.Buffer, str3.Length );
+ else
+ ((LPWNDCLASSEXA) lpwcx)->lpszClassName = heap_string_poolA ( str3.Buffer, str3.Length );
+ }
- classPtr = (CLASS *)HeapAlloc( GetProcessHeap(), 0, sizeof(CLASS) +
- classExtra - sizeof(classPtr->wExtra) );
+ HEAP_free ( str2.Buffer );
+ HEAP_free ( str3.Buffer );
+ return retval;
+}
- if (classExtra)
- HEAP_memset( classPtr->wExtra, 0, classExtra );
- if (!classPtr) {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- GlobalDeleteAtom( atom );
- return FALSE;
- }
- classPtr->magic = CLASS_MAGIC;
- classPtr->cWindows = 0;
- classPtr->style = wc->style;
- classPtr->winproc = wc->lpfnWndProc;
- classPtr->cbWndExtra = winExtra;
- classPtr->cbClsExtra = classExtra;
- classPtr->hInstance = wc->hInstance;
- classPtr->atomName = atom;
- classPtr->hIcon = (HICON)wc->hIcon;
- classPtr->hIconSm = (HICON)wc->hIconSm;
- classPtr->hCursor = (HCURSOR)wc->hCursor;
- classPtr->hbrBackground = (HBRUSH)wc->hbrBackground;
- classPtr->bUnicode = FALSE;
-
- classPtr->dce = (wc->style & CS_CLASSDC) ?
- CreateDC( "DISPLAY", NULL,NULL,NULL ) : NULL;
-
- if ( wc->lpszMenuName != NULL ) {
- len = lstrlenW(wc->lpszMenuName);
- classPtr->menuName = HeapAlloc(GetProcessHeap(),0,sizeof(WCHAR)*(len+1));
- lstrcpyW(classPtr->menuName,wc->lpszMenuName);
- }
- else
- classPtr->menuName = NULL;
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetClassInfoExA(
+ HINSTANCE hinst,
+ LPCSTR lpszClass,
+ LPWNDCLASSEXA lpwcx)
+{
+ return GetClassInfoExCommon(hinst, (LPWSTR)lpszClass, (LPWNDCLASSEXW)lpwcx, FALSE);
+}
- len = lstrlenW((LPWSTR)wc->lpszClassName);
- classPtr->className = HeapAlloc(GetProcessHeap(),0,(len+1)*sizeof(WCHAR));
- lstrcpyW((LPWSTR)classPtr->className,(LPWSTR) wc->lpszClassName );
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetClassInfoExW(
+ HINSTANCE hinst,
+ LPCWSTR lpszClass,
+ LPWNDCLASSEXW lpwcx)
+{
+ return GetClassInfoExCommon(hinst, lpszClass, lpwcx, TRUE);
+}
- classPtr->next = rootClass;
- rootClass = classPtr;
- return atom;
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetClassInfoA(
+ HINSTANCE hInstance,
+ LPCSTR lpClassName,
+ LPWNDCLASSA lpWndClass)
+{
+ WNDCLASSEXA w;
+ BOOL retval;
+
+ if ( !lpClassName || !lpWndClass )
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ retval = GetClassInfoExA(hInstance,lpClassName,&w);
+ if (retval)
+ {
+ RtlCopyMemory ( lpWndClass, &w.style, sizeof(WNDCLASSA) );
+ }
+ return retval;
}
-WINBOOL STDCALL UnregisterClassA(LPCSTR lpClassName, HINSTANCE hInstance )
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+GetClassInfoW(
+ HINSTANCE hInstance,
+ LPCWSTR lpClassName,
+ LPWNDCLASSW lpWndClass)
{
- CLASS *classPtr;
- classPtr = CLASS_FindClassByAtom( STRING2ATOMA(lpClassName), hInstance );
- if ( classPtr == NULL )
- return FALSE;
+ WNDCLASSEXW w;
+ BOOL retval;
+
+ if(!lpClassName || !lpWndClass)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ retval = GetClassInfoExW(hInstance,lpClassName,&w);
+ RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
+ return retval;
+}
- if ( CLASS_FreeClass(classPtr) == TRUE )
- GlobalDeleteAtom( classPtr->atomName );
- return TRUE;
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetClassLongA(HWND hWnd, int nIndex)
+{
+ switch (nIndex)
+ {
+ case GCL_HBRBACKGROUND:
+ {
+ DWORD hBrush = NtUserGetClassLong(hWnd, GCL_HBRBACKGROUND, TRUE);
+ if (hBrush != 0 && hBrush < 0x4000)
+ hBrush = (DWORD)GetSysColorBrush((ULONG)hBrush - 1);
+ return hBrush;
+ }
+
+ case GCL_MENUNAME:
+ {
+ PUNICODE_STRING Name;
+ Name = (PUNICODE_STRING)NtUserGetClassLong(hWnd, nIndex, TRUE);
+ if (IS_INTRESOURCE(Name))
+ return (DWORD)Name;
+ else
+ return (DWORD)heap_string_poolA(Name->Buffer, Name->Length);
+ }
+
+ default:
+ return NtUserGetClassLong(hWnd, nIndex, TRUE);
+ }
}
+/*
+ * @implemented
+ */
+DWORD STDCALL
+GetClassLongW ( HWND hWnd, int nIndex )
+{
+ switch (nIndex)
+ {
+ case GCL_HBRBACKGROUND:
+ {
+ DWORD hBrush = NtUserGetClassLong(hWnd, GCL_HBRBACKGROUND, TRUE);
+ if (hBrush != 0 && hBrush < 0x4000)
+ hBrush = (DWORD)GetSysColorBrush((ULONG)hBrush - 1);
+ return hBrush;
+ }
+
+ case GCL_MENUNAME:
+ {
+ PUNICODE_STRING Name;
+ Name = (PUNICODE_STRING)NtUserGetClassLong(hWnd, nIndex, FALSE);
+ if (IS_INTRESOURCE(Name))
+ return (DWORD)Name;
+ else
+ return (DWORD)heap_string_poolW(Name->Buffer, Name->Length);
+ }
+
+ default:
+ return NtUserGetClassLong(hWnd, nIndex, FALSE);
+ }
+}
-
-WINBOOL STDCALL UnregisterClassW(LPCWSTR lpClassName, HINSTANCE hInstance )
+/*
+ * @implemented
+ */
+int STDCALL
+GetClassNameA(
+ HWND hWnd,
+ LPSTR lpClassName,
+ int nMaxCount)
{
- CLASS *classPtr;
- classPtr = CLASS_FindClassByAtom( STRING2ATOMW(lpClassName), hInstance );
- if ( classPtr == NULL )
- return FALSE;
+ int result;
+ LPWSTR ClassNameW;
+ NTSTATUS Status;
+
+ if(!lpClassName)
+ return 0;
+
+ ClassNameW = HEAP_alloc ( (nMaxCount+1)*sizeof(WCHAR) );
+
+ result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount );
+
+ Status = HEAP_strcpyWtoA ( lpClassName, ClassNameW, result );
+
+ HEAP_free ( ClassNameW );
+ if ( !NT_SUCCESS(Status) )
+ return 0;
- if ( CLASS_FreeClass(classPtr) == TRUE )
- GlobalDeleteAtom( classPtr->atomName );
- return TRUE;
+ return result;
}
-WINBOOL STDCALL GetClassInfoA( HINSTANCE hInstance, LPCSTR lpClassName, LPWNDCLASS lpWndClass )
+/*
+ * @implemented
+ */
+int
+STDCALL
+GetClassNameW(
+ HWND hWnd,
+ LPWSTR lpClassName,
+ int nMaxCount)
{
-
- CLASS *classPtr;
- ATOM a;
-
- if ( HIWORD(lpClassName) != 0 )
- a = FindAtomA(lpClassName);
- else
- a = lpClassName;
-
- classPtr = CLASS_FindClassByAtom( a, hInstance );
- if ( classPtr == NULL )
- return FALSE;
-
-
- lpWndClass->style = classPtr->style;
- lpWndClass->lpfnWndProc = classPtr->winproc;
- lpWndClass->cbClsExtra = classPtr->cbWndExtra;
- lpWndClass->cbClsExtra = classPtr->cbClsExtra;
- lpWndClass->hInstance = classPtr->hInstance;
- lpWndClass->hIcon = classPtr->hIcon;
- lpWndClass->hCursor = classPtr->hCursor;
- lpWndClass->hbrBackground = classPtr->hbrBackground;
- return TRUE;
+ return NtUserGetClassName(hWnd, lpClassName, nMaxCount);
}
-WINBOOL STDCALL GetClassInfoW( HINSTANCE hInstance, LPCWSTR lpClassName, LPWNDCLASS lpWndClass )
+/*
+ * @implemented
+ */
+WORD
+STDCALL
+GetClassWord(
+ HWND hWnd,
+ int nIndex)
+/*
+ * NOTE: Obsoleted in 32-bit windows
+ */
{
- CLASS *classPtr;
- ATOM a;
-
- if ( HIWORD(lpClassName) != 0 )
- a = FindAtomW(lpClassName);
- else
- a = lpClassName;
-
- classPtr = CLASS_FindClassByAtom( a, hInstance );
- if ( classPtr == NULL )
- return FALSE;
-
-
- lpWndClass->style = classPtr->style;
- lpWndClass->lpfnWndProc = classPtr->winproc;
- lpWndClass->cbClsExtra = classPtr->cbWndExtra;
- lpWndClass->cbClsExtra = classPtr->cbClsExtra;
- lpWndClass->hInstance = classPtr->hInstance;
- lpWndClass->hIcon = classPtr->hIcon;
- lpWndClass->hCursor = classPtr->hCursor;
- lpWndClass->hbrBackground = classPtr->hbrBackground;
- return TRUE;
-
+ if ((nIndex < 0) && (nIndex != GCW_ATOM))
+ return 0;
+
+ return (WORD) NtUserGetClassLong ( hWnd, nIndex, TRUE );
}
-WINBOOL STDCALL GetClassInfoExA( HINSTANCE hInstance, LPCSTR lpClassName, LPWNDCLASSEX lpWndClassEx )
+
+/*
+ * @implemented
+ */
+LONG
+STDCALL
+GetWindowLongA ( HWND hWnd, int nIndex )
{
+ return NtUserGetWindowLong(hWnd, nIndex, TRUE);
+}
- CLASS *classPtr;
- ATOM a;
-
- if ( HIWORD(lpClassName) != 0 )
- a = FindAtomA(lpClassName);
- else
- a = (ATOM)lpClassName;
-
- classPtr = CLASS_FindClassByAtom( a, hInstance );
- if ( classPtr == NULL )
- return FALSE;
-
-
- if ( lpWndClassEx ->cbSize != sizeof(WNDCLASSEX) )
- return FALSE;
-
-
- lpWndClassEx->style = classPtr->style;
- lpWndClassEx->lpfnWndProc = classPtr->winproc;
- lpWndClassEx->cbClsExtra = classPtr->cbWndExtra;
- lpWndClassEx->cbClsExtra = classPtr->cbClsExtra;
- lpWndClassEx->hInstance = classPtr->hInstance;
- lpWndClassEx->hIcon = classPtr->hIcon;
- lpWndClassEx->hCursor = classPtr->hCursor;
- lpWndClassEx->hbrBackground = classPtr->hbrBackground;
-
-
- return TRUE;
+
+/*
+ * @implemented
+ */
+LONG
+STDCALL
+GetWindowLongW(HWND hWnd, int nIndex)
+{
+ return NtUserGetWindowLong(hWnd, nIndex, FALSE);
}
-WINBOOL STDCALL GetClassInfoExW( HINSTANCE hInstance, LPCWSTR lpClassName, LPWNDCLASSEX lpWndClassEx )
+/*
+ * @implemented
+ */
+WORD
+STDCALL
+GetWindowWord(HWND hWnd, int nIndex)
{
+ return (WORD)NtUserGetWindowLong(hWnd, nIndex, TRUE);
+}
- CLASS *classPtr;
- ATOM a;
-
- if ( HIWORD(lpClassName) != 0 )
- a = FindAtomW(lpClassName);
- else
- a = (ATOM)lpClassName;
-
- classPtr = CLASS_FindClassByAtom( a, hInstance );
- if ( classPtr == NULL )
- return FALSE;
-
-
- if ( lpWndClassEx ->cbSize != sizeof(WNDCLASSEX) )
- return FALSE;
-
-
- lpWndClassEx->style = classPtr->style;
- lpWndClassEx->lpfnWndProc = classPtr->winproc;
- lpWndClassEx->cbClsExtra = classPtr->cbWndExtra;
- lpWndClassEx->cbClsExtra = classPtr->cbClsExtra;
- lpWndClassEx->hInstance = classPtr->hInstance;
- lpWndClassEx->hIcon = classPtr->hIcon;
- lpWndClassEx->hCursor = classPtr->hCursor;
- lpWndClassEx->hbrBackground = classPtr->hbrBackground;
-
-
- return TRUE;
+/*
+ * @implemented
+ */
+WORD
+STDCALL
+SetWindowWord ( HWND hWnd,int nIndex,WORD wNewWord )
+{
+ return (WORD)NtUserSetWindowLong ( hWnd, nIndex, (LONG)wNewWord, TRUE );
}
-int STDCALL GetClassNameA(HWND hWnd, LPSTR lpClassName, int nMaxCount )
+/*
+ * @implemented
+ */
+UINT
+STDCALL
+RealGetWindowClassW(
+ HWND hwnd,
+ LPWSTR pszType,
+ UINT cchType)
{
- WND *wndPtr = WIN_FindWndPtr(hWnd);
+ /* FIXME: Implement correct functionality of RealGetWindowClass */
+ return GetClassNameW(hwnd,pszType,cchType);
+}
- if ( wndPtr == NULL )
- return 0;
- if ( wndPtr->class->bUnicode == TRUE )
- return 0;
+/*
+ * @implemented
+ */
+UINT
+STDCALL
+RealGetWindowClassA(
+ HWND hwnd,
+ LPSTR pszType,
+ UINT cchType)
+{
+ /* FIXME: Implement correct functionality of RealGetWindowClass */
+ return GetClassNameA(hwnd,pszType,cchType);
+}
- return lpstrncpyA(lpClassName,wndPtr->class->className, nMaxCount);
-
+/*
+ * Create a small icon based on a standard icon
+ */
+static HICON
+CreateSmallIcon(HICON StdIcon)
+{
+ HICON SmallIcon = NULL;
+ ICONINFO StdInfo;
+ int SmallIconWidth;
+ int SmallIconHeight;
+ BITMAP StdBitmapInfo;
+ HDC hInfoDc = NULL;
+ 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))
+ {
+ DPRINT1("Failed to get icon info for icon 0x%x\n", StdIcon);
+ goto cleanup;
+ }
+ if (! GetObjectW(StdInfo.hbmMask, sizeof(BITMAP), &StdBitmapInfo))
+ {
+ DPRINT1("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;
+ }
+
+ /* Get a handle to a info DC and handles to DCs which can be used to
+ select a bitmap into. This is done to avoid triggering a switch to
+ graphics mode (if we're currently in text/blue screen mode) */
+ hInfoDc = CreateICW(NULL, NULL, NULL, NULL);
+ if (NULL == hInfoDc)
+ {
+ DPRINT1("Failed to create info DC\n");
+ goto cleanup;
+ }
+ hSourceDc = CreateCompatibleDC(NULL);
+ if (NULL == hSourceDc)
+ {
+ DPRINT1("Failed to create source DC\n");
+ goto cleanup;
+ }
+ hDestDc = CreateCompatibleDC(NULL);
+ if (NULL == hDestDc)
+ {
+ DPRINT1("Failed to create dest DC\n");
+ goto cleanup;
+ }
+
+ OldSourceBitmap = SelectObject(hSourceDc, StdInfo.hbmColor);
+ if (NULL == OldSourceBitmap)
+ {
+ DPRINT1("Failed to select source color bitmap\n");
+ goto cleanup;
+ }
+ SmallInfo.hbmColor = CreateCompatibleBitmap(hInfoDc, SmallIconWidth,
+ SmallIconHeight);
+ if (NULL == SmallInfo.hbmColor)
+ {
+ DPRINT1("Failed to create color bitmap\n");
+ goto cleanup;
+ }
+ OldDestBitmap = SelectObject(hDestDc, SmallInfo.hbmColor);
+ if (NULL == OldDestBitmap)
+ {
+ DPRINT1("Failed to select dest color bitmap\n");
+ goto cleanup;
+ }
+ if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
+ hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
+ StdBitmapInfo.bmHeight, SRCCOPY))
+ {
+ DPRINT1("Failed to stretch color bitmap\n");
+ goto cleanup;
+ }
+
+ if (NULL == SelectObject(hSourceDc, StdInfo.hbmMask))
+ {
+ DPRINT1("Failed to select source mask bitmap\n");
+ goto cleanup;
+ }
+ SmallInfo.hbmMask = CreateBitmap(SmallIconWidth, SmallIconHeight, 1, 1,
+ NULL);
+ if (NULL == SmallInfo.hbmMask)
+ {
+ DPRINT1("Failed to create mask bitmap\n");
+ goto cleanup;
+ }
+ if (NULL == SelectObject(hDestDc, SmallInfo.hbmMask))
+ {
+ DPRINT1("Failed to select dest mask bitmap\n");
+ goto cleanup;
+ }
+ if (! StretchBlt(hDestDc, 0, 0, SmallIconWidth, SmallIconHeight,
+ hSourceDc, 0, 0, StdBitmapInfo.bmWidth,
+ StdBitmapInfo.bmHeight, SRCCOPY))
+ {
+ DPRINT1("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)
+ {
+ DPRINT1("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);
+ }
+ if (NULL != hInfoDc)
+ {
+ DeleteDC(hInfoDc);
+ }
+
+ return SmallIcon;
}
-int STDCALL GetClassNameW(HWND hWnd, LPWSTR lpClassName, int nMaxCount )
+/*
+ * @implemented
+ */
+ATOM STDCALL
+RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
{
- WND *wndPtr = WIN_FindWndPtr(hWnd);
+ RTL_ATOM Atom;
+ WNDCLASSEXA WndClass;
+ UNICODE_STRING ClassName;
+ UNICODE_STRING MenuName;
+ HMENU hMenu;
+
+ if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXA) ||
+ lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
+ lpwcx->lpszClassName == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ 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);
+ return 0;
+ }
+
+ /* Yes, this is correct. We should modify the passed structure. */
+ if (lpwcx->hInstance == NULL)
+ ((WNDCLASSEXA*)lpwcx)->hInstance = GetModuleHandleW(NULL);
+
+ RtlCopyMemory(&WndClass, lpwcx, sizeof(WNDCLASSEXA));
+
+ if (NULL == WndClass.hIconSm)
+ {
+ WndClass.hIconSm = CreateSmallIcon(WndClass.hIcon);
+ }
+
+ if HIWORD(lpwcx->lpszMenuName)
+ {
+ hMenu = 0;
+ RtlCreateUnicodeStringFromAsciiz(&MenuName, WndClass.lpszMenuName);
+ }
+ else
+ {
+ MenuName.Length =
+ MenuName.MaximumLength = 0;
+ MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
+ hMenu = LoadMenuA(WndClass.hInstance, lpwcx->lpszMenuName);
+ }
+
+ if (IS_ATOM(WndClass.lpszClassName))
+ {
+ ClassName.Length =
+ ClassName.MaximumLength = 0;
+ ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
+ } else
+ {
+ RtlCreateUnicodeStringFromAsciiz(&ClassName, WndClass.lpszClassName);
+ }
+
+ Atom = NtUserRegisterClassExWOW(
+ (WNDCLASSEXW*)&WndClass,
+ &ClassName,
+ &ClassName,
+ &MenuName,
+ NULL,
+ REGISTERCLASS_ANSI,
+ 0,
+ hMenu);
+
+ if (!IS_ATOM(WndClass.lpszMenuName))
+ RtlFreeUnicodeString(&MenuName);
+ if (!IS_ATOM(WndClass.lpszClassName))
+ RtlFreeUnicodeString(&ClassName);
+
+ return (ATOM)Atom;
+}
- if ( wndPtr == NULL )
- return 0;
+/*
+ * @implemented
+ */
+ATOM STDCALL
+RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
+{
+ WNDCLASSEXW WndClass;
+ UNICODE_STRING ClassName;
+ UNICODE_STRING MenuName;
+ HMENU hMenu;
+
+ if (lpwcx == NULL || lpwcx->cbSize != sizeof(WNDCLASSEXW) ||
+ lpwcx->cbClsExtra < 0 || lpwcx->cbWndExtra < 0 ||
+ lpwcx->lpszClassName == NULL)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ 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);
+ 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 HIWORD(lpwcx->lpszMenuName)
+ {
+ hMenu = 0;
+ RtlInitUnicodeString(&MenuName, WndClass.lpszMenuName);
+ }
+ else
+ {
+ MenuName.Length =
+ MenuName.MaximumLength = 0;
+ MenuName.Buffer = (LPWSTR)WndClass.lpszMenuName;
+ hMenu = LoadMenuW(WndClass.hInstance, lpwcx->lpszMenuName);
+ }
+
+ if (IS_ATOM(WndClass.lpszClassName))
+ {
+ ClassName.Length =
+ ClassName.MaximumLength = 0;
+ ClassName.Buffer = (LPWSTR)WndClass.lpszClassName;
+ } else
+ {
+ RtlInitUnicodeString(&ClassName, WndClass.lpszClassName);
+ }
+
+ return (ATOM)NtUserRegisterClassExWOW(
+ &WndClass,
+ &ClassName,
+ &ClassName,
+ &MenuName,
+ NULL,
+ 0,
+ 0,
+ hMenu);
+}
- if ( wndPtr->class->bUnicode == FALSE )
- return 0;
+/*
+ * @implemented
+ */
+ATOM STDCALL
+RegisterClassA(CONST WNDCLASSA *lpWndClass)
+{
+ WNDCLASSEXA Class;
- return lpstrncpyW(lpClassName,wndPtr->class->className, nMaxCount);
+ if (lpWndClass == NULL)
+ return 0;
+ RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSA));
+ Class.cbSize = sizeof(WNDCLASSEXA);
+ Class.hIconSm = NULL;
+ return RegisterClassExA(&Class);
}
-DWORD STDCALL GetClassLongA(HWND hWnd, int nIndex )
+/*
+ * @implemented
+ */
+ATOM STDCALL
+RegisterClassW(CONST WNDCLASSW *lpWndClass)
{
- WND * wndPtr;
-
- if (!(wndPtr = WIN_FindWndPtr( hWnd ))) return 0;
- if (nIndex >= 0)
- {
- if (nIndex <= wndPtr->class->cbClsExtra - sizeof(LONG))
- return (DWORD)((char *)wndPtr->class->wExtra) + nIndex;
- }
- switch(nIndex)
- {
- case GCL_STYLE: return (LONG)wndPtr->class->style;
- case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
- case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
- case GCL_HMODULE: return (LONG)wndPtr->class->hInstance;
- case GCL_WNDPROC: return (LONG)wndPtr->class->winproc;
- case GCL_MENUNAME: return (LONG)wndPtr->class->menuName;
- case GCW_ATOM:
- case GCL_HBRBACKGROUND:
- case GCL_HCURSOR:
- case GCL_HICON:
- case GCL_HICONSM:
- return GetClassWord( hWnd, nIndex );
- default:
- return -1;
- }
-
- return 0;
+ WNDCLASSEXW Class;
+
+ if (lpWndClass == NULL)
+ return 0;
+
+ RtlCopyMemory(&Class.style, lpWndClass, sizeof(WNDCLASSW));
+ Class.cbSize = sizeof(WNDCLASSEXW);
+ Class.hIconSm = NULL;
+
+ return RegisterClassExW(&Class);
}
-DWORD STDCALL GetClassLongW(HWND hWnd, int nIndex )
+/*
+ * @implemented
+ */
+DWORD
+STDCALL
+SetClassLongA (
+ HWND hWnd,
+ int nIndex,
+ LONG dwNewLong)
{
- WND * wndPtr;
-
- if (!(wndPtr = WIN_FindWndPtr( hWnd ))) return 0;
- if (nIndex >= 0)
- {
- if (nIndex <= wndPtr->class->cbClsExtra - sizeof(LONG))
- return (DWORD)((char *)wndPtr->class->wExtra) + nIndex;
- }
- switch(nIndex)
- {
- case GCL_STYLE: return (LONG)wndPtr->class->style;
- case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
- case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
- case GCL_HMODULE: return (LONG)wndPtr->class->hInstance;
- case GCL_WNDPROC: return (LONG)wndPtr->class->winproc;
- case GCL_MENUNAME: return (LONG)wndPtr->class->menuName;
- case GCW_ATOM:
- case GCL_HBRBACKGROUND:
- case GCL_HCURSOR:
- case GCL_HICON:
- case GCL_HICONSM:
- return GetClassWord( hWnd, nIndex );
- default:
- return -1;
- }
-
- return 0;
+ UNICODE_STRING str2buf;
+ PUNICODE_STRING str;
+ PUNICODE_STRING str2 = &str2buf;
+
+ if ( nIndex != GCL_MENUNAME )
+ {
+ return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, TRUE );
+ }
+ if ( IS_INTRESOURCE(dwNewLong) )
+ {
+ str2 = (PUNICODE_STRING)dwNewLong;
+ }
+ else
+ {
+ RtlCreateUnicodeStringFromAsciiz ( &str2buf,(LPSTR)dwNewLong );
+ }
+
+ str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE);
+
+ if ( !IS_INTRESOURCE(dwNewLong) )
+ {
+ RtlFreeUnicodeString ( str2 );
+ }
+ if ( IS_INTRESOURCE(str) )
+ {
+ return (DWORD)str;
+ }
+ else
+ {
+ return (DWORD)heap_string_poolA ( str->Buffer, str->Length );
+ }
}
-
-WORD STDCALL GetClassWord( HWND hWnd, INT nIndex )
+/*
+ * @implemented
+ */
+DWORD
+STDCALL
+SetClassLongW(
+ HWND hWnd,
+ int nIndex,
+ LONG dwNewLong)
{
- WND * wndPtr;
-
- if (!(wndPtr = WIN_FindWndPtr( hWnd ))) return 0;
- if (nIndex >= 0)
- {
- if (nIndex <= wndPtr->class->cbClsExtra - sizeof(WORD))
- return (WORD)(wndPtr->class->wExtra + nIndex);
- }
- else switch(nIndex)
- {
- //case GCW_HBRBACKGROUND: return wndPtr->class->hbrBackground;
- //case GCW_HCURSOR: return wndPtr->class->hCursor;
- //case GCW_HICON: return wndPtr->class->hIcon;
- // case GCW_HICONSM: return wndPtr->class->hIconSm;
- case GCW_ATOM: return wndPtr->class->atomName;
- //case GCW_STYLE:
- //case GCW_CBWNDEXTRA:
- //case GCW_CBCLSEXTRA:
- //case GCW_HMODULE:
- return (WORD)GetClassLongA( hWnd, nIndex );
- default:
- return -1;
- }
-
-
- return 0;
+ UNICODE_STRING str2buf;
+ PUNICODE_STRING str;
+ PUNICODE_STRING str2 = &str2buf;
+
+ if (nIndex != GCL_MENUNAME )
+ {
+ return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, FALSE );
+ }
+ if ( IS_INTRESOURCE(dwNewLong) )
+ {
+ str2 = (PUNICODE_STRING)dwNewLong;
+ }
+ else
+ {
+ RtlCreateUnicodeString ( &str2buf, (LPWSTR)dwNewLong );
+ }
+
+ str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE);
+
+ if ( !IS_INTRESOURCE(dwNewLong) )
+ {
+ RtlFreeUnicodeString(str2);
+ }
+ if ( IS_INTRESOURCE(str) )
+ {
+ return (DWORD)str;
+ }
+ else
+ {
+ return (DWORD)heap_string_poolW ( str->Buffer, str->Length );
+ }
}
+
+/*
+ * @implemented
+ */
WORD
STDCALL
SetClassWord(
- HWND hWnd,
- int nIndex,
- WORD wNewWord)
+ HWND hWnd,
+ int nIndex,
+ WORD wNewWord)
+/*
+ * NOTE: Obsoleted in 32-bit windows
+ */
{
- return 0;
+ if ((nIndex < 0) && (nIndex != GCW_ATOM))
+ return 0;
+
+ return (WORD) NtUserSetClassLong ( hWnd, nIndex, wNewWord, TRUE );
}
-DWORD
+
+/*
+ * @implemented
+ */
+LONG
STDCALL
-SetClassLongA(
- HWND hWnd,
- int nIndex,
- LONG dwNewLong)
+SetWindowLongA(
+ HWND hWnd,
+ int nIndex,
+ LONG dwNewLong)
{
- return 0;
+ return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, TRUE);
}
-DWORD
+
+/*
+ * @implemented
+ */
+LONG
STDCALL
-SetClassLongW(
- HWND hWnd,
- int nIndex,
- LONG dwNewLong)
+SetWindowLongW(
+ HWND hWnd,
+ int nIndex,
+ LONG dwNewLong)
{
- return 0;
+ return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
}
-CLASS *CLASS_FindClassByAtom( ATOM classAtom, HINSTANCE hInstance )
+
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+UnregisterClassA(
+ LPCSTR lpClassName,
+ HINSTANCE hInstance)
{
- CLASS *p = rootClass;
- while(p != NULL ) {
- if ( p->atomName == classAtom )
- return p;
- p = p->next;
- }
- return NULL;
+ LPWSTR ClassName;
+ NTSTATUS Status;
+ BOOL Result;
+
+ if(!IS_ATOM(lpClassName))
+ {
+ Status = HEAP_strdupAtoW(&ClassName, lpClassName, NULL);
+ if(!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+ }
+ else
+ ClassName = (LPWSTR)lpClassName;
+
+ Result = (BOOL)NtUserUnregisterClass((LPCWSTR)ClassName, hInstance, 0);
+
+ if(ClassName && !IS_ATOM(lpClassName))
+ HEAP_free(ClassName);
+
+ return Result;
}
-WINBOOL CLASS_FreeClass(CLASS *classPtr)
+/*
+ * @implemented
+ */
+BOOL
+STDCALL
+UnregisterClassW(
+ LPCWSTR lpClassName,
+ HINSTANCE hInstance)
{
- CLASS *p = rootClass;
- if( classPtr->cWindows > 0 )
- return FALSE;
-
- if (classPtr->dce)
- DeleteDC( classPtr->dce );
- if (classPtr->hbrBackground)
- DeleteObject( classPtr->hbrBackground );
-
-
- classPtr->atomName = 0;
- HeapFree(GetProcessHeap(),0,classPtr->className);
-
- while(p != NULL && p->next != classPtr )
- p = p->next;
-
- if ( p != NULL )
- p->next = classPtr->next;
-
- HeapFree(GetProcessHeap(),0,classPtr);
- return TRUE;
+ return (BOOL)NtUserUnregisterClass(lpClassName, hInstance, 0);
}
-
+
+/* EOF */