3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS user32.dll
5 * FILE: lib/user32/windows/class.c
6 * PURPOSE: Window classes
7 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
9 * 09-05-2001 CSH Created
18 #include <user32/regcontrol.h>
21 static BOOL
GetClassInfoExCommon(
28 UNICODE_STRING str2
, str3
;
33 if ( !lpszClass
|| !lpwcx
)
35 SetLastError(ERROR_INVALID_PARAMETER
);
39 if(IS_ATOM(lpszClass
))
40 str
= (LPWSTR
)lpszClass
;
43 extern BOOL ControlsInitialized
;
47 str
= HEAP_strdupW ( lpszClass
, wcslen(lpszClass
) );
51 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
58 Status
= HEAP_strdupAtoW(&str
, (LPCSTR
)lpszClass
, NULL
);
60 if (! NT_SUCCESS(Status
))
62 SetLastError(RtlNtStatusToDosError(Status
));
67 /* Register built-in controls if not already done */
68 if ( !ControlsInitialized
)
70 ControlsInitialized
= ControlsInit(str
);
74 str2
.Length
= str3
.Length
= 0;
75 str2
.MaximumLength
= str3
.MaximumLength
= 255;
76 str2
.Buffer
= (PWSTR
)HEAP_alloc ( str2
.MaximumLength
* sizeof(WCHAR
) );
79 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
85 str3
.Buffer
= (PWSTR
)HEAP_alloc ( str3
.MaximumLength
* sizeof(WCHAR
) );
88 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
89 HEAP_free ( str2
.Buffer
);
95 w
.lpszMenuName
= (LPCWSTR
)&str2
;
96 w
.lpszClassName
= (LPCWSTR
)&str3
;
97 retval
= (BOOL
)NtUserGetClassInfo(hInst
, str
, &w
, TRUE
, 0);
101 RtlCopyMemory ( lpwcx
, &w
, sizeof(WNDCLASSEXW
) );
103 if ( !IS_INTRESOURCE(w
.lpszMenuName
) && w
.lpszMenuName
)
106 lpwcx
->lpszMenuName
= heap_string_poolW ( str2
.Buffer
, str2
.Length
);
108 ((LPWNDCLASSEXA
) lpwcx
)->lpszMenuName
= heap_string_poolA ( str2
.Buffer
, str2
.Length
);
111 if ( !IS_ATOM(w
.lpszClassName
) && w
.lpszClassName
)
114 lpwcx
->lpszClassName
= heap_string_poolW ( str3
.Buffer
, str3
.Length
);
116 ((LPWNDCLASSEXA
) lpwcx
)->lpszClassName
= heap_string_poolA ( str3
.Buffer
, str3
.Length
);
119 HEAP_free ( str2
.Buffer
);
120 HEAP_free ( str3
.Buffer
);
136 return GetClassInfoExCommon(hinst
, (LPWSTR
)lpszClass
, (LPWNDCLASSEXW
)lpwcx
, FALSE
);
150 return GetClassInfoExCommon(hinst
, lpszClass
, lpwcx
, TRUE
);
162 LPWNDCLASSA lpWndClass
)
167 if ( !lpClassName
|| !lpWndClass
)
169 SetLastError(ERROR_INVALID_PARAMETER
);
173 retval
= GetClassInfoExA(hInstance
,lpClassName
,&w
);
176 RtlCopyMemory ( lpWndClass
, &w
.style
, sizeof(WNDCLASSA
) );
189 LPWNDCLASSW lpWndClass
)
194 if(!lpClassName
|| !lpWndClass
)
196 SetLastError(ERROR_INVALID_PARAMETER
);
200 retval
= GetClassInfoExW(hInstance
,lpClassName
,&w
);
201 RtlCopyMemory (lpWndClass
,&w
.style
,sizeof(WNDCLASSW
));
210 GetClassLongA(HWND hWnd
, int nIndex
)
214 case GCL_HBRBACKGROUND
:
216 DWORD hBrush
= NtUserGetClassLong(hWnd
, GCL_HBRBACKGROUND
, TRUE
);
217 if (hBrush
!= 0 && hBrush
< 0x4000)
218 hBrush
= (DWORD
)GetSysColorBrush((ULONG
)hBrush
- 1);
224 PUNICODE_STRING Name
;
225 Name
= (PUNICODE_STRING
)NtUserGetClassLong(hWnd
, nIndex
, TRUE
);
226 if (IS_INTRESOURCE(Name
))
229 return (DWORD
)heap_string_poolA(Name
->Buffer
, Name
->Length
);
233 return NtUserGetClassLong(hWnd
, nIndex
, TRUE
);
241 GetClassLongW ( HWND hWnd
, int nIndex
)
245 case GCL_HBRBACKGROUND
:
247 DWORD hBrush
= NtUserGetClassLong(hWnd
, GCL_HBRBACKGROUND
, TRUE
);
248 if (hBrush
!= 0 && hBrush
< 0x4000)
249 hBrush
= (DWORD
)GetSysColorBrush((ULONG
)hBrush
- 1);
255 PUNICODE_STRING Name
;
256 Name
= (PUNICODE_STRING
)NtUserGetClassLong(hWnd
, nIndex
, FALSE
);
257 if (IS_INTRESOURCE(Name
))
260 return (DWORD
)heap_string_poolW(Name
->Buffer
, Name
->Length
);
264 return NtUserGetClassLong(hWnd
, nIndex
, FALSE
);
285 ClassNameW
= HEAP_alloc ( (nMaxCount
+1)*sizeof(WCHAR
) );
287 result
= NtUserGetClassName ( hWnd
, ClassNameW
, nMaxCount
);
289 Status
= HEAP_strcpyWtoA ( lpClassName
, ClassNameW
, result
);
291 HEAP_free ( ClassNameW
);
293 if ( !NT_SUCCESS(Status
) )
310 return NtUserGetClassName(hWnd
, lpClassName
, nMaxCount
);
323 * NOTE: Obsoleted in 32-bit windows
326 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
329 return (WORD
) NtUserGetClassLong ( hWnd
, nIndex
, TRUE
);
338 GetWindowLongA ( HWND hWnd
, int nIndex
)
340 return NtUserGetWindowLong(hWnd
, nIndex
, TRUE
);
349 GetWindowLongW(HWND hWnd
, int nIndex
)
351 return NtUserGetWindowLong(hWnd
, nIndex
, FALSE
);
359 GetWindowWord(HWND hWnd
, int nIndex
)
361 return (WORD
)NtUserGetWindowLong(hWnd
, nIndex
, TRUE
);
369 SetWindowWord ( HWND hWnd
,int nIndex
,WORD wNewWord
)
371 return (WORD
)NtUserSetWindowLong ( hWnd
, nIndex
, (LONG
)wNewWord
, TRUE
);
384 /* FIXME: Implement correct functionality of RealGetWindowClass */
385 return GetClassNameW(hwnd
,pszType
,cchType
);
399 /* FIXME: Implement correct functionality of RealGetWindowClass */
400 return GetClassNameA(hwnd
,pszType
,cchType
);
407 RegisterClassExA(CONST WNDCLASSEXA
*lpwcx
)
410 WNDCLASSEXA WndClass
;
411 UNICODE_STRING ClassName
;
412 UNICODE_STRING MenuName
;
414 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
415 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
416 lpwcx
->lpszClassName
== NULL
)
418 SetLastError(ERROR_INVALID_PARAMETER
);
423 * On real Windows this looks more like:
424 * if (lpwcx->hInstance == User32Instance &&
425 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
426 * But since I have no idea what the magic field in the
427 * TEB structure means, I rather decided to omit that.
430 if (lpwcx
->hInstance
== User32Instance
)
432 SetLastError(ERROR_INVALID_PARAMETER
);
436 /* Yes, this is correct. We should modify the passed structure. */
437 if (lpwcx
->hInstance
== NULL
)
438 ((WNDCLASSEXA
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
440 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
442 if (IS_ATOM(lpwcx
->lpszMenuName
) || lpwcx
->lpszMenuName
== 0)
445 MenuName
.MaximumLength
= 0;
446 MenuName
.Buffer
= (LPWSTR
)lpwcx
->lpszMenuName
;
449 RtlCreateUnicodeStringFromAsciiz(&MenuName
, lpwcx
->lpszMenuName
);
452 if (IS_ATOM(lpwcx
->lpszClassName
))
455 ClassName
.MaximumLength
= 0;
456 ClassName
.Buffer
= (LPWSTR
)lpwcx
->lpszClassName
;
459 RtlCreateUnicodeStringFromAsciiz(&ClassName
, lpwcx
->lpszClassName
);
462 Atom
= NtUserRegisterClassExWOW(
463 (WNDCLASSEXW
*)&WndClass
,
471 if (!IS_ATOM(lpwcx
->lpszMenuName
))
472 RtlFreeUnicodeString(&MenuName
);
473 if (!IS_ATOM(lpwcx
->lpszClassName
))
474 RtlFreeUnicodeString(&ClassName
);
483 RegisterClassExW(CONST WNDCLASSEXW
*lpwcx
)
485 WNDCLASSEXW WndClass
;
486 UNICODE_STRING ClassName
;
487 UNICODE_STRING MenuName
;
489 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
490 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
491 lpwcx
->lpszClassName
== NULL
)
493 SetLastError(ERROR_INVALID_PARAMETER
);
498 * On real Windows this looks more like:
499 * if (lpwcx->hInstance == User32Instance &&
500 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
501 * But since I have no idea what the magic field in the
502 * TEB structure means, I rather decided to omit that.
505 if (lpwcx
->hInstance
== User32Instance
)
507 SetLastError(ERROR_INVALID_PARAMETER
);
511 /* Yes, this is correct. We should modify the passed structure. */
512 if (lpwcx
->hInstance
== NULL
)
513 ((WNDCLASSEXW
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
515 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
517 if (IS_ATOM(lpwcx
->lpszMenuName
))
520 MenuName
.MaximumLength
= 0;
521 MenuName
.Buffer
= (LPWSTR
)lpwcx
->lpszMenuName
;
524 RtlInitUnicodeString(&MenuName
, lpwcx
->lpszMenuName
);
527 if (IS_ATOM(lpwcx
->lpszClassName
))
530 ClassName
.MaximumLength
= 0;
531 ClassName
.Buffer
= (LPWSTR
)lpwcx
->lpszClassName
;
534 RtlInitUnicodeString(&ClassName
, lpwcx
->lpszClassName
);
537 return (ATOM
)NtUserRegisterClassExWOW(
551 RegisterClassA(CONST WNDCLASSA
*lpWndClass
)
555 if (lpWndClass
== NULL
)
558 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSA
));
559 Class
.cbSize
= sizeof(WNDCLASSEXA
);
560 Class
.hIconSm
= NULL
;
562 return RegisterClassExA(&Class
);
569 RegisterClassW(CONST WNDCLASSW
*lpWndClass
)
573 if (lpWndClass
== NULL
)
576 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSW
));
577 Class
.cbSize
= sizeof(WNDCLASSEXW
);
578 Class
.hIconSm
= NULL
;
580 return RegisterClassExW(&Class
);
593 UNICODE_STRING str2buf
;
595 PUNICODE_STRING str2
= &str2buf
;
597 if ( nIndex
!= GCL_MENUNAME
)
599 return NtUserSetClassLong ( hWnd
, nIndex
, dwNewLong
, TRUE
);
601 if ( IS_INTRESOURCE(dwNewLong
) )
603 str2
= (PUNICODE_STRING
)dwNewLong
;
607 RtlCreateUnicodeStringFromAsciiz ( &str2buf
,(LPSTR
)dwNewLong
);
610 str
= (PUNICODE_STRING
)NtUserSetClassLong(hWnd
, nIndex
, (DWORD
)str2
, TRUE
);
612 if ( !IS_INTRESOURCE(dwNewLong
) )
614 RtlFreeUnicodeString ( str2
);
616 if ( IS_INTRESOURCE(str
) )
622 return (DWORD
)heap_string_poolA ( str
->Buffer
, str
->Length
);
637 UNICODE_STRING str2buf
;
639 PUNICODE_STRING str2
= &str2buf
;
641 if (nIndex
!= GCL_MENUNAME
)
643 return NtUserSetClassLong ( hWnd
, nIndex
, dwNewLong
, FALSE
);
645 if ( IS_INTRESOURCE(dwNewLong
) )
647 str2
= (PUNICODE_STRING
)dwNewLong
;
651 RtlCreateUnicodeString ( &str2buf
, (LPWSTR
)dwNewLong
);
654 str
= (PUNICODE_STRING
)NtUserSetClassLong(hWnd
, nIndex
, (DWORD
)str2
, TRUE
);
656 if ( !IS_INTRESOURCE(dwNewLong
) )
658 RtlFreeUnicodeString(str2
);
660 if ( IS_INTRESOURCE(str
) )
666 return (DWORD
)heap_string_poolW ( str
->Buffer
, str
->Length
);
681 * NOTE: Obsoleted in 32-bit windows
684 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
687 return (WORD
) NtUserSetClassLong ( hWnd
, nIndex
, wNewWord
, TRUE
);
701 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, TRUE
);
715 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
732 if(!IS_ATOM(lpClassName
))
734 Status
= HEAP_strdupAtoW(&ClassName
, lpClassName
, NULL
);
735 if(!NT_SUCCESS(Status
))
737 SetLastError(RtlNtStatusToDosError(Status
));
742 ClassName
= (LPWSTR
)lpClassName
;
744 Result
= (BOOL
)NtUserUnregisterClass((LPCWSTR
)ClassName
, hInstance
, 0);
746 if(ClassName
&& !IS_ATOM(lpClassName
))
747 HEAP_free(ClassName
);
762 return (BOOL
)NtUserUnregisterClass(lpClassName
, hInstance
, 0);