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 (!RegisterDefaultClasses
)
51 ERR("GetClassInfoExA RegisterSystemControls\n");
52 RegisterSystemControls();
55 if (IS_ATOM(lpszClass
))
57 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpszClass
);
61 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
,
64 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
69 Ret
= NtUserGetClassInfo(hInstance
,
72 (LPWSTR
*)&pszMenuName
,
76 lpwcx
->lpszClassName
= lpszClass
;
77 // lpwcx->lpszMenuName = pszMenuName;
80 if (!IS_ATOM(lpszClass
))
82 RtlFreeUnicodeString(&ClassName
);
99 UNICODE_STRING ClassName
= {0};
103 TRACE("%p class/atom: %S/%04x %p\n", hInstance
,
104 IS_ATOM(lpszClass
) ? NULL
: lpszClass
,
105 IS_ATOM(lpszClass
) ? lpszClass
: 0,
108 //HACKHACK: This is ROS-specific and should go away
109 lpwcx
->cbSize
= sizeof(*lpwcx
);
111 if (hInstance
== User32Instance
)
116 if (lpszClass
== NULL
)
118 SetLastError(ERROR_INVALID_PARAMETER
);
122 if (!RegisterDefaultClasses
)
124 ERR("GetClassInfoExW RegisterSystemControls\n");
125 RegisterSystemControls();
128 if (IS_ATOM(lpszClass
))
130 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpszClass
);
134 RtlInitUnicodeString(&ClassName
,
138 Ret
= NtUserGetClassInfo( hInstance
,
145 lpwcx
->lpszClassName
= lpszClass
;
146 // lpwcx->lpszMenuName = pszMenuName;
160 LPWNDCLASSA lpWndClass
)
165 retval
= GetClassInfoExA(hInstance
, lpClassName
, &wcex
);
168 lpWndClass
->style
= wcex
.style
;
169 lpWndClass
->lpfnWndProc
= wcex
.lpfnWndProc
;
170 lpWndClass
->cbClsExtra
= wcex
.cbClsExtra
;
171 lpWndClass
->cbWndExtra
= wcex
.cbWndExtra
;
172 lpWndClass
->hInstance
= wcex
.hInstance
;
173 lpWndClass
->hIcon
= wcex
.hIcon
;
174 lpWndClass
->hCursor
= wcex
.hCursor
;
175 lpWndClass
->hbrBackground
= wcex
.hbrBackground
;
176 lpWndClass
->lpszMenuName
= wcex
.lpszMenuName
;
177 lpWndClass
->lpszClassName
= wcex
.lpszClassName
;
191 LPWNDCLASSW lpWndClass
)
196 retval
= GetClassInfoExW(hInstance
, lpClassName
, &wcex
);
199 lpWndClass
->style
= wcex
.style
;
200 lpWndClass
->lpfnWndProc
= wcex
.lpfnWndProc
;
201 lpWndClass
->cbClsExtra
= wcex
.cbClsExtra
;
202 lpWndClass
->cbWndExtra
= wcex
.cbWndExtra
;
203 lpWndClass
->hInstance
= wcex
.hInstance
;
204 lpWndClass
->hIcon
= wcex
.hIcon
;
205 lpWndClass
->hCursor
= wcex
.hCursor
;
206 lpWndClass
->hbrBackground
= wcex
.hbrBackground
;
207 lpWndClass
->lpszMenuName
= wcex
.lpszMenuName
;
208 lpWndClass
->lpszClassName
= wcex
.lpszClassName
;
214 // Based on find_winproc... Fixes many whine tests......
217 IntGetClsWndProc(PWND pWnd
, PCLS Class
, BOOL Ansi
)
220 ULONG_PTR gcpd
, Ret
= 0;
221 // If server side, sweep through proc list and return the client side proc.
222 if (Class
->CSF_flags
& CSF_SERVERSIDEPROC
)
223 { // Always scan through the list due to wine class "deftest".
224 for ( i
= FNID_FIRST
; i
<= FNID_SWITCH
; i
++)
226 if (GETPFNSERVER(i
) == Class
->lpfnWndProc
)
229 Ret
= (ULONG_PTR
)GETPFNCLIENTA(i
);
231 Ret
= (ULONG_PTR
)GETPFNCLIENTW(i
);
237 Ret
= (ULONG_PTR
)Class
->lpfnWndProc
;
238 // Return the proc if one of the FnId default class type.
239 if (Class
->fnid
<= FNID_GHOST
&& Class
->fnid
>= FNID_BUTTON
)
242 { // If match return the right proc by type.
243 if (GETPFNCLIENTW(Class
->fnid
) == Class
->lpfnWndProc
)
244 Ret
= (ULONG_PTR
)GETPFNCLIENTA(Class
->fnid
);
248 if (GETPFNCLIENTA(Class
->fnid
) == Class
->lpfnWndProc
)
249 Ret
= (ULONG_PTR
)GETPFNCLIENTW(Class
->fnid
);
252 // Return on change or Ansi/Unicode proc equal.
253 if ( Ret
!= (ULONG_PTR
)Class
->lpfnWndProc
||
254 Ansi
== !!(Class
->CSF_flags
& CSF_ANSIPROC
) )
257 /* We have an Ansi and Unicode swap! If Ansi create Unicode proc handle.
258 This will force CallWindowProc to deal with it. */
259 gcpd
= NtUserGetCPD( UserHMGetHandle(pWnd
),
260 (Ansi
? UserGetCPDA2U
: UserGetCPDU2A
)|UserGetCPDWndtoCls
,
263 return (gcpd
? gcpd
: Ret
);
267 // Based on IntGetClsWndProc
270 IntGetWndProc(PWND pWnd
, BOOL Ansi
)
273 WNDPROC gcpd
, Ret
= 0;
274 PCLS Class
= DesktopPtrToUser(pWnd
->pcls
);
276 if (!Class
) return Ret
;
278 if (pWnd
->state
& WNDS_SERVERSIDEWINDOWPROC
)
280 for ( i
= FNID_FIRST
; i
<= FNID_SWITCH
; i
++)
282 if (GETPFNSERVER(i
) == pWnd
->lpfnWndProc
)
285 Ret
= GETPFNCLIENTA(i
);
287 Ret
= GETPFNCLIENTW(i
);
293 /* Edit controls are special - they return a wndproc handle when
294 GetWindowLongPtr is called with a different A/W.
295 On the other hand there is no W->A->W conversion so this control
296 is treated specially.
298 if (Class
->fnid
== FNID_EDIT
)
299 Ret
= pWnd
->lpfnWndProc
;
303 Ret
= pWnd
->lpfnWndProc
;
305 if (Class
->fnid
<= FNID_GHOST
&& Class
->fnid
>= FNID_BUTTON
)
309 if (GETPFNCLIENTW(Class
->fnid
) == pWnd
->lpfnWndProc
)
310 Ret
= GETPFNCLIENTA(Class
->fnid
);
314 if (GETPFNCLIENTA(Class
->fnid
) == pWnd
->lpfnWndProc
)
315 Ret
= GETPFNCLIENTW(Class
->fnid
);
318 // Return on the change.
319 if ( Ret
!= pWnd
->lpfnWndProc
)
323 if ( Ansi
== !!(pWnd
->state
& WNDS_ANSIWINDOWPROC
) )
326 gcpd
= (WNDPROC
)NtUserGetCPD( UserHMGetHandle(pWnd
),
327 (Ansi
? UserGetCPDA2U
: UserGetCPDU2A
)|UserGetCPDWindow
,
330 return (gcpd
? gcpd
: Ret
);
337 GetClassLongA(HWND hWnd
, int nIndex
)
343 TRACE("%p %d\n", hWnd
, nIndex
);
345 Wnd
= ValidateHwnd(hWnd
);
351 Class
= DesktopPtrToUser(Wnd
->pcls
);
356 if (nIndex
+ sizeof(ULONG_PTR
) < nIndex
||
357 nIndex
+ sizeof(ULONG_PTR
) > Class
->cbclsExtra
)
359 SetLastError(ERROR_INVALID_PARAMETER
);
362 Ret
= *(PULONG_PTR
)((ULONG_PTR
)(Class
+ 1) + nIndex
);
369 Ret
= (ULONG_PTR
)Class
->cbwndExtra
;
373 Ret
= (ULONG_PTR
)Class
->cbclsExtra
;
376 case GCL_HBRBACKGROUND
:
377 Ret
= (ULONG_PTR
)Class
->hbrBackground
;
378 if (Ret
!= 0 && Ret
< 0x4000)
379 Ret
= (ULONG_PTR
)GetSysColorBrush((ULONG
)Ret
- 1);
383 //ERR("Cls 0x%x GCL_HMODULE 0x%x\n", Wnd->pcls, Class->hModule);
384 Ret
= (ULONG_PTR
)Class
->hModule
;
388 Ret
= (ULONG_PTR
)Class
->lpszClientAnsiMenuName
;
392 Ret
= (ULONG_PTR
)Class
->style
;
396 Ret
= (ULONG_PTR
)Class
->atomClassName
;
400 /* FIXME - get handle from pointer to CURSOR object */
401 Ret
= (ULONG_PTR
)Class
->hCursor
;
405 /* FIXME - get handle from pointer to ICON object */
406 Ret
= (ULONG_PTR
)Class
->hIcon
;
410 /* FIXME - get handle from pointer to ICON object */
411 Ret
= (ULONG_PTR
)Class
->hIconSm
;
415 Ret
= IntGetClsWndProc(Wnd
, Class
, TRUE
);
419 SetLastError(ERROR_INVALID_INDEX
);
426 /* This is a race condition! Call win32k to make sure we're getting
427 the correct result */
428 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
430 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
433 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
435 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
440 Ret
= NtUserGetClassLong(hWnd
, nIndex
, TRUE
);
449 GetClassLongW ( HWND hWnd
, int nIndex
)
455 TRACE("%p %d\n", hWnd
, nIndex
);
457 Wnd
= ValidateHwnd(hWnd
);
463 Class
= DesktopPtrToUser(Wnd
->pcls
);
468 if (nIndex
+ sizeof(ULONG_PTR
) < nIndex
||
469 nIndex
+ sizeof(ULONG_PTR
) > Class
->cbclsExtra
)
471 SetLastError(ERROR_INVALID_PARAMETER
);
474 Ret
= *(PULONG_PTR
)((ULONG_PTR
)(Class
+ 1) + nIndex
);
481 Ret
= (ULONG_PTR
)Class
->cbwndExtra
;
485 Ret
= (ULONG_PTR
)Class
->cbclsExtra
;
488 case GCL_HBRBACKGROUND
:
489 Ret
= (ULONG_PTR
)Class
->hbrBackground
;
490 if (Ret
!= 0 && Ret
< 0x4000)
491 Ret
= (ULONG_PTR
)GetSysColorBrush((ULONG
)Ret
- 1);
495 Ret
= (ULONG_PTR
)Class
->hModule
;
499 Ret
= (ULONG_PTR
)Class
->lpszClientUnicodeMenuName
;
503 Ret
= (ULONG_PTR
)Class
->style
;
507 Ret
= (ULONG_PTR
)Class
->atomClassName
;
511 /* FIXME - get handle from pointer to CURSOR object */
512 Ret
= (ULONG_PTR
)Class
->hCursor
;
516 /* FIXME - get handle from pointer to ICON object */
517 Ret
= (ULONG_PTR
)Class
->hIcon
;
521 /* FIXME - get handle from pointer to ICON object */
522 Ret
= (ULONG_PTR
)Class
->hIconSm
;
526 Ret
= IntGetClsWndProc(Wnd
, Class
, FALSE
);
530 SetLastError(ERROR_INVALID_INDEX
);
537 /* This is a race condition! Call win32k to make sure we're getting
538 the correct result */
539 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
541 WARN("Invalid class for hwnd 0x%p!\n", hWnd
);
544 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
546 Wnd
= NULL
; /* Make sure we call NtUserGetClassLong */
551 Ret
= NtUserGetClassLong(hWnd
, nIndex
, FALSE
);
562 GetClassLongPtrA(HWND hWnd
,
574 GetClassLongPtrW(HWND hWnd
,
592 ANSI_STRING ClassName
;
595 ClassName
.MaximumLength
= nMaxCount
;
596 ClassName
.Buffer
= lpClassName
;
598 Result
= NtUserGetClassName(hWnd
,
599 (PUNICODE_STRING
)&ClassName
,
602 TRACE("%p class/atom: %s/%04x %x\n", hWnd
,
603 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
604 IS_ATOM(lpClassName
) ? lpClassName
: 0,
621 UNICODE_STRING ClassName
;
624 ClassName
.MaximumLength
= nMaxCount
* sizeof(WCHAR
);
625 ClassName
.Buffer
= lpClassName
;
627 Result
= NtUserGetClassName(hWnd
,
631 TRACE("%p class/atom: %S/%04x %x\n", hWnd
,
632 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
633 IS_ATOM(lpClassName
) ? lpClassName
: 0,
649 * NOTE: Obsoleted in 32-bit windows
652 TRACE("%p %x\n", hWnd
, nIndex
);
654 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
657 return (WORD
) NtUserGetClassLong ( hWnd
, nIndex
, TRUE
);
661 LONG_PTR
IntGetWindowLong( HWND hwnd
, INT offset
, UINT size
, BOOL unicode
)
663 LONG_PTR retvalue
= 0;
666 if (offset
== GWLP_HWNDPARENT
)
668 HWND parent
= GetAncestor( hwnd
, GA_PARENT
);
669 if (parent
== GetDesktopWindow()) parent
= GetWindow( hwnd
, GW_OWNER
);
670 return (ULONG_PTR
)parent
;
673 if (!(wndPtr
= ValidateHwnd( hwnd
)))
675 SetLastError( ERROR_INVALID_WINDOW_HANDLE
);
681 if (offset
> (int)(wndPtr
->cbwndExtra
- size
))
683 WARN("Invalid offset %d\n", offset
);
684 SetLastError( ERROR_INVALID_INDEX
);
687 retvalue
= *((LONG_PTR
*)((PCHAR
)(wndPtr
+ 1) + offset
));
689 /* WINE: special case for dialog window procedure */
690 //if ((offset == DWLP_DLGPROC) && (size == sizeof(LONG_PTR)) && (wndPtr->flags & WIN_ISDIALOG))
691 // retvalue = (LONG_PTR)IntGetWndProc( (WNDPROC)retvalue, unicode );
697 case GWLP_USERDATA
: retvalue
= wndPtr
->dwUserData
; break;
698 case GWL_STYLE
: retvalue
= wndPtr
->style
; break;
699 case GWL_EXSTYLE
: retvalue
= wndPtr
->ExStyle
; break;
700 case GWLP_ID
: retvalue
= wndPtr
->IDMenu
; break;
701 case GWLP_HINSTANCE
: retvalue
= (ULONG_PTR
)wndPtr
->hModule
; break;
704 if (!TestWindowProcess(wndPtr
))
706 SetLastError(ERROR_ACCESS_DENIED
);
709 retvalue
= (ULONG_PTR
)IntGetWndProc(wndPtr
, unicode
);
713 WARN("Unknown offset %d\n", offset
);
714 SetLastError( ERROR_INVALID_INDEX
);
725 GetWindowLongA ( HWND hWnd
, int nIndex
)
727 return IntGetWindowLong( hWnd
, nIndex
, sizeof(LONG
), FALSE
);
735 GetWindowLongW(HWND hWnd
, int nIndex
)
737 return IntGetWindowLong( hWnd
, nIndex
, sizeof(LONG
), TRUE
);
746 GetWindowLongPtrA(HWND hWnd
,
749 return IntGetWindowLong( hWnd
, nIndex
, sizeof(LONG_PTR
), FALSE
);
757 GetWindowLongPtrW(HWND hWnd
,
760 return IntGetWindowLong( hWnd
, nIndex
, sizeof(LONG_PTR
), TRUE
);
770 GetWindowWord(HWND hWnd
, int nIndex
)
776 case GWLP_HWNDPARENT
:
781 WARN("Invalid offset %d\n", nIndex
);
782 SetLastError( ERROR_INVALID_INDEX
);
787 return IntGetWindowLong( hWnd
, nIndex
, sizeof(WORD
), FALSE
);
800 /* FIXME: Implement correct functionality of RealGetWindowClass */
801 return GetClassNameW(hwnd
,pszType
,cchType
);
815 /* FIXME: Implement correct functionality of RealGetWindowClass */
816 return GetClassNameA(hwnd
,pszType
,cchType
);
820 * Create a small icon based on a standard icon
823 CreateSmallIcon(HICON StdIcon
)
825 HICON SmallIcon
= NULL
;
829 BITMAP StdBitmapInfo
;
831 HDC hSourceDc
= NULL
;
834 HBITMAP OldSourceBitmap
= NULL
;
835 HBITMAP OldDestBitmap
= NULL
;
837 SmallInfo
.hbmColor
= NULL
;
838 SmallInfo
.hbmMask
= NULL
;
840 /* We need something to work with... */
846 SmallIconWidth
= GetSystemMetrics(SM_CXSMICON
);
847 SmallIconHeight
= GetSystemMetrics(SM_CYSMICON
);
848 if (! GetIconInfo(StdIcon
, &StdInfo
))
850 ERR("Failed to get icon info for icon 0x%x\n", StdIcon
);
853 if (! GetObjectW(StdInfo
.hbmMask
, sizeof(BITMAP
), &StdBitmapInfo
))
855 ERR("Failed to get bitmap info for icon 0x%x bitmap 0x%x\n",
856 StdIcon
, StdInfo
.hbmColor
);
859 if (StdBitmapInfo
.bmWidth
== SmallIconWidth
&&
860 StdBitmapInfo
.bmHeight
== SmallIconHeight
)
862 /* Icon already has the correct dimensions */
866 /* Get a handle to a info DC and handles to DCs which can be used to
867 select a bitmap into. This is done to avoid triggering a switch to
868 graphics mode (if we're currently in text/blue screen mode) */
869 hInfoDc
= CreateICW(NULL
, NULL
, NULL
, NULL
);
872 ERR("Failed to create info DC\n");
875 hSourceDc
= CreateCompatibleDC(NULL
);
876 if (NULL
== hSourceDc
)
878 ERR("Failed to create source DC\n");
881 hDestDc
= CreateCompatibleDC(NULL
);
884 ERR("Failed to create dest DC\n");
888 OldSourceBitmap
= SelectObject(hSourceDc
, StdInfo
.hbmColor
);
889 if (NULL
== OldSourceBitmap
)
891 ERR("Failed to select source color bitmap\n");
894 SmallInfo
.hbmColor
= CreateCompatibleBitmap(hInfoDc
, SmallIconWidth
,
896 if (NULL
== SmallInfo
.hbmColor
)
898 ERR("Failed to create color bitmap\n");
901 OldDestBitmap
= SelectObject(hDestDc
, SmallInfo
.hbmColor
);
902 if (NULL
== OldDestBitmap
)
904 ERR("Failed to select dest color bitmap\n");
907 if (! StretchBlt(hDestDc
, 0, 0, SmallIconWidth
, SmallIconHeight
,
908 hSourceDc
, 0, 0, StdBitmapInfo
.bmWidth
,
909 StdBitmapInfo
.bmHeight
, SRCCOPY
))
911 ERR("Failed to stretch color bitmap\n");
915 if (NULL
== SelectObject(hSourceDc
, StdInfo
.hbmMask
))
917 ERR("Failed to select source mask bitmap\n");
920 SmallInfo
.hbmMask
= CreateBitmap(SmallIconWidth
, SmallIconHeight
, 1, 1,
922 if (NULL
== SmallInfo
.hbmMask
)
924 ERR("Failed to create mask bitmap\n");
927 if (NULL
== SelectObject(hDestDc
, SmallInfo
.hbmMask
))
929 ERR("Failed to select dest mask bitmap\n");
932 if (! StretchBlt(hDestDc
, 0, 0, SmallIconWidth
, SmallIconHeight
,
933 hSourceDc
, 0, 0, StdBitmapInfo
.bmWidth
,
934 StdBitmapInfo
.bmHeight
, SRCCOPY
))
936 ERR("Failed to stretch mask bitmap\n");
940 SmallInfo
.fIcon
= TRUE
;
941 SmallInfo
.xHotspot
= SmallIconWidth
/ 2;
942 SmallInfo
.yHotspot
= SmallIconHeight
/ 2;
943 SmallIcon
= CreateIconIndirect(&SmallInfo
);
944 if (NULL
== SmallIcon
)
946 ERR("Failed to create icon\n");
951 if (NULL
!= SmallInfo
.hbmMask
)
953 DeleteObject(SmallInfo
.hbmMask
);
955 if (NULL
!= OldDestBitmap
)
957 SelectObject(hDestDc
, OldDestBitmap
);
959 if (NULL
!= SmallInfo
.hbmColor
)
961 DeleteObject(SmallInfo
.hbmColor
);
967 if (NULL
!= OldSourceBitmap
)
969 SelectObject(hSourceDc
, OldSourceBitmap
);
971 if (NULL
!= hSourceDc
)
985 RegisterClassExWOWW(WNDCLASSEXW
*lpwcx
,
992 WNDCLASSEXW WndClass
;
993 UNICODE_STRING ClassName
;
994 UNICODE_STRING MenuName
= {0};
995 CLSMENUNAME clsMenuName
;
996 ANSI_STRING AnsiMenuName
;
998 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
999 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
1000 lpwcx
->lpszClassName
== NULL
)
1002 ERR("RegisterClassExWOWW Invalid Parameter Error!\n");
1003 SetLastError(ERROR_INVALID_PARAMETER
);
1009 if (!RegisterDefaultClasses
) RegisterSystemControls();
1012 * On real Windows this looks more like:
1013 * if (lpwcx->hInstance == User32Instance &&
1014 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
1015 * But since I have no idea what the magic field in the
1016 * TEB structure means, I rather decided to omit that.
1019 GetWin32ClientInfo()->dwExpWinVer & (WINVER == 0x400)
1021 if (lpwcx
->hInstance
== User32Instance
)
1023 ERR("RegisterClassExWOWW User32Instance!\n");
1024 SetLastError(ERROR_INVALID_PARAMETER
);
1027 /* Yes, this is correct. We should modify the passed structure. */
1028 if (lpwcx
->hInstance
== NULL
)
1029 ((WNDCLASSEXW
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
1031 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
1033 if (NULL
== WndClass
.hIconSm
)
1035 WndClass
.hIconSm
= CreateSmallIcon(WndClass
.hIcon
);
1038 if (WndClass
.lpszMenuName
!= NULL
)
1040 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
1042 if (WndClass
.lpszMenuName
[0])
1044 RtlInitUnicodeString(&MenuName
, WndClass
.lpszMenuName
);
1045 RtlUnicodeStringToAnsiString( &AnsiMenuName
, &MenuName
, TRUE
);
1050 MenuName
.Buffer
= (LPWSTR
)WndClass
.lpszMenuName
;
1051 AnsiMenuName
.Buffer
= (PCHAR
)WndClass
.lpszMenuName
;
1055 if (IS_ATOM(WndClass
.lpszClassName
))
1058 ClassName
.MaximumLength
= 0;
1059 ClassName
.Buffer
= (LPWSTR
)WndClass
.lpszClassName
;
1063 RtlInitUnicodeString(&ClassName
, WndClass
.lpszClassName
);
1066 clsMenuName
.pszClientAnsiMenuName
= AnsiMenuName
.Buffer
;
1067 clsMenuName
.pwszClientUnicodeMenuName
= MenuName
.Buffer
;
1068 clsMenuName
.pusMenuName
= &MenuName
;
1070 Atom
= NtUserRegisterClassExWOW( &WndClass
,
1072 NULL
, //PUNICODE_STRING ClsNVersion,
1078 TRACE("atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
1079 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
1080 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
1089 RegisterClassExA(CONST WNDCLASSEXA
*lpwcx
)
1092 WNDCLASSEXW WndClass
;
1093 WCHAR mname
[MAX_BUFFER_LEN
];
1094 WCHAR cname
[MAX_BUFFER_LEN
];
1096 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXA
));
1098 if (WndClass
.lpszMenuName
!= NULL
)
1100 if (!IS_INTRESOURCE(WndClass
.lpszMenuName
))
1102 if (WndClass
.lpszMenuName
[0])
1104 if (!MultiByteToWideChar( CP_ACP
, 0, lpwcx
->lpszMenuName
, -1, mname
, MAX_ATOM_LEN
+ 1 )) return 0;
1106 WndClass
.lpszMenuName
= mname
;
1111 if (!IS_ATOM(WndClass
.lpszClassName
))
1113 if (!MultiByteToWideChar( CP_ACP
, 0, lpwcx
->lpszClassName
, -1, cname
, MAX_ATOM_LEN
+ 1 )) return 0;
1115 WndClass
.lpszClassName
= cname
;
1118 Atom
= RegisterClassExWOWW( &WndClass
,
1124 TRACE("A atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d class=%p\n",
1125 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
1126 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
, WndClass
);
1135 RegisterClassExW(CONST WNDCLASSEXW
*lpwcx
)
1139 Atom
= RegisterClassExWOWW( (WNDCLASSEXW
*)lpwcx
, 0, 0, 0, TRUE
);
1141 TRACE("W atom=%04x wndproc=%p hinst=%p bg=%p style=%08x clsExt=%d winExt=%d\n",
1142 Atom
, lpwcx
->lpfnWndProc
, lpwcx
->hInstance
, lpwcx
->hbrBackground
,
1143 lpwcx
->style
, lpwcx
->cbClsExtra
, lpwcx
->cbWndExtra
);
1152 RegisterClassA(CONST WNDCLASSA
*lpWndClass
)
1156 if (lpWndClass
== NULL
)
1159 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSA
));
1160 Class
.cbSize
= sizeof(WNDCLASSEXA
);
1161 Class
.hIconSm
= NULL
;
1163 return RegisterClassExA(&Class
);
1170 RegisterClassW(CONST WNDCLASSW
*lpWndClass
)
1174 if (lpWndClass
== NULL
)
1177 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSW
));
1178 Class
.cbSize
= sizeof(WNDCLASSEXW
);
1179 Class
.hIconSm
= NULL
;
1181 return RegisterClassExW(&Class
);
1189 SetClassLongA (HWND hWnd
,
1193 PSTR lpStr
= (PSTR
)(ULONG_PTR
)dwNewLong
;
1194 UNICODE_STRING Value
= {0};
1195 BOOL Allocated
= FALSE
;
1198 /* FIXME - portability!!!! */
1200 if (nIndex
== GCL_MENUNAME
&& lpStr
!= NULL
)
1202 if (!IS_INTRESOURCE(lpStr
))
1204 if (!RtlCreateUnicodeStringFromAsciiz(&Value
,
1207 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1214 Value
.Buffer
= (PWSTR
)lpStr
;
1216 dwNewLong
= (LONG_PTR
)&Value
;
1218 else if (nIndex
== GCW_ATOM
&& lpStr
!= NULL
)
1220 if (!IS_ATOM(lpStr
))
1222 if (!RtlCreateUnicodeStringFromAsciiz(&Value
,
1225 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1232 Value
.Buffer
= (PWSTR
)lpStr
;
1234 dwNewLong
= (LONG_PTR
)&Value
;
1237 Ret
= (DWORD
)NtUserSetClassLong(hWnd
,
1244 RtlFreeUnicodeString(&Value
);
1256 SetClassLongW(HWND hWnd
,
1260 PWSTR lpStr
= (PWSTR
)(ULONG_PTR
)dwNewLong
;
1261 UNICODE_STRING Value
= {0};
1263 TRACE("%p %d %lx\n", hWnd
, nIndex
, dwNewLong
);
1265 /* FIXME - portability!!!! */
1267 if (nIndex
== GCL_MENUNAME
&& lpStr
!= NULL
)
1269 if (!IS_INTRESOURCE(lpStr
))
1271 RtlInitUnicodeString(&Value
,
1275 Value
.Buffer
= lpStr
;
1277 dwNewLong
= (LONG_PTR
)&Value
;
1279 else if (nIndex
== GCW_ATOM
&& lpStr
!= NULL
)
1281 if (!IS_ATOM(lpStr
))
1283 RtlInitUnicodeString(&Value
,
1287 Value
.Buffer
= lpStr
;
1289 dwNewLong
= (LONG_PTR
)&Value
;
1292 return (DWORD
)NtUserSetClassLong(hWnd
,
1304 SetClassLongPtrA(HWND hWnd
,
1317 SetClassLongPtrW(HWND hWnd
,
1336 * NOTE: Obsoleted in 32-bit windows
1339 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
1342 return (WORD
) SetClassLongW ( hWnd
, nIndex
, wNewWord
);
1350 SetWindowWord ( HWND hWnd
,int nIndex
,WORD wNewWord
)
1355 case GWLP_HINSTANCE
:
1356 case GWLP_HWNDPARENT
:
1361 WARN("Invalid offset %d\n", nIndex
);
1362 SetLastError( ERROR_INVALID_INDEX
);
1367 return NtUserSetWindowLong( hWnd
, nIndex
, wNewWord
, FALSE
);
1380 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, TRUE
);
1393 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
1402 SetWindowLongPtrA(HWND hWnd
,
1406 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
1414 SetWindowLongPtrW(HWND hWnd
,
1418 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
1429 HINSTANCE hInstance
)
1431 UNICODE_STRING ClassName
= {0};
1434 TRACE("class/atom: %s/%04x %p\n",
1435 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
1436 IS_ATOM(lpClassName
) ? lpClassName
: 0,
1439 if (!IS_ATOM(lpClassName
))
1441 if (!RtlCreateUnicodeStringFromAsciiz(&ClassName
,
1444 SetLastError(ERROR_NOT_ENOUGH_MEMORY
);
1449 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpClassName
);
1451 Ret
= NtUserUnregisterClass(&ClassName
,
1455 if (!IS_ATOM(lpClassName
))
1456 RtlFreeUnicodeString(&ClassName
);
1468 LPCWSTR lpClassName
,
1469 HINSTANCE hInstance
)
1471 UNICODE_STRING ClassName
= {0};
1473 TRACE("class/atom: %S/%04x %p\n",
1474 IS_ATOM(lpClassName
) ? NULL
: lpClassName
,
1475 IS_ATOM(lpClassName
) ? lpClassName
: 0,
1478 if (!IS_ATOM(lpClassName
))
1480 RtlInitUnicodeString(&ClassName
,
1484 ClassName
.Buffer
= (PWSTR
)((ULONG_PTR
)lpClassName
);
1486 return NtUserUnregisterClass(&ClassName
,