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,
37 SetLastError( ERROR_NOACCESS
);
41 if (hInstance
== User32Instance
)
46 if (lpszClass
== NULL
)
48 SetLastError(ERROR_INVALID_PARAMETER
);
52 if (!RegisterDefaultClasses
)
54 ERR("GetClassInfoExA RegisterSystemControls\n");
55 RegisterSystemControls();
58 if (IS_ATOM(lpszClass
))
60 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpszClass
);
64 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
,
67 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
72 Ret
= NtUserGetClassInfo(hInstance
,
75 (LPWSTR
*)&pszMenuName
,
79 lpwcx
->lpszClassName
= lpszClass
;
80 // lpwcx->lpszMenuName = pszMenuName;
83 if (!IS_ATOM(lpszClass
))
85 RtlFreeUnicodeString(&ClassName
);
102 UNICODE_STRING ClassName
= {0};
106 TRACE("%p class/atom: %S/%04x %p\n", hInstance
,
107 IS_ATOM(lpszClass
) ? NULL
: lpszClass
,
108 IS_ATOM(lpszClass
) ? lpszClass
: 0,
111 /* From wine, for speed only, ReactOS supports the correct return in
112 * Win32k. cbSize is ignored.
116 SetLastError( ERROR_NOACCESS
);
120 if (hInstance
== User32Instance
)
125 if (lpszClass
== NULL
)
127 SetLastError(ERROR_INVALID_PARAMETER
);
131 if (!RegisterDefaultClasses
)
133 ERR("GetClassInfoExW RegisterSystemControls\n");
134 RegisterSystemControls();
137 if (IS_ATOM(lpszClass
))
139 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpszClass
);
143 RtlInitUnicodeString(&ClassName
,
147 Ret
= NtUserGetClassInfo( hInstance
,
154 lpwcx
->lpszClassName
= lpszClass
;
155 // lpwcx->lpszMenuName = pszMenuName;
169 LPWNDCLASSA lpWndClass
)
174 retval
= GetClassInfoExA(hInstance
, lpClassName
, &wcex
);
177 lpWndClass
->style
= wcex
.style
;
178 lpWndClass
->lpfnWndProc
= wcex
.lpfnWndProc
;
179 lpWndClass
->cbClsExtra
= wcex
.cbClsExtra
;
180 lpWndClass
->cbWndExtra
= wcex
.cbWndExtra
;
181 lpWndClass
->hInstance
= wcex
.hInstance
;
182 lpWndClass
->hIcon
= wcex
.hIcon
;
183 lpWndClass
->hCursor
= wcex
.hCursor
;
184 lpWndClass
->hbrBackground
= wcex
.hbrBackground
;
185 lpWndClass
->lpszMenuName
= wcex
.lpszMenuName
;
186 lpWndClass
->lpszClassName
= wcex
.lpszClassName
;
200 LPWNDCLASSW lpWndClass
)
205 retval
= GetClassInfoExW(hInstance
, lpClassName
, &wcex
);
208 lpWndClass
->style
= wcex
.style
;
209 lpWndClass
->lpfnWndProc
= wcex
.lpfnWndProc
;
210 lpWndClass
->cbClsExtra
= wcex
.cbClsExtra
;
211 lpWndClass
->cbWndExtra
= wcex
.cbWndExtra
;
212 lpWndClass
->hInstance
= wcex
.hInstance
;
213 lpWndClass
->hIcon
= wcex
.hIcon
;
214 lpWndClass
->hCursor
= wcex
.hCursor
;
215 lpWndClass
->hbrBackground
= wcex
.hbrBackground
;
216 lpWndClass
->lpszMenuName
= wcex
.lpszMenuName
;
217 lpWndClass
->lpszClassName
= wcex
.lpszClassName
;
223 // Based on find_winproc... Fixes many whine tests......
226 IntGetClsWndProc(PWND pWnd
, PCLS Class
, BOOL Ansi
)
229 ULONG_PTR gcpd
, Ret
= 0;
230 // If server side, sweep through proc list and return the client side proc.
231 if (Class
->CSF_flags
& CSF_SERVERSIDEPROC
)
232 { // Always scan through the list due to wine class "deftest".
233 for ( i
= FNID_FIRST
; i
<= FNID_SWITCH
; i
++)
235 if (GETPFNSERVER(i
) == Class
->lpfnWndProc
)
238 Ret
= (ULONG_PTR
)GETPFNCLIENTA(i
);
240 Ret
= (ULONG_PTR
)GETPFNCLIENTW(i
);
246 Ret
= (ULONG_PTR
)Class
->lpfnWndProc
;
247 // Return the proc if one of the FnId default class type.
248 if (Class
->fnid
<= FNID_GHOST
&& Class
->fnid
>= FNID_BUTTON
)
251 { // If match return the right proc by type.
252 if (GETPFNCLIENTW(Class
->fnid
) == Class
->lpfnWndProc
)
253 Ret
= (ULONG_PTR
)GETPFNCLIENTA(Class
->fnid
);
257 if (GETPFNCLIENTA(Class
->fnid
) == Class
->lpfnWndProc
)
258 Ret
= (ULONG_PTR
)GETPFNCLIENTW(Class
->fnid
);
261 // Return on change or Ansi/Unicode proc equal.
262 if ( Ret
!= (ULONG_PTR
)Class
->lpfnWndProc
||
263 Ansi
== !!(Class
->CSF_flags
& CSF_ANSIPROC
) )
266 /* We have an Ansi and Unicode swap! If Ansi create Unicode proc handle.
267 This will force CallWindowProc to deal with it. */
268 gcpd
= NtUserGetCPD( UserHMGetHandle(pWnd
),
269 (Ansi
? UserGetCPDA2U
: UserGetCPDU2A
)|UserGetCPDWndtoCls
,
272 return (gcpd
? gcpd
: Ret
);
276 // Based on IntGetClsWndProc
279 IntGetWndProc(PWND pWnd
, BOOL Ansi
)
282 WNDPROC gcpd
, Ret
= 0;
283 PCLS Class
= DesktopPtrToUser(pWnd
->pcls
);
285 if (!Class
) return Ret
;
287 if (pWnd
->state
& WNDS_SERVERSIDEWINDOWPROC
)
289 for ( i
= FNID_FIRST
; i
<= FNID_SWITCH
; i
++)
291 if (GETPFNSERVER(i
) == pWnd
->lpfnWndProc
)
294 Ret
= GETPFNCLIENTA(i
);
296 Ret
= GETPFNCLIENTW(i
);
302 /* Edit controls are special - they return a wndproc handle when
303 GetWindowLongPtr is called with a different A/W.
304 On the other hand there is no W->A->W conversion so this control
305 is treated specially.
307 if (Class
->fnid
== FNID_EDIT
)
308 Ret
= pWnd
->lpfnWndProc
;
312 Ret
= pWnd
->lpfnWndProc
;
314 if (Class
->fnid
<= FNID_GHOST
&& Class
->fnid
>= FNID_BUTTON
)
318 if (GETPFNCLIENTW(Class
->fnid
) == pWnd
->lpfnWndProc
)
319 Ret
= GETPFNCLIENTA(Class
->fnid
);
323 if (GETPFNCLIENTA(Class
->fnid
) == pWnd
->lpfnWndProc
)
324 Ret
= GETPFNCLIENTW(Class
->fnid
);
327 // Return on the change.
328 if ( Ret
!= pWnd
->lpfnWndProc
)
332 if ( Ansi
== !!(pWnd
->state
& WNDS_ANSIWINDOWPROC
) )
335 gcpd
= (WNDPROC
)NtUserGetCPD( UserHMGetHandle(pWnd
),
336 (Ansi
? UserGetCPDA2U
: UserGetCPDU2A
)|UserGetCPDWindow
,
339 return (gcpd
? gcpd
: Ret
);
342 static ULONG_PTR FASTCALL
343 IntGetClassLongA(PWND Wnd
, PCLS Class
, int nIndex
)
349 if (nIndex
+ sizeof(ULONG_PTR
) < nIndex
||
350 nIndex
+ sizeof(ULONG_PTR
) > Class
->cbclsExtra
)
352 SetLastError(ERROR_INVALID_PARAMETER
);
355 Ret
= *(PULONG_PTR
)((ULONG_PTR
)(Class
+ 1) + nIndex
);
362 Ret
= (ULONG_PTR
)Class
->cbwndExtra
;
366 Ret
= (ULONG_PTR
)Class
->cbclsExtra
;
369 case GCL_HBRBACKGROUND
:
370 Ret
= (ULONG_PTR
)Class
->hbrBackground
;
371 if (Ret
!= 0 && Ret
< 0x4000)
372 Ret
= (ULONG_PTR
)GetSysColorBrush((ULONG
)Ret
- 1);
376 //ERR("Cls 0x%x GCL_HMODULE 0x%x\n", Wnd->pcls, Class->hModule);
377 Ret
= (ULONG_PTR
)Class
->hModule
;
381 Ret
= (ULONG_PTR
)Class
->lpszClientAnsiMenuName
;
385 Ret
= (ULONG_PTR
)Class
->style
;
389 Ret
= (ULONG_PTR
)Class
->atomClassName
;
393 /* FIXME - get handle from pointer to CURSOR object */
394 Ret
= (ULONG_PTR
)Class
->hCursor
;
398 /* FIXME - get handle from pointer to ICON object */
399 Ret
= (ULONG_PTR
)Class
->hIcon
;
403 /* FIXME - get handle from pointer to ICON object */
404 Ret
= (ULONG_PTR
)Class
->hIconSm
;
408 Ret
= IntGetClsWndProc(Wnd
, Class
, TRUE
);
412 SetLastError(ERROR_INVALID_INDEX
);
420 static ULONG_PTR FASTCALL
421 IntGetClassLongW (PWND Wnd
, PCLS Class
, int nIndex
)
427 if (nIndex
+ sizeof(ULONG_PTR
) < nIndex
||
428 nIndex
+ sizeof(ULONG_PTR
) > Class
->cbclsExtra
)
430 SetLastError(ERROR_INVALID_PARAMETER
);
433 Ret
= *(PULONG_PTR
)((ULONG_PTR
)(Class
+ 1) + nIndex
);
440 Ret
= (ULONG_PTR
)Class
->cbwndExtra
;
444 Ret
= (ULONG_PTR
)Class
->cbclsExtra
;
447 case GCLP_HBRBACKGROUND
:
448 Ret
= (ULONG_PTR
)Class
->hbrBackground
;
449 if (Ret
!= 0 && Ret
< 0x4000)
450 Ret
= (ULONG_PTR
)GetSysColorBrush((ULONG
)Ret
- 1);
454 Ret
= (ULONG_PTR
)Class
->hModule
;
458 Ret
= (ULONG_PTR
)Class
->lpszClientUnicodeMenuName
;
462 Ret
= (ULONG_PTR
)Class
->style
;
466 Ret
= (ULONG_PTR
)Class
->atomClassName
;
470 /* FIXME - get handle from pointer to CURSOR object */
471 Ret
= (ULONG_PTR
)Class
->hCursor
;
475 /* FIXME - get handle from pointer to ICON object */
476 Ret
= (ULONG_PTR
)Class
->hIcon
;
480 /* FIXME - get handle from pointer to ICON object */
481 Ret
= (ULONG_PTR
)Class
->hIconSm
;
485 Ret
= IntGetClsWndProc(Wnd
, Class
, FALSE
);
489 SetLastError(ERROR_INVALID_INDEX
);
501 GetClassLongA(HWND hWnd
, int nIndex
)
507 TRACE("%p %d\n", hWnd
, nIndex
);
509 Wnd
= ValidateHwnd(hWnd
);
515 Class
= DesktopPtrToUser(Wnd
->pcls
);
521 case GCLP_HBRBACKGROUND
:
528 SetLastError(ERROR_INVALID_INDEX
);
532 Ret
= IntGetClassLongA(Wnd
, Class
, nIndex
);
536 Ret
= IntGetClassLongA(Wnd
, Class
, nIndex
);
541 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
544 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
557 GetClassLongW ( HWND hWnd
, int nIndex
)
563 TRACE("%p %d\n", hWnd
, nIndex
);
565 Wnd
= ValidateHwnd(hWnd
);
571 Class
= DesktopPtrToUser(Wnd
->pcls
);
577 case GCLP_HBRBACKGROUND
:
584 SetLastError(ERROR_INVALID_INDEX
);
588 Ret
= IntGetClassLongW(Wnd
, Class
, nIndex
);
592 Ret
= IntGetClassLongW(Wnd
, Class
, nIndex
);
597 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
600 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
615 GetClassLongPtrA(HWND hWnd
,
622 TRACE("%p %d\n", hWnd
, nIndex
);
624 Wnd
= ValidateHwnd(hWnd
);
630 Class
= DesktopPtrToUser(Wnd
->pcls
);
633 Ret
= IntGetClassLongA(Wnd
, Class
, nIndex
);
637 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
640 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
654 GetClassLongPtrW(HWND hWnd
,
661 TRACE("%p %d\n", hWnd
, nIndex
);
663 Wnd
= ValidateHwnd(hWnd
);
669 Class
= DesktopPtrToUser(Wnd
->pcls
);
672 Ret
= IntGetClassLongW(Wnd
, Class
, nIndex
);
676 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
679 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
699 WCHAR tmpbuf
[MAX_ATOM_LEN
+ 1];
702 if (nMaxCount
<= 0) return 0;
703 if (!GetClassNameW( hWnd
, tmpbuf
, sizeof(tmpbuf
)/sizeof(WCHAR
) )) return 0;
704 RtlUnicodeToMultiByteN( lpClassName
, nMaxCount
- 1, (PULONG
)&len
, tmpbuf
, strlenW(tmpbuf
) * sizeof(WCHAR
) );
705 lpClassName
[len
] = 0;
707 TRACE("%p class/atom: %s/%04x %x\n", hWnd
,
708 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
709 IS_ATOM(lpClassName
) ? lpClassName
: 0,
726 UNICODE_STRING ClassName
;
729 ClassName
.MaximumLength
= nMaxCount
* sizeof(WCHAR
);
730 ClassName
.Buffer
= lpClassName
;
732 Result
= NtUserGetClassName(hWnd
,
736 TRACE("%p class/atom: %S/%04x %x\n", hWnd
,
737 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
738 IS_ATOM(lpClassName
) ? lpClassName
: 0,
758 if (offset
< 0) return GetClassLongA( hwnd
, offset
);
760 Wnd
= ValidateHwnd(hwnd
);
764 class = DesktopPtrToUser(Wnd
->pcls
);
765 if (class == NULL
) return 0;
767 if (offset
<= class->cbclsExtra
- sizeof(WORD
))
768 memcpy( &retvalue
, (char *)(class + 1) + offset
, sizeof(retvalue
) );
770 SetLastError( ERROR_INVALID_INDEX
);
776 LONG_PTR
IntGetWindowLong( HWND hwnd
, INT offset
, UINT size
, BOOL unicode
)
778 LONG_PTR retvalue
= 0;
781 if (offset
== GWLP_HWNDPARENT
)
783 HWND parent
= GetAncestor( hwnd
, GA_PARENT
);
784 if (parent
== GetDesktopWindow()) parent
= GetWindow( hwnd
, GW_OWNER
);
785 return (ULONG_PTR
)parent
;
788 if (!(wndPtr
= ValidateHwnd( hwnd
)))
790 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
796 if (offset
> (int)(wndPtr
->cbwndExtra
- size
))
798 WARN("Invalid offset %d\n", offset
);
799 SetLastError( ERROR_INVALID_INDEX
);
802 retvalue
= *((LONG_PTR
*)((PCHAR
)(wndPtr
+ 1) + offset
));
804 /* WINE: special case for dialog window procedure */
805 //if ((offset == DWLP_DLGPROC) && (size == sizeof(LONG_PTR)) && (wndPtr->flags & WIN_ISDIALOG))
806 // retvalue = (LONG_PTR)IntGetWndProc( (WNDPROC)retvalue, unicode );
812 case GWLP_USERDATA
: retvalue
= wndPtr
->dwUserData
; break;
813 case GWL_STYLE
: retvalue
= wndPtr
->style
; break;
814 case GWL_EXSTYLE
: retvalue
= wndPtr
->ExStyle
; break;
815 case GWLP_ID
: retvalue
= wndPtr
->IDMenu
; break;
816 case GWLP_HINSTANCE
: retvalue
= (ULONG_PTR
)wndPtr
->hModule
; break;
819 if (!TestWindowProcess(wndPtr
))
821 SetLastError(ERROR_ACCESS_DENIED
);
824 retvalue
= (ULONG_PTR
)IntGetWndProc(wndPtr
, !unicode
);
828 WARN("Unknown offset %d\n", offset
);
829 SetLastError( ERROR_INVALID_INDEX
);
840 GetWindowLongA ( HWND hWnd
, int nIndex
)
842 return IntGetWindowLong( hWnd
, nIndex
, sizeof(LONG
), FALSE
);
850 GetWindowLongW(HWND hWnd
, int nIndex
)
852 return IntGetWindowLong( hWnd
, nIndex
, sizeof(LONG
), TRUE
);
861 GetWindowLongPtrA(HWND hWnd
,
864 return IntGetWindowLong( hWnd
, nIndex
, sizeof(LONG_PTR
), FALSE
);
872 GetWindowLongPtrW(HWND hWnd
,
875 return IntGetWindowLong( hWnd
, nIndex
, sizeof(LONG_PTR
), TRUE
);
885 GetWindowWord(HWND hWnd
, int nIndex
)
891 case GWLP_HWNDPARENT
:
896 WARN("Invalid offset %d\n", nIndex
);
897 SetLastError( ERROR_INVALID_INDEX
);
902 return IntGetWindowLong( hWnd
, nIndex
, sizeof(WORD
), FALSE
);
915 UNICODE_STRING ClassName
;
916 ClassName
.MaximumLength
= cchType
* sizeof(WCHAR
);
917 ClassName
.Buffer
= (PWSTR
)pszType
;
919 return NtUserGetClassName(hwnd
,TRUE
,&ClassName
);
933 WCHAR tmpbuf
[MAX_ATOM_LEN
+ 1];
936 if ((INT
)cchType
<= 0) return 0;
937 if (!RealGetWindowClassW( hwnd
, tmpbuf
, sizeof(tmpbuf
)/sizeof(WCHAR
) )) return 0;
938 RtlUnicodeToMultiByteN( pszType
, cchType
- 1, (PULONG
)&len
, tmpbuf
, strlenW(tmpbuf
) * sizeof(WCHAR
) );
944 * Create a small icon based on a standard icon
947 CreateSmallIcon(HICON StdIcon
)
949 HICON SmallIcon
= NULL
;
953 BITMAP StdBitmapInfo
;
954 HDC hSourceDc
= NULL
;
957 HBITMAP OldSourceBitmap
= NULL
;
958 HBITMAP OldDestBitmap
= NULL
;
960 SmallInfo
.hbmColor
= NULL
;
961 SmallInfo
.hbmMask
= NULL
;
963 /* We need something to work with... */
969 SmallIconWidth
= GetSystemMetrics(SM_CXSMICON
);
970 SmallIconHeight
= GetSystemMetrics(SM_CYSMICON
);
971 if (! GetIconInfo(StdIcon
, &StdInfo
))
973 ERR("Failed to get icon info for icon 0x%x\n", StdIcon
);
976 if (! GetObjectW(StdInfo
.hbmMask
, sizeof(BITMAP
), &StdBitmapInfo
))
978 ERR("Failed to get bitmap info for icon 0x%x bitmap 0x%x\n",
979 StdIcon
, StdInfo
.hbmColor
);
982 if (StdBitmapInfo
.bmWidth
== SmallIconWidth
&&
983 StdBitmapInfo
.bmHeight
== SmallIconHeight
)
985 /* Icon already has the correct dimensions */
989 hSourceDc
= CreateCompatibleDC(NULL
);
990 if (NULL
== hSourceDc
)
992 ERR("Failed to create source DC\n");
995 hDestDc
= CreateCompatibleDC(NULL
);
998 ERR("Failed to create dest DC\n");
1002 OldSourceBitmap
= SelectObject(hSourceDc
, StdInfo
.hbmColor
);
1003 if (NULL
== OldSourceBitmap
)
1005 ERR("Failed to select source color bitmap\n");
1008 SmallInfo
.hbmColor
= CreateCompatibleBitmap(hSourceDc
, SmallIconWidth
,
1010 if (NULL
== SmallInfo
.hbmColor
)
1012 ERR("Failed to create color bitmap\n");
1015 OldDestBitmap
= SelectObject(hDestDc
, SmallInfo
.hbmColor
);
1016 if (NULL
== OldDestBitmap
)
1018 ERR("Failed to select dest color bitmap\n");
1021 if (! StretchBlt(hDestDc
, 0, 0, SmallIconWidth
, SmallIconHeight
,
1022 hSourceDc
, 0, 0, StdBitmapInfo
.bmWidth
,
1023 StdBitmapInfo
.bmHeight
, SRCCOPY
))
1025 ERR("Failed to stretch color bitmap\n");
1029 if (NULL
== SelectObject(hSourceDc
, StdInfo
.hbmMask
))
1031 ERR("Failed to select source mask bitmap\n");
1034 SmallInfo
.hbmMask
= CreateCompatibleBitmap(hSourceDc
, SmallIconWidth
, SmallIconHeight
);
1035 if (NULL
== SmallInfo
.hbmMask
)
1037 ERR("Failed to create mask bitmap\n");
1040 if (NULL
== SelectObject(hDestDc
, SmallInfo
.hbmMask
))
1042 ERR("Failed to select dest mask bitmap\n");
1045 if (! StretchBlt(hDestDc
, 0, 0, SmallIconWidth
, SmallIconHeight
,
1046 hSourceDc
, 0, 0, StdBitmapInfo
.bmWidth
,
1047 StdBitmapInfo
.bmHeight
, SRCCOPY
))
1049 ERR("Failed to stretch mask bitmap\n");
1053 SmallInfo
.fIcon
= TRUE
;
1054 SmallInfo
.xHotspot
= SmallIconWidth
/ 2;
1055 SmallInfo
.yHotspot
= SmallIconHeight
/ 2;
1056 SmallIcon
= CreateIconIndirect(&SmallInfo
);
1057 if (NULL
== SmallIcon
)
1059 ERR("Failed to create icon\n");
1064 if (NULL
!= SmallInfo
.hbmMask
)
1066 DeleteObject(SmallInfo
.hbmMask
);
1068 if (NULL
!= OldDestBitmap
)
1070 SelectObject(hDestDc
, OldDestBitmap
);
1072 if (NULL
!= SmallInfo
.hbmColor
)
1074 DeleteObject(SmallInfo
.hbmColor
);
1076 if (NULL
!= hDestDc
)
1080 if (NULL
!= OldSourceBitmap
)
1082 SelectObject(hSourceDc
, OldSourceBitmap
);
1084 if (NULL
!= hSourceDc
)
1086 DeleteDC(hSourceDc
);
1094 RegisterClassExWOWW(WNDCLASSEXW
*lpwcx
,
1101 WNDCLASSEXW WndClass
;
1102 UNICODE_STRING ClassName
;
1103 UNICODE_STRING MenuName
= {0};
1104 CLSMENUNAME clsMenuName
;
1105 ANSI_STRING AnsiMenuName
;
1107 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
1108 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
1109 lpwcx
->lpszClassName
== NULL
)
1111 TRACE("RegisterClassExWOWW Invalid Parameter Error!\n");
1112 SetLastError(ERROR_INVALID_PARAMETER
);
1118 if (!RegisterDefaultClasses
) RegisterSystemControls();
1121 * On real Windows this looks more like:
1122 * if (lpwcx->hInstance == User32Instance &&
1123 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
1124 * But since I have no idea what the magic field in the
1125 * TEB structure means, I rather decided to omit that.
1128 GetWin32ClientInfo()->dwExpWinVer & (WINVER == 0x400)
1130 if (lpwcx
->hInstance
== User32Instance
)
1132 TRACE("RegisterClassExWOWW User32Instance!\n");
1133 SetLastError(ERROR_INVALID_PARAMETER
);
1136 /* Yes, this is correct. We should modify the passed structure. */
1137 if (lpwcx
->hInstance
== NULL
)
1138 ((WNDCLASSEXW
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
1140 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
1142 if (NULL
== WndClass
.hIconSm
)
1144 WndClass
.hIconSm
= CreateSmallIcon(WndClass
.hIcon
);
1147 if (WndClass
.lpszMenuName
!= NULL
)
1149 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
1151 if (WndClass
.lpszMenuName
[0])
1153 RtlInitUnicodeString(&MenuName
, WndClass
.lpszMenuName
);
1154 RtlUnicodeStringToAnsiString( &AnsiMenuName
, &MenuName
, TRUE
);
1159 MenuName
.Buffer
= (LPWSTR
)WndClass
.lpszMenuName
;
1160 AnsiMenuName
.Buffer
= (PCHAR
)WndClass
.lpszMenuName
;
1164 if (IS_ATOM(WndClass
.lpszClassName
))
1167 ClassName
.MaximumLength
= 0;
1168 ClassName
.Buffer
= (LPWSTR
)WndClass
.lpszClassName
;
1172 RtlInitUnicodeString(&ClassName
, WndClass
.lpszClassName
);
1175 clsMenuName
.pszClientAnsiMenuName
= AnsiMenuName
.Buffer
;
1176 clsMenuName
.pwszClientUnicodeMenuName
= MenuName
.Buffer
;
1177 clsMenuName
.pusMenuName
= &MenuName
;
1179 Atom
= NtUserRegisterClassExWOW( &WndClass
,
1181 NULL
, //PUNICODE_STRING ClsNVersion,
1187 TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
1188 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
1189 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
1198 RegisterClassExA(CONST WNDCLASSEXA
*lpwcx
)
1201 WNDCLASSEXW WndClass
;
1202 WCHAR mname
[MAX_BUFFER_LEN
];
1203 WCHAR cname
[MAX_BUFFER_LEN
];
1205 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXA
));
1207 if (WndClass
.lpszMenuName
!= NULL
)
1209 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
1211 if (WndClass
.lpszMenuName
[0])
1213 if (!MultiByteToWideChar( CP_ACP
, 0, lpwcx
->lpszMenuName
, -1, mname
, MAX_ATOM_LEN
+ 1 )) return 0;
1215 WndClass
.lpszMenuName
= mname
;
1220 if (!IS_ATOM(WndClass
.lpszClassName
))
1222 if (!MultiByteToWideChar( CP_ACP
, 0, lpwcx
->lpszClassName
, -1, cname
, MAX_ATOM_LEN
+ 1 )) return 0;
1224 WndClass
.lpszClassName
= cname
;
1227 Atom
= RegisterClassExWOWW( &WndClass
,
1233 TRACE("A atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
1234 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
1235 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
1244 RegisterClassExW(CONST WNDCLASSEXW
*lpwcx
)
1248 Atom
= RegisterClassExWOWW( (WNDCLASSEXW
*)lpwcx
, 0, 0, 0, TRUE
);
1250 TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d\n",
1251 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
1252 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
);
1261 RegisterClassA(CONST WNDCLASSA
*lpWndClass
)
1265 if (lpWndClass
== NULL
)
1268 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSA
));
1269 Class
.cbSize
= sizeof(WNDCLASSEXA
);
1270 Class
.hIconSm
= NULL
;
1272 return RegisterClassExA(&Class
);
1279 RegisterClassW(CONST WNDCLASSW
*lpWndClass
)
1283 if (lpWndClass
== NULL
)
1286 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSW
));
1287 Class
.cbSize
= sizeof(WNDCLASSEXW
);
1288 Class
.hIconSm
= NULL
;
1290 return RegisterClassExW(&Class
);
1298 SetClassLongA (HWND hWnd
,
1302 PSTR lpStr
= (PSTR
)(ULONG_PTR
)dwNewLong
;
1303 UNICODE_STRING Value
= {0};
1304 BOOL Allocated
= FALSE
;
1307 /* FIXME - portability!!!! */
1309 if (nIndex
== GCL_MENUNAME
&& lpStr
!= NULL
)
1311 if (!IS_INTRESOURCE(lpStr
))
1313 if (!RtlCreateUnicodeStringFromAsciiz(&Value
,
1316 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1323 Value
.Buffer
= (PWSTR
)lpStr
;
1325 dwNewLong
= (LONG_PTR
)&Value
;
1327 else if (nIndex
== GCW_ATOM
&& lpStr
!= NULL
)
1329 if (!IS_ATOM(lpStr
))
1331 if (!RtlCreateUnicodeStringFromAsciiz(&Value
,
1334 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1341 Value
.Buffer
= (PWSTR
)lpStr
;
1343 dwNewLong
= (LONG_PTR
)&Value
;
1346 Ret
= (DWORD
)NtUserSetClassLong(hWnd
,
1353 RtlFreeUnicodeString(&Value
);
1365 SetClassLongW(HWND hWnd
,
1369 PWSTR lpStr
= (PWSTR
)(ULONG_PTR
)dwNewLong
;
1370 UNICODE_STRING Value
= {0};
1372 TRACE("%p %d %lx\n", hWnd
, nIndex
, dwNewLong
);
1374 /* FIXME - portability!!!! */
1376 if (nIndex
== GCL_MENUNAME
&& lpStr
!= NULL
)
1378 if (!IS_INTRESOURCE(lpStr
))
1380 RtlInitUnicodeString(&Value
,
1384 Value
.Buffer
= lpStr
;
1386 dwNewLong
= (LONG_PTR
)&Value
;
1388 else if (nIndex
== GCW_ATOM
&& lpStr
!= NULL
)
1390 if (!IS_ATOM(lpStr
))
1392 RtlInitUnicodeString(&Value
,
1396 Value
.Buffer
= lpStr
;
1398 dwNewLong
= (LONG_PTR
)&Value
;
1401 return (DWORD
)NtUserSetClassLong(hWnd
,
1413 SetClassLongPtrA(HWND hWnd
,
1426 SetClassLongPtrW(HWND hWnd
,
1445 * NOTE: Obsoleted in 32-bit windows
1448 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
1451 return (WORD
) SetClassLongW ( hWnd
, nIndex
, wNewWord
);
1459 SetWindowWord ( HWND hWnd
,int nIndex
,WORD wNewWord
)
1464 case GWLP_HINSTANCE
:
1465 case GWLP_HWNDPARENT
:
1470 WARN("Invalid offset %d\n", nIndex
);
1471 SetLastError( ERROR_INVALID_INDEX
);
1476 return NtUserSetWindowLong( hWnd
, nIndex
, wNewWord
, FALSE
);
1489 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, TRUE
);
1502 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
1511 SetWindowLongPtrA(HWND hWnd
,
1515 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
1523 SetWindowLongPtrW(HWND hWnd
,
1527 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
1538 HINSTANCE hInstance
)
1540 UNICODE_STRING ClassName
= {0};
1543 TRACE("class/atom: %s/%04x %p\n",
1544 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
1545 IS_ATOM(lpClassName
) ? lpClassName
: 0,
1548 if (!IS_ATOM(lpClassName
))
1550 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
,
1553 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1558 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpClassName
);
1560 Ret
= NtUserUnregisterClass(&ClassName
,
1564 if (!IS_ATOM(lpClassName
))
1565 RtlFreeUnicodeString(&ClassName
);
1577 LPCWSTR lpClassName
,
1578 HINSTANCE hInstance
)
1580 UNICODE_STRING ClassName
= {0};
1582 TRACE("class/atom: %S/%04x %p\n",
1583 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
1584 IS_ATOM(lpClassName
) ? lpClassName
: 0,
1587 if (!IS_ATOM(lpClassName
))
1589 RtlInitUnicodeString(&ClassName
,
1593 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpClassName
);
1595 return NtUserUnregisterClass(&ClassName
,