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};
30 TRACE("%p class/atom: %s/%04x %p\n", hInstance
,
31 IS_ATOM(lpszClass
) ? NULL
: lpszClass
,
32 IS_ATOM(lpszClass
) ? lpszClass
: 0,
35 //HACKHACK: This is ROS-specific and should go away
36 lpwcx
->cbSize
= sizeof(*lpwcx
);
38 if (hInstance
== User32Instance
)
43 if (lpszClass
== NULL
)
45 SetLastError(ERROR_INVALID_PARAMETER
);
49 if (IS_ATOM(lpszClass
))
51 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpszClass
);
55 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
,
58 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
63 Ret
= NtUserGetClassInfo(hInstance
,
66 (LPWSTR
*)&pszMenuName
,
70 lpwcx
->lpszClassName
= lpszClass
;
71 // lpwcx->lpszMenuName = pszMenuName;
74 if (!IS_ATOM(lpszClass
))
76 RtlFreeUnicodeString(&ClassName
);
93 UNICODE_STRING ClassName
= {0};
97 TRACE("%p class/atom: %S/%04x %p\n", hInstance
,
98 IS_ATOM(lpszClass
) ? NULL
: lpszClass
,
99 IS_ATOM(lpszClass
) ? lpszClass
: 0,
102 //HACKHACK: This is ROS-specific and should go away
103 lpwcx
->cbSize
= sizeof(*lpwcx
);
105 if (hInstance
== User32Instance
)
110 if (lpszClass
== NULL
)
112 SetLastError(ERROR_INVALID_PARAMETER
);
116 if (IS_ATOM(lpszClass
))
118 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpszClass
);
122 RtlInitUnicodeString(&ClassName
,
126 Ret
= NtUserGetClassInfo( hInstance
,
133 lpwcx
->lpszClassName
= lpszClass
;
134 // lpwcx->lpszMenuName = pszMenuName;
148 LPWNDCLASSA lpWndClass
)
153 retval
= GetClassInfoExA(hInstance
, lpClassName
, &wcex
);
156 lpWndClass
->style
= wcex
.style
;
157 lpWndClass
->lpfnWndProc
= wcex
.lpfnWndProc
;
158 lpWndClass
->cbClsExtra
= wcex
.cbClsExtra
;
159 lpWndClass
->cbWndExtra
= wcex
.cbWndExtra
;
160 lpWndClass
->hInstance
= wcex
.hInstance
;
161 lpWndClass
->hIcon
= wcex
.hIcon
;
162 lpWndClass
->hCursor
= wcex
.hCursor
;
163 lpWndClass
->hbrBackground
= wcex
.hbrBackground
;
164 lpWndClass
->lpszMenuName
= wcex
.lpszMenuName
;
165 lpWndClass
->lpszClassName
= wcex
.lpszClassName
;
179 LPWNDCLASSW lpWndClass
)
184 retval
= GetClassInfoExW(hInstance
, lpClassName
, &wcex
);
187 lpWndClass
->style
= wcex
.style
;
188 lpWndClass
->lpfnWndProc
= wcex
.lpfnWndProc
;
189 lpWndClass
->cbClsExtra
= wcex
.cbClsExtra
;
190 lpWndClass
->cbWndExtra
= wcex
.cbWndExtra
;
191 lpWndClass
->hInstance
= wcex
.hInstance
;
192 lpWndClass
->hIcon
= wcex
.hIcon
;
193 lpWndClass
->hCursor
= wcex
.hCursor
;
194 lpWndClass
->hbrBackground
= wcex
.hbrBackground
;
195 lpWndClass
->lpszMenuName
= wcex
.lpszMenuName
;
196 lpWndClass
->lpszClassName
= wcex
.lpszClassName
;
205 GetClassLongA(HWND hWnd
, int nIndex
)
211 TRACE("%p %d\n", hWnd
, nIndex
);
213 Wnd
= ValidateHwnd(hWnd
);
219 Class
= DesktopPtrToUser(Wnd
->pcls
);
224 if (nIndex
+ sizeof(ULONG_PTR
) < nIndex
||
225 nIndex
+ sizeof(ULONG_PTR
) > Class
->cbclsExtra
)
227 SetLastError(ERROR_INVALID_PARAMETER
);
230 Ret
= *(PULONG_PTR
)((ULONG_PTR
)(Class
+ 1) + nIndex
);
237 Ret
= (ULONG_PTR
)Class
->cbwndExtra
;
241 Ret
= (ULONG_PTR
)Class
->cbclsExtra
;
244 case GCL_HBRBACKGROUND
:
245 Ret
= (ULONG_PTR
)Class
->hbrBackground
;
246 if (Ret
!= 0 && Ret
< 0x4000)
247 Ret
= (ULONG_PTR
)GetSysColorBrush((ULONG
)Ret
- 1);
251 Ret
= (ULONG_PTR
)Class
->hModule
;
255 Ret
= (ULONG_PTR
)Class
->lpszClientAnsiMenuName
;
259 Ret
= (ULONG_PTR
)Class
->style
;
263 Ret
= (ULONG_PTR
)Class
->atomClassName
;
267 /* FIXME - get handle from pointer to CURSOR object */
268 Ret
= (ULONG_PTR
)Class
->hCursor
;
272 /* FIXME - get handle from pointer to ICON object */
273 Ret
= (ULONG_PTR
)Class
->hIcon
;
277 /* FIXME - get handle from pointer to ICON object */
278 Ret
= (ULONG_PTR
)Class
->hIconSm
;
282 /* We need to make a call to win32k as it may be required to
283 create a callproc handle */
288 SetLastError(ERROR_INVALID_INDEX
);
295 /* This is a race condition! Call win32k to make sure we're getting
296 the correct result */
297 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
299 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
302 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
304 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
309 Ret
= NtUserGetClassLong(hWnd
, nIndex
, TRUE
);
318 GetClassLongW ( HWND hWnd
, int nIndex
)
324 TRACE("%p %d\n", hWnd
, nIndex
);
326 Wnd
= ValidateHwnd(hWnd
);
332 Class
= DesktopPtrToUser(Wnd
->pcls
);
337 if (nIndex
+ sizeof(ULONG_PTR
) < nIndex
||
338 nIndex
+ sizeof(ULONG_PTR
) > Class
->cbclsExtra
)
340 SetLastError(ERROR_INVALID_PARAMETER
);
343 Ret
= *(PULONG_PTR
)((ULONG_PTR
)(Class
+ 1) + nIndex
);
350 Ret
= (ULONG_PTR
)Class
->cbwndExtra
;
354 Ret
= (ULONG_PTR
)Class
->cbclsExtra
;
357 case GCL_HBRBACKGROUND
:
358 Ret
= (ULONG_PTR
)Class
->hbrBackground
;
359 if (Ret
!= 0 && Ret
< 0x4000)
360 Ret
= (ULONG_PTR
)GetSysColorBrush((ULONG
)Ret
- 1);
364 Ret
= (ULONG_PTR
)Class
->hModule
;
368 Ret
= (ULONG_PTR
)Class
->lpszClientUnicodeMenuName
;
372 Ret
= (ULONG_PTR
)Class
->style
;
376 Ret
= (ULONG_PTR
)Class
->atomClassName
;
380 /* FIXME - get handle from pointer to CURSOR object */
381 Ret
= (ULONG_PTR
)Class
->hCursor
;
385 /* FIXME - get handle from pointer to ICON object */
386 Ret
= (ULONG_PTR
)Class
->hIcon
;
390 /* FIXME - get handle from pointer to ICON object */
391 Ret
= (ULONG_PTR
)Class
->hIconSm
;
395 /* We need to make a call to win32k as it may be required to
396 create a callproc handle */
401 SetLastError(ERROR_INVALID_INDEX
);
408 /* This is a race condition! Call win32k to make sure we're getting
409 the correct result */
410 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
412 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
415 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
417 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
422 Ret
= NtUserGetClassLong(hWnd
, nIndex
, FALSE
);
437 ANSI_STRING ClassName
;
440 ClassName
.MaximumLength
= nMaxCount
;
441 ClassName
.Buffer
= lpClassName
;
443 Result
= NtUserGetClassName(hWnd
,
444 (PUNICODE_STRING
)&ClassName
,
447 TRACE("%p class/atom: %s/%04x %x\n", hWnd
,
448 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
449 IS_ATOM(lpClassName
) ? lpClassName
: 0,
466 UNICODE_STRING ClassName
;
469 ClassName
.MaximumLength
= nMaxCount
* sizeof(WCHAR
);
470 ClassName
.Buffer
= lpClassName
;
472 Result
= NtUserGetClassName(hWnd
,
476 TRACE("%p class/atom: %S/%04x %x\n", hWnd
,
477 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
478 IS_ATOM(lpClassName
) ? lpClassName
: 0,
494 * NOTE: Obsoleted in 32-bit windows
497 TRACE("%p %x\n", hWnd
, nIndex
);
499 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
502 return (WORD
) NtUserGetClassLong ( hWnd
, nIndex
, TRUE
);
511 GetWindowLongA ( HWND hWnd
, int nIndex
)
515 Wnd
= ValidateHwnd(hWnd
);
521 if ((DWORD
)nIndex
+ sizeof(LONG
) > Wnd
->cbwndExtra
)
523 SetLastError(ERROR_INVALID_PARAMETER
);
527 return *((LONG
*)((PCHAR
)(Wnd
+ 1) + nIndex
));
538 return (LONG
)Wnd
->hModule
;
542 return Wnd
->dwUserData
;
546 HWND parent
= GetAncestor( hWnd
, GA_PARENT
);
547 if (parent
== GetDesktopWindow()) parent
= GetWindow( hWnd
, GW_OWNER
);
551 /* Call win32k for this as a callproc handle may need
553 return NtUserGetWindowLong(hWnd
, nIndex
, TRUE
);
556 SetLastError(ERROR_INVALID_PARAMETER
);
568 GetWindowLongW(HWND hWnd
, int nIndex
)
572 Wnd
= ValidateHwnd(hWnd
);
578 if ((DWORD
)nIndex
+ sizeof(LONG
) > Wnd
->cbwndExtra
)
580 SetLastError(ERROR_INVALID_PARAMETER
);
584 return *((LONG
*)((PCHAR
)(Wnd
+ 1) + nIndex
));
595 return (LONG
)Wnd
->hModule
;
599 return Wnd
->dwUserData
;
603 HWND parent
= GetAncestor( hWnd
, GA_PARENT
);
604 if (parent
== GetDesktopWindow()) parent
= GetWindow( hWnd
, GW_OWNER
);
608 /* Call win32k for this as a callproc handle may need
610 return NtUserGetWindowLong(hWnd
, nIndex
, FALSE
);
613 SetLastError(ERROR_INVALID_PARAMETER
);
624 GetWindowWord(HWND hWnd
, int nIndex
)
626 return (WORD
)GetWindowLongW(hWnd
, nIndex
);
634 SetWindowWord ( HWND hWnd
,int nIndex
,WORD wNewWord
)
636 return (WORD
)NtUserSetWindowLong ( hWnd
, nIndex
, (LONG
)wNewWord
, TRUE
);
649 /* FIXME: Implement correct functionality of RealGetWindowClass */
650 return GetClassNameW(hwnd
,pszType
,cchType
);
664 /* FIXME: Implement correct functionality of RealGetWindowClass */
665 return GetClassNameA(hwnd
,pszType
,cchType
);
669 * Create a small icon based on a standard icon
672 CreateSmallIcon(HICON StdIcon
)
674 HICON SmallIcon
= NULL
;
678 BITMAP StdBitmapInfo
;
680 HDC hSourceDc
= NULL
;
683 HBITMAP OldSourceBitmap
= NULL
;
684 HBITMAP OldDestBitmap
= NULL
;
686 SmallInfo
.hbmColor
= NULL
;
687 SmallInfo
.hbmMask
= NULL
;
689 /* We need something to work with... */
695 SmallIconWidth
= GetSystemMetrics(SM_CXSMICON
);
696 SmallIconHeight
= GetSystemMetrics(SM_CYSMICON
);
697 if (! GetIconInfo(StdIcon
, &StdInfo
))
699 ERR("Failed to get icon info for icon 0x%x\n", StdIcon
);
702 if (! GetObjectW(StdInfo
.hbmMask
, sizeof(BITMAP
), &StdBitmapInfo
))
704 ERR("Failed to get bitmap info for icon 0x%x bitmap 0x%x\n",
705 StdIcon
, StdInfo
.hbmColor
);
708 if (StdBitmapInfo
.bmWidth
== SmallIconWidth
&&
709 StdBitmapInfo
.bmHeight
== SmallIconHeight
)
711 /* Icon already has the correct dimensions */
715 /* Get a handle to a info DC and handles to DCs which can be used to
716 select a bitmap into. This is done to avoid triggering a switch to
717 graphics mode (if we're currently in text/blue screen mode) */
718 hInfoDc
= CreateICW(NULL
, NULL
, NULL
, NULL
);
721 ERR("Failed to create info DC\n");
724 hSourceDc
= CreateCompatibleDC(NULL
);
725 if (NULL
== hSourceDc
)
727 ERR("Failed to create source DC\n");
730 hDestDc
= CreateCompatibleDC(NULL
);
733 ERR("Failed to create dest DC\n");
737 OldSourceBitmap
= SelectObject(hSourceDc
, StdInfo
.hbmColor
);
738 if (NULL
== OldSourceBitmap
)
740 ERR("Failed to select source color bitmap\n");
743 SmallInfo
.hbmColor
= CreateCompatibleBitmap(hInfoDc
, SmallIconWidth
,
745 if (NULL
== SmallInfo
.hbmColor
)
747 ERR("Failed to create color bitmap\n");
750 OldDestBitmap
= SelectObject(hDestDc
, SmallInfo
.hbmColor
);
751 if (NULL
== OldDestBitmap
)
753 ERR("Failed to select dest color bitmap\n");
756 if (! StretchBlt(hDestDc
, 0, 0, SmallIconWidth
, SmallIconHeight
,
757 hSourceDc
, 0, 0, StdBitmapInfo
.bmWidth
,
758 StdBitmapInfo
.bmHeight
, SRCCOPY
))
760 ERR("Failed to stretch color bitmap\n");
764 if (NULL
== SelectObject(hSourceDc
, StdInfo
.hbmMask
))
766 ERR("Failed to select source mask bitmap\n");
769 SmallInfo
.hbmMask
= CreateBitmap(SmallIconWidth
, SmallIconHeight
, 1, 1,
771 if (NULL
== SmallInfo
.hbmMask
)
773 ERR("Failed to create mask bitmap\n");
776 if (NULL
== SelectObject(hDestDc
, SmallInfo
.hbmMask
))
778 ERR("Failed to select dest mask bitmap\n");
781 if (! StretchBlt(hDestDc
, 0, 0, SmallIconWidth
, SmallIconHeight
,
782 hSourceDc
, 0, 0, StdBitmapInfo
.bmWidth
,
783 StdBitmapInfo
.bmHeight
, SRCCOPY
))
785 ERR("Failed to stretch mask bitmap\n");
789 SmallInfo
.fIcon
= TRUE
;
790 SmallInfo
.xHotspot
= SmallIconWidth
/ 2;
791 SmallInfo
.yHotspot
= SmallIconHeight
/ 2;
792 SmallIcon
= CreateIconIndirect(&SmallInfo
);
793 if (NULL
== SmallIcon
)
795 ERR("Failed to create icon\n");
800 if (NULL
!= SmallInfo
.hbmMask
)
802 DeleteObject(SmallInfo
.hbmMask
);
804 if (NULL
!= OldDestBitmap
)
806 SelectObject(hDestDc
, OldDestBitmap
);
808 if (NULL
!= SmallInfo
.hbmColor
)
810 DeleteObject(SmallInfo
.hbmColor
);
816 if (NULL
!= OldSourceBitmap
)
818 SelectObject(hSourceDc
, OldSourceBitmap
);
820 if (NULL
!= hSourceDc
)
834 RegisterClassExWOWW(WNDCLASSEXW
*lpwcx
,
840 WNDCLASSEXW WndClass
;
841 UNICODE_STRING ClassName
;
842 UNICODE_STRING MenuName
= {0};
843 CLSMENUNAME clsMenuName
;
844 ANSI_STRING AnsiMenuName
;
846 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
847 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
848 lpwcx
->lpszClassName
== NULL
)
850 SetLastError(ERROR_INVALID_PARAMETER
);
854 if (lpwcx
->hInstance
== User32Instance
)
856 SetLastError(ERROR_INVALID_PARAMETER
);
860 /* Yes, this is correct. We should modify the passed structure. */
861 if (lpwcx
->hInstance
== NULL
)
862 ((WNDCLASSEXW
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
864 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
866 if (NULL
== WndClass
.hIconSm
)
868 WndClass
.hIconSm
= CreateSmallIcon(WndClass
.hIcon
);
871 if (WndClass
.lpszMenuName
!= NULL
)
873 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
875 if (WndClass
.lpszMenuName
[0])
877 RtlInitUnicodeString(&MenuName
, WndClass
.lpszMenuName
);
882 MenuName
.Buffer
= (LPWSTR
)WndClass
.lpszMenuName
;
886 if (IS_ATOM(WndClass
.lpszClassName
))
889 ClassName
.MaximumLength
= 0;
890 ClassName
.Buffer
= (LPWSTR
)WndClass
.lpszClassName
;
894 RtlInitUnicodeString(&ClassName
, WndClass
.lpszClassName
);
897 RtlUnicodeStringToAnsiString( &AnsiMenuName
, &MenuName
, TRUE
);
899 clsMenuName
.pszClientAnsiMenuName
= AnsiMenuName
.Buffer
;
900 clsMenuName
.pwszClientUnicodeMenuName
= MenuName
.Buffer
;
901 clsMenuName
.pusMenuName
= &MenuName
;
903 Atom
= NtUserRegisterClassExWOW( &WndClass
,
905 NULL
, //PUNICODE_STRING ClsNVersion,
911 TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
912 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
913 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
922 RegisterClassExA(CONST WNDCLASSEXA
*lpwcx
)
925 WNDCLASSEXA WndClass
;
926 UNICODE_STRING ClassName
;
927 UNICODE_STRING MenuName
= {0};
928 CLSMENUNAME clsMenuName
;
929 ANSI_STRING AnsiMenuName
;
931 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXA
) ||
932 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
933 lpwcx
->lpszClassName
== NULL
)
935 SetLastError(ERROR_INVALID_PARAMETER
);
939 if (lpwcx
->hInstance
== User32Instance
)
941 SetLastError(ERROR_INVALID_PARAMETER
);
945 /* Yes, this is correct. We should modify the passed structure. */
946 if (lpwcx
->hInstance
== NULL
)
947 ((WNDCLASSEXA
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
949 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXA
));
951 if (NULL
== WndClass
.hIconSm
)
953 WndClass
.hIconSm
= CreateSmallIcon(WndClass
.hIcon
);
956 if (WndClass
.lpszMenuName
!= NULL
)
958 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
960 if (WndClass
.lpszMenuName
[0])
962 RtlCreateUnicodeStringFromAsciiz(&MenuName
, WndClass
.lpszMenuName
);
967 MenuName
.Buffer
= (LPWSTR
)WndClass
.lpszMenuName
;
971 if (IS_ATOM(WndClass
.lpszClassName
))
974 ClassName
.MaximumLength
= 0;
975 ClassName
.Buffer
= (LPWSTR
)WndClass
.lpszClassName
;
979 RtlCreateUnicodeStringFromAsciiz(&ClassName
, WndClass
.lpszClassName
);
982 RtlUnicodeStringToAnsiString( &AnsiMenuName
, &MenuName
, TRUE
);
984 clsMenuName
.pszClientAnsiMenuName
= AnsiMenuName
.Buffer
;
985 clsMenuName
.pwszClientUnicodeMenuName
= MenuName
.Buffer
;
986 clsMenuName
.pusMenuName
= &MenuName
;
988 Atom
= NtUserRegisterClassExWOW( (WNDCLASSEXW
*)&WndClass
,
990 NULL
, //PUNICODE_STRING ClsNVersion,
996 TRACE("A atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
997 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
998 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
1000 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
1002 RtlFreeUnicodeString(&MenuName
);
1003 RtlFreeAnsiString(&AnsiMenuName
);
1005 if (!IS_ATOM(WndClass
.lpszClassName
))
1006 RtlFreeUnicodeString(&ClassName
);
1015 RegisterClassExW(CONST WNDCLASSEXW
*lpwcx
)
1018 WNDCLASSEXW WndClass
;
1019 UNICODE_STRING ClassName
;
1020 UNICODE_STRING MenuName
= {0};
1021 CLSMENUNAME clsMenuName
;
1022 ANSI_STRING AnsiMenuName
;
1024 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
1025 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
1026 lpwcx
->lpszClassName
== NULL
)
1028 SetLastError(ERROR_INVALID_PARAMETER
);
1033 * On real Windows this looks more like:
1034 * if (lpwcx->hInstance == User32Instance &&
1035 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
1036 * But since I have no idea what the magic field in the
1037 * TEB structure means, I rather decided to omit that.
1040 GetWin32ClientInfo()->ulWindowsVersion & (WINVER == 400)
1042 if (lpwcx
->hInstance
== User32Instance
)
1044 SetLastError(ERROR_INVALID_PARAMETER
);
1048 /* Yes, this is correct. We should modify the passed structure. */
1049 if (lpwcx
->hInstance
== NULL
)
1050 ((WNDCLASSEXW
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
1052 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
1054 if (NULL
== WndClass
.hIconSm
)
1056 WndClass
.hIconSm
= CreateSmallIcon(WndClass
.hIcon
);
1059 if (WndClass
.lpszMenuName
!= NULL
)
1061 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
1063 if (WndClass
.lpszMenuName
[0])
1065 RtlInitUnicodeString(&MenuName
, WndClass
.lpszMenuName
);
1070 MenuName
.Buffer
= (LPWSTR
)WndClass
.lpszMenuName
;
1074 if (IS_ATOM(WndClass
.lpszClassName
))
1077 ClassName
.MaximumLength
= 0;
1078 ClassName
.Buffer
= (LPWSTR
)WndClass
.lpszClassName
;
1082 RtlInitUnicodeString(&ClassName
, WndClass
.lpszClassName
);
1085 RtlUnicodeStringToAnsiString( &AnsiMenuName
, &MenuName
, TRUE
);
1087 clsMenuName
.pszClientAnsiMenuName
= AnsiMenuName
.Buffer
;
1088 clsMenuName
.pwszClientUnicodeMenuName
= MenuName
.Buffer
;
1089 clsMenuName
.pusMenuName
= &MenuName
;
1091 Atom
= NtUserRegisterClassExWOW( &WndClass
,
1093 NULL
, //PUNICODE_STRING ClsNVersion,
1099 TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
1100 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
1101 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
1110 RegisterClassA(CONST WNDCLASSA
*lpWndClass
)
1114 if (lpWndClass
== NULL
)
1117 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSA
));
1118 Class
.cbSize
= sizeof(WNDCLASSEXA
);
1119 Class
.hIconSm
= NULL
;
1121 return RegisterClassExA(&Class
);
1128 RegisterClassW(CONST WNDCLASSW
*lpWndClass
)
1132 if (lpWndClass
== NULL
)
1135 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSW
));
1136 Class
.cbSize
= sizeof(WNDCLASSEXW
);
1137 Class
.hIconSm
= NULL
;
1139 return RegisterClassExW(&Class
);
1147 SetClassLongA (HWND hWnd
,
1151 PSTR lpStr
= (PSTR
)dwNewLong
;
1152 UNICODE_STRING Value
= {0};
1153 BOOL Allocated
= FALSE
;
1156 TRACE("%p %d %lx\n", hWnd
, nIndex
, dwNewLong
);
1158 /* FIXME - portability!!!! */
1160 if (nIndex
== GCL_MENUNAME
&& lpStr
!= NULL
)
1162 if (!IS_INTRESOURCE(lpStr
))
1164 if (!RtlCreateUnicodeStringFromAsciiz(&Value
,
1167 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1174 Value
.Buffer
= (PWSTR
)lpStr
;
1176 dwNewLong
= (LONG
)&Value
;
1178 else if (nIndex
== GCW_ATOM
&& lpStr
!= NULL
)
1180 if (!IS_ATOM(lpStr
))
1182 if (!RtlCreateUnicodeStringFromAsciiz(&Value
,
1185 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1192 Value
.Buffer
= (PWSTR
)lpStr
;
1194 dwNewLong
= (LONG
)&Value
;
1197 Ret
= (DWORD
)NtUserSetClassLong(hWnd
,
1204 RtlFreeUnicodeString(&Value
);
1216 SetClassLongW(HWND hWnd
,
1220 PWSTR lpStr
= (PWSTR
)dwNewLong
;
1221 UNICODE_STRING Value
= {0};
1223 TRACE("%p %d %lx\n", hWnd
, nIndex
, dwNewLong
);
1225 /* FIXME - portability!!!! */
1227 if (nIndex
== GCL_MENUNAME
&& lpStr
!= NULL
)
1229 if (!IS_INTRESOURCE(lpStr
))
1231 RtlInitUnicodeString(&Value
,
1235 Value
.Buffer
= lpStr
;
1237 dwNewLong
= (LONG
)&Value
;
1239 else if (nIndex
== GCW_ATOM
&& lpStr
!= NULL
)
1241 if (!IS_ATOM(lpStr
))
1243 RtlInitUnicodeString(&Value
,
1247 Value
.Buffer
= lpStr
;
1249 dwNewLong
= (LONG
)&Value
;
1252 return (DWORD
)NtUserSetClassLong(hWnd
,
1269 * NOTE: Obsoleted in 32-bit windows
1272 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
1275 return (WORD
) SetClassLongW ( hWnd
, nIndex
, wNewWord
);
1289 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, TRUE
);
1303 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
1314 HINSTANCE hInstance
)
1316 UNICODE_STRING ClassName
= {0};
1319 TRACE("class/atom: %s/%04x %p\n",
1320 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
1321 IS_ATOM(lpClassName
) ? lpClassName
: 0,
1324 if (!IS_ATOM(lpClassName
))
1326 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
,
1329 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1334 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpClassName
);
1336 Ret
= NtUserUnregisterClass(&ClassName
,
1340 if (!IS_ATOM(lpClassName
))
1341 RtlFreeUnicodeString(&ClassName
);
1353 LPCWSTR lpClassName
,
1354 HINSTANCE hInstance
)
1356 UNICODE_STRING ClassName
= {0};
1358 TRACE("class/atom: %S/%04x %p\n",
1359 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
1360 IS_ATOM(lpClassName
) ? lpClassName
: 0,
1363 if (!IS_ATOM(lpClassName
))
1365 RtlInitUnicodeString(&ClassName
,
1369 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpClassName
);
1371 return NtUserUnregisterClass(&ClassName
,