2 * PROJECT: ReactOS user32.dll
3 * COPYRIGHT: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/user32/windows/class.c
5 * PURPOSE: Window classes
6 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
8 * 09-05-2001 CSH Created
13 #include <wine/debug.h>
14 WINE_DEFAULT_DEBUG_CHANNEL(user32
);
26 UNICODE_STRING ClassName
= {0};
29 TRACE("%p class/atom: %s/%04x %p\n", hInstance
,
30 IS_ATOM(lpszClass
) ? NULL
: lpszClass
,
31 IS_ATOM(lpszClass
) ? lpszClass
: 0,
34 //HACKHACK: This is ROS-specific and should go away
35 lpwcx
->cbSize
= sizeof(*lpwcx
);
37 if (hInstance
== User32Instance
)
42 if (lpszClass
== NULL
)
44 SetLastError(ERROR_INVALID_PARAMETER
);
48 if (IS_ATOM(lpszClass
))
50 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpszClass
);
54 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
,
57 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
62 Ret
= NtUserGetClassInfo(hInstance
,
68 if (!IS_ATOM(lpszClass
))
70 RtlFreeUnicodeString(&ClassName
);
87 UNICODE_STRING ClassName
= {0};
89 TRACE("%p class/atom: %S/%04x %p\n", hInstance
,
90 IS_ATOM(lpszClass
) ? NULL
: lpszClass
,
91 IS_ATOM(lpszClass
) ? lpszClass
: 0,
94 //HACKHACK: This is ROS-specific and should go away
95 lpwcx
->cbSize
= sizeof(*lpwcx
);
97 if (hInstance
== User32Instance
)
102 if (lpszClass
== NULL
)
104 SetLastError(ERROR_INVALID_PARAMETER
);
108 if (IS_ATOM(lpszClass
))
110 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpszClass
);
114 RtlInitUnicodeString(&ClassName
,
118 return NtUserGetClassInfo(hInstance
,
134 LPWNDCLASSA lpWndClass
)
139 retval
= GetClassInfoExA(hInstance
, lpClassName
, &wcex
);
142 lpWndClass
->style
= wcex
.style
;
143 lpWndClass
->lpfnWndProc
= wcex
.lpfnWndProc
;
144 lpWndClass
->cbClsExtra
= wcex
.cbClsExtra
;
145 lpWndClass
->cbWndExtra
= wcex
.cbWndExtra
;
146 lpWndClass
->hInstance
= wcex
.hInstance
;
147 lpWndClass
->hIcon
= wcex
.hIcon
;
148 lpWndClass
->hCursor
= wcex
.hCursor
;
149 lpWndClass
->hbrBackground
= wcex
.hbrBackground
;
150 lpWndClass
->lpszMenuName
= wcex
.lpszMenuName
;
151 lpWndClass
->lpszClassName
= wcex
.lpszClassName
;
165 LPWNDCLASSW lpWndClass
)
170 retval
= GetClassInfoExW(hInstance
, lpClassName
, &wcex
);
173 lpWndClass
->style
= wcex
.style
;
174 lpWndClass
->lpfnWndProc
= wcex
.lpfnWndProc
;
175 lpWndClass
->cbClsExtra
= wcex
.cbClsExtra
;
176 lpWndClass
->cbWndExtra
= wcex
.cbWndExtra
;
177 lpWndClass
->hInstance
= wcex
.hInstance
;
178 lpWndClass
->hIcon
= wcex
.hIcon
;
179 lpWndClass
->hCursor
= wcex
.hCursor
;
180 lpWndClass
->hbrBackground
= wcex
.hbrBackground
;
181 lpWndClass
->lpszMenuName
= wcex
.lpszMenuName
;
182 lpWndClass
->lpszClassName
= wcex
.lpszClassName
;
191 GetClassLongA(HWND hWnd
, int nIndex
)
197 TRACE("%p %d\n", hWnd
, nIndex
);
199 Wnd
= ValidateHwnd(hWnd
);
205 Class
= DesktopPtrToUser(Wnd
->Class
);
210 if (nIndex
+ sizeof(ULONG_PTR
) < nIndex
||
211 nIndex
+ sizeof(ULONG_PTR
) > Class
->ClsExtra
)
213 SetLastError(ERROR_INVALID_PARAMETER
);
216 Ret
= *(PULONG_PTR
)((ULONG_PTR
)(Class
+ 1) + nIndex
);
223 Ret
= (ULONG_PTR
)Class
->WndExtra
;
227 Ret
= (ULONG_PTR
)Class
->ClsExtra
;
230 case GCL_HBRBACKGROUND
:
231 Ret
= (ULONG_PTR
)Class
->hbrBackground
;
232 if (Ret
!= 0 && Ret
< 0x4000)
233 Ret
= (ULONG_PTR
)GetSysColorBrush((ULONG
)Ret
- 1);
237 Ret
= (ULONG_PTR
)Class
->hInstance
;
241 Ret
= (ULONG_PTR
)Class
->AnsiMenuName
;
245 Ret
= (ULONG_PTR
)Class
->Style
;
249 Ret
= (ULONG_PTR
)Class
->Atom
;
253 /* FIXME - get handle from pointer to CURSOR object */
254 Ret
= (ULONG_PTR
)Class
->hCursor
;
258 /* FIXME - get handle from pointer to ICON object */
259 Ret
= (ULONG_PTR
)Class
->hIcon
;
263 /* FIXME - get handle from pointer to ICON object */
264 Ret
= (ULONG_PTR
)Class
->hIconSm
;
268 /* We need to make a call to win32k as it may be required to
269 create a callproc handle */
274 SetLastError(ERROR_INVALID_INDEX
);
281 /* This is a race condition! Call win32k to make sure we're getting
282 the correct result */
283 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
285 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
288 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
290 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
295 Ret
= NtUserGetClassLong(hWnd
, nIndex
, TRUE
);
304 GetClassLongW ( HWND hWnd
, int nIndex
)
310 TRACE("%p %d\n", hWnd
, nIndex
);
312 Wnd
= ValidateHwnd(hWnd
);
318 Class
= DesktopPtrToUser(Wnd
->Class
);
323 if (nIndex
+ sizeof(ULONG_PTR
) < nIndex
||
324 nIndex
+ sizeof(ULONG_PTR
) > Class
->ClsExtra
)
326 SetLastError(ERROR_INVALID_PARAMETER
);
329 Ret
= *(PULONG_PTR
)((ULONG_PTR
)(Class
+ 1) + nIndex
);
336 Ret
= (ULONG_PTR
)Class
->WndExtra
;
340 Ret
= (ULONG_PTR
)Class
->ClsExtra
;
343 case GCL_HBRBACKGROUND
:
344 Ret
= (ULONG_PTR
)Class
->hbrBackground
;
345 if (Ret
!= 0 && Ret
< 0x4000)
346 Ret
= (ULONG_PTR
)GetSysColorBrush((ULONG
)Ret
- 1);
350 Ret
= (ULONG_PTR
)Class
->hInstance
;
354 Ret
= (ULONG_PTR
)Class
->MenuName
;
358 Ret
= (ULONG_PTR
)Class
->Style
;
362 Ret
= (ULONG_PTR
)Class
->Atom
;
366 /* FIXME - get handle from pointer to CURSOR object */
367 Ret
= (ULONG_PTR
)Class
->hCursor
;
371 /* FIXME - get handle from pointer to ICON object */
372 Ret
= (ULONG_PTR
)Class
->hIcon
;
376 /* FIXME - get handle from pointer to ICON object */
377 Ret
= (ULONG_PTR
)Class
->hIconSm
;
381 /* We need to make a call to win32k as it may be required to
382 create a callproc handle */
387 SetLastError(ERROR_INVALID_INDEX
);
394 /* This is a race condition! Call win32k to make sure we're getting
395 the correct result */
396 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
398 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
401 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
403 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
408 Ret
= NtUserGetClassLong(hWnd
, nIndex
, FALSE
);
423 ANSI_STRING ClassName
;
426 ClassName
.MaximumLength
= nMaxCount
;
427 ClassName
.Buffer
= lpClassName
;
429 Result
= NtUserGetClassName(hWnd
,
430 (PUNICODE_STRING
)&ClassName
,
433 TRACE("%p class/atom: %s/%04x %x\n", hWnd
,
434 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
435 IS_ATOM(lpClassName
) ? lpClassName
: 0,
452 UNICODE_STRING ClassName
;
455 ClassName
.MaximumLength
= nMaxCount
* sizeof(WCHAR
);
456 ClassName
.Buffer
= lpClassName
;
458 Result
= NtUserGetClassName(hWnd
,
462 TRACE("%p class/atom: %S/%04x %x\n", hWnd
,
463 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
464 IS_ATOM(lpClassName
) ? lpClassName
: 0,
480 * NOTE: Obsoleted in 32-bit windows
483 TRACE("%p %x\n", hWnd
, nIndex
);
485 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
488 return (WORD
) NtUserGetClassLong ( hWnd
, nIndex
, TRUE
);
497 GetWindowLongA ( HWND hWnd
, int nIndex
)
501 Wnd
= ValidateHwnd(hWnd
);
507 if ((DWORD
)nIndex
+ sizeof(LONG
) > Wnd
->ExtraDataSize
)
509 SetLastError(ERROR_INVALID_PARAMETER
);
513 return *((LONG
*)((PCHAR
)(Wnd
+ 1) + nIndex
));
524 return (LONG
)Wnd
->Instance
;
528 return Wnd
->UserData
;
532 HWND parent
= GetAncestor( hWnd
, GA_PARENT
);
533 if (parent
== GetDesktopWindow()) parent
= GetWindow( hWnd
, GW_OWNER
);
537 /* Call win32k for this as a callproc handle may need
539 return NtUserGetWindowLong(hWnd
, nIndex
, TRUE
);
542 SetLastError(ERROR_INVALID_PARAMETER
);
554 GetWindowLongW(HWND hWnd
, int nIndex
)
558 Wnd
= ValidateHwnd(hWnd
);
564 if ((DWORD
)nIndex
+ sizeof(LONG
) > Wnd
->ExtraDataSize
)
566 SetLastError(ERROR_INVALID_PARAMETER
);
570 return *((LONG
*)((PCHAR
)(Wnd
+ 1) + nIndex
));
581 return (LONG
)Wnd
->Instance
;
585 return Wnd
->UserData
;
589 HWND parent
= GetAncestor( hWnd
, GA_PARENT
);
590 if (parent
== GetDesktopWindow()) parent
= GetWindow( hWnd
, GW_OWNER
);
594 /* Call win32k for this as a callproc handle may need
596 return NtUserGetWindowLong(hWnd
, nIndex
, FALSE
);
599 SetLastError(ERROR_INVALID_PARAMETER
);
610 GetWindowWord(HWND hWnd
, int nIndex
)
612 return (WORD
)GetWindowLongW(hWnd
, nIndex
);
620 SetWindowWord ( HWND hWnd
,int nIndex
,WORD wNewWord
)
622 return (WORD
)NtUserSetWindowLong ( hWnd
, nIndex
, (LONG
)wNewWord
, TRUE
);
635 /* FIXME: Implement correct functionality of RealGetWindowClass */
636 return GetClassNameW(hwnd
,pszType
,cchType
);
650 /* FIXME: Implement correct functionality of RealGetWindowClass */
651 return GetClassNameA(hwnd
,pszType
,cchType
);
655 * Create a small icon based on a standard icon
658 CreateSmallIcon(HICON StdIcon
)
660 HICON SmallIcon
= NULL
;
664 BITMAP StdBitmapInfo
;
666 HDC hSourceDc
= NULL
;
669 HBITMAP OldSourceBitmap
= NULL
;
670 HBITMAP OldDestBitmap
= NULL
;
672 SmallInfo
.hbmColor
= NULL
;
673 SmallInfo
.hbmMask
= NULL
;
675 /* We need something to work with... */
681 SmallIconWidth
= GetSystemMetrics(SM_CXSMICON
);
682 SmallIconHeight
= GetSystemMetrics(SM_CYSMICON
);
683 if (! GetIconInfo(StdIcon
, &StdInfo
))
685 ERR("Failed to get icon info for icon 0x%x\n", StdIcon
);
688 if (! GetObjectW(StdInfo
.hbmMask
, sizeof(BITMAP
), &StdBitmapInfo
))
690 ERR("Failed to get bitmap info for icon 0x%x bitmap 0x%x\n",
691 StdIcon
, StdInfo
.hbmColor
);
694 if (StdBitmapInfo
.bmWidth
== SmallIconWidth
&&
695 StdBitmapInfo
.bmHeight
== SmallIconHeight
)
697 /* Icon already has the correct dimensions */
701 /* Get a handle to a info DC and handles to DCs which can be used to
702 select a bitmap into. This is done to avoid triggering a switch to
703 graphics mode (if we're currently in text/blue screen mode) */
704 hInfoDc
= CreateICW(NULL
, NULL
, NULL
, NULL
);
707 ERR("Failed to create info DC\n");
710 hSourceDc
= CreateCompatibleDC(NULL
);
711 if (NULL
== hSourceDc
)
713 ERR("Failed to create source DC\n");
716 hDestDc
= CreateCompatibleDC(NULL
);
719 ERR("Failed to create dest DC\n");
723 OldSourceBitmap
= SelectObject(hSourceDc
, StdInfo
.hbmColor
);
724 if (NULL
== OldSourceBitmap
)
726 ERR("Failed to select source color bitmap\n");
729 SmallInfo
.hbmColor
= CreateCompatibleBitmap(hInfoDc
, SmallIconWidth
,
731 if (NULL
== SmallInfo
.hbmColor
)
733 ERR("Failed to create color bitmap\n");
736 OldDestBitmap
= SelectObject(hDestDc
, SmallInfo
.hbmColor
);
737 if (NULL
== OldDestBitmap
)
739 ERR("Failed to select dest color bitmap\n");
742 if (! StretchBlt(hDestDc
, 0, 0, SmallIconWidth
, SmallIconHeight
,
743 hSourceDc
, 0, 0, StdBitmapInfo
.bmWidth
,
744 StdBitmapInfo
.bmHeight
, SRCCOPY
))
746 ERR("Failed to stretch color bitmap\n");
750 if (NULL
== SelectObject(hSourceDc
, StdInfo
.hbmMask
))
752 ERR("Failed to select source mask bitmap\n");
755 SmallInfo
.hbmMask
= CreateBitmap(SmallIconWidth
, SmallIconHeight
, 1, 1,
757 if (NULL
== SmallInfo
.hbmMask
)
759 ERR("Failed to create mask bitmap\n");
762 if (NULL
== SelectObject(hDestDc
, SmallInfo
.hbmMask
))
764 ERR("Failed to select dest mask bitmap\n");
767 if (! StretchBlt(hDestDc
, 0, 0, SmallIconWidth
, SmallIconHeight
,
768 hSourceDc
, 0, 0, StdBitmapInfo
.bmWidth
,
769 StdBitmapInfo
.bmHeight
, SRCCOPY
))
771 ERR("Failed to stretch mask bitmap\n");
775 SmallInfo
.fIcon
= TRUE
;
776 SmallInfo
.xHotspot
= SmallIconWidth
/ 2;
777 SmallInfo
.yHotspot
= SmallIconHeight
/ 2;
778 SmallIcon
= CreateIconIndirect(&SmallInfo
);
779 if (NULL
== SmallIcon
)
781 ERR("Failed to create icon\n");
786 if (NULL
!= SmallInfo
.hbmMask
)
788 DeleteObject(SmallInfo
.hbmMask
);
790 if (NULL
!= OldDestBitmap
)
792 SelectObject(hDestDc
, OldDestBitmap
);
794 if (NULL
!= SmallInfo
.hbmColor
)
796 DeleteObject(SmallInfo
.hbmColor
);
802 if (NULL
!= OldSourceBitmap
)
804 SelectObject(hSourceDc
, OldSourceBitmap
);
806 if (NULL
!= hSourceDc
)
820 RegisterClassExWOWW(WNDCLASSEXW
*lpwcx
,
833 RegisterClassExA(CONST WNDCLASSEXA
*lpwcx
)
836 WNDCLASSEXA WndClass
;
837 UNICODE_STRING ClassName
;
838 UNICODE_STRING MenuName
= {0};
841 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXA
) ||
842 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
843 lpwcx
->lpszClassName
== NULL
)
845 SetLastError(ERROR_INVALID_PARAMETER
);
850 * On real Windows this looks more like:
851 * if (lpwcx->hInstance == User32Instance &&
852 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
853 * But since I have no idea what the magic field in the
854 * TEB structure means, I rather decided to omit that.
857 if (lpwcx
->hInstance
== User32Instance
)
859 SetLastError(ERROR_INVALID_PARAMETER
);
863 /* Yes, this is correct. We should modify the passed structure. */
864 if (lpwcx
->hInstance
== NULL
)
865 ((WNDCLASSEXA
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
867 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXA
));
869 if (NULL
== WndClass
.hIconSm
)
871 WndClass
.hIconSm
= CreateSmallIcon(WndClass
.hIcon
);
874 if (WndClass
.lpszMenuName
!= NULL
)
876 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
878 if (WndClass
.lpszMenuName
[0])
880 RtlCreateUnicodeStringFromAsciiz(&MenuName
, WndClass
.lpszMenuName
);
885 MenuName
.Buffer
= (LPWSTR
)WndClass
.lpszMenuName
;
888 if (MenuName
.Buffer
!= NULL
)
889 hMenu
= LoadMenuA(WndClass
.hInstance
, WndClass
.lpszMenuName
);
892 if (IS_ATOM(WndClass
.lpszClassName
))
895 ClassName
.MaximumLength
= 0;
896 ClassName
.Buffer
= (LPWSTR
)WndClass
.lpszClassName
;
900 RtlCreateUnicodeStringFromAsciiz(&ClassName
, WndClass
.lpszClassName
);
903 Atom
= NtUserRegisterClassEx((WNDCLASSEXW
*)&WndClass
,
910 TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
911 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
912 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
914 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
915 RtlFreeUnicodeString(&MenuName
);
916 if (!IS_ATOM(WndClass
.lpszClassName
))
917 RtlFreeUnicodeString(&ClassName
);
926 RegisterClassExW(CONST WNDCLASSEXW
*lpwcx
)
929 WNDCLASSEXW WndClass
;
930 UNICODE_STRING ClassName
;
931 UNICODE_STRING MenuName
= {0};
934 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
935 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
936 lpwcx
->lpszClassName
== NULL
)
938 SetLastError(ERROR_INVALID_PARAMETER
);
943 * On real Windows this looks more like:
944 * if (lpwcx->hInstance == User32Instance &&
945 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
946 * But since I have no idea what the magic field in the
947 * TEB structure means, I rather decided to omit that.
950 if (lpwcx
->hInstance
== User32Instance
)
952 SetLastError(ERROR_INVALID_PARAMETER
);
956 /* Yes, this is correct. We should modify the passed structure. */
957 if (lpwcx
->hInstance
== NULL
)
958 ((WNDCLASSEXW
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
960 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
962 if (NULL
== WndClass
.hIconSm
)
964 WndClass
.hIconSm
= CreateSmallIcon(WndClass
.hIcon
);
967 if (WndClass
.lpszMenuName
!= NULL
)
969 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
971 if (WndClass
.lpszMenuName
[0])
973 RtlInitUnicodeString(&MenuName
, WndClass
.lpszMenuName
);
978 MenuName
.Buffer
= (LPWSTR
)WndClass
.lpszMenuName
;
981 if (MenuName
.Buffer
!= NULL
)
982 hMenu
= LoadMenuW(WndClass
.hInstance
, WndClass
.lpszMenuName
);
985 if (IS_ATOM(WndClass
.lpszClassName
))
988 ClassName
.MaximumLength
= 0;
989 ClassName
.Buffer
= (LPWSTR
)WndClass
.lpszClassName
;
993 RtlInitUnicodeString(&ClassName
, WndClass
.lpszClassName
);
996 Atom
= (ATOM
)NtUserRegisterClassEx(&WndClass
,
1003 TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
1004 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
1005 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
1014 RegisterClassA(CONST WNDCLASSA
*lpWndClass
)
1018 if (lpWndClass
== NULL
)
1021 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSA
));
1022 Class
.cbSize
= sizeof(WNDCLASSEXA
);
1023 Class
.hIconSm
= NULL
;
1025 return RegisterClassExA(&Class
);
1032 RegisterClassW(CONST WNDCLASSW
*lpWndClass
)
1036 if (lpWndClass
== NULL
)
1039 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSW
));
1040 Class
.cbSize
= sizeof(WNDCLASSEXW
);
1041 Class
.hIconSm
= NULL
;
1043 return RegisterClassExW(&Class
);
1051 SetClassLongA (HWND hWnd
,
1055 PSTR lpStr
= (PSTR
)dwNewLong
;
1056 UNICODE_STRING Value
= {0};
1057 BOOL Allocated
= FALSE
;
1060 TRACE("%p %d %lx\n", hWnd
, nIndex
, dwNewLong
);
1062 /* FIXME - portability!!!! */
1064 if (nIndex
== GCL_MENUNAME
&& lpStr
!= NULL
)
1066 if (!IS_INTRESOURCE(lpStr
))
1068 if (!RtlCreateUnicodeStringFromAsciiz(&Value
,
1071 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1078 Value
.Buffer
= (PWSTR
)lpStr
;
1080 dwNewLong
= (LONG
)&Value
;
1082 else if (nIndex
== GCW_ATOM
&& lpStr
!= NULL
)
1084 if (!IS_ATOM(lpStr
))
1086 if (!RtlCreateUnicodeStringFromAsciiz(&Value
,
1089 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1096 Value
.Buffer
= (PWSTR
)lpStr
;
1098 dwNewLong
= (LONG
)&Value
;
1101 Ret
= (DWORD
)NtUserSetClassLong(hWnd
,
1108 RtlFreeUnicodeString(&Value
);
1120 SetClassLongW(HWND hWnd
,
1124 PWSTR lpStr
= (PWSTR
)dwNewLong
;
1125 UNICODE_STRING Value
= {0};
1127 TRACE("%p %d %lx\n", hWnd
, nIndex
, dwNewLong
);
1129 /* FIXME - portability!!!! */
1131 if (nIndex
== GCL_MENUNAME
&& lpStr
!= NULL
)
1133 if (!IS_INTRESOURCE(lpStr
))
1135 RtlInitUnicodeString(&Value
,
1139 Value
.Buffer
= lpStr
;
1141 dwNewLong
= (LONG
)&Value
;
1143 else if (nIndex
== GCW_ATOM
&& lpStr
!= NULL
)
1145 if (!IS_ATOM(lpStr
))
1147 RtlInitUnicodeString(&Value
,
1151 Value
.Buffer
= lpStr
;
1153 dwNewLong
= (LONG
)&Value
;
1156 return (DWORD
)NtUserSetClassLong(hWnd
,
1173 * NOTE: Obsoleted in 32-bit windows
1176 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
1179 return (WORD
) SetClassLongW ( hWnd
, nIndex
, wNewWord
);
1193 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, TRUE
);
1207 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
1218 HINSTANCE hInstance
)
1220 UNICODE_STRING ClassName
= {0};
1223 TRACE("class/atom: %s/%04x %p\n",
1224 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
1225 IS_ATOM(lpClassName
) ? lpClassName
: 0,
1228 if (!IS_ATOM(lpClassName
))
1230 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
,
1233 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1238 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpClassName
);
1240 Ret
= NtUserUnregisterClass(&ClassName
,
1244 if (!IS_ATOM(lpClassName
))
1245 RtlFreeUnicodeString(&ClassName
);
1257 LPCWSTR lpClassName
,
1258 HINSTANCE hInstance
)
1260 UNICODE_STRING ClassName
= {0};
1262 TRACE("class/atom: %S/%04x %p\n",
1263 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
1264 IS_ATOM(lpClassName
) ? lpClassName
: 0,
1267 if (!IS_ATOM(lpClassName
))
1269 RtlInitUnicodeString(&ClassName
,
1273 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpClassName
);
1275 return NtUserUnregisterClass(&ClassName
,