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
20 static BOOL
GetClassInfoExCommon(
27 UNICODE_STRING str2
, str3
;
32 if ( !lpszClass
|| !lpwcx
)
34 SetLastError(ERROR_INVALID_PARAMETER
);
38 if(IS_ATOM(lpszClass
))
39 str
= (LPWSTR
)lpszClass
;
42 extern BOOL ControlsInitialized
;
46 str
= HEAP_strdupW ( lpszClass
, wcslen(lpszClass
) );
50 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
57 Status
= HEAP_strdupAtoW(&str
, (LPCSTR
)lpszClass
, NULL
);
59 if (! NT_SUCCESS(Status
))
61 SetLastError(RtlNtStatusToDosError(Status
));
66 /* Register built-in controls if not already done */
67 if ( !ControlsInitialized
)
69 ControlsInitialized
= ControlsInit(str
);
73 str2
.Length
= str3
.Length
= 0;
74 str2
.MaximumLength
= str3
.MaximumLength
= 255;
75 str2
.Buffer
= (PWSTR
)HEAP_alloc ( str2
.MaximumLength
* sizeof(WCHAR
) );
78 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
84 str3
.Buffer
= (PWSTR
)HEAP_alloc ( str3
.MaximumLength
* sizeof(WCHAR
) );
87 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
88 HEAP_free ( str2
.Buffer
);
94 w
.lpszMenuName
= (LPCWSTR
)&str2
;
95 w
.lpszClassName
= (LPCWSTR
)&str3
;
96 retval
= (BOOL
)NtUserGetClassInfo(hInst
, str
, &w
, TRUE
, 0);
100 RtlCopyMemory ( lpwcx
, &w
, sizeof(WNDCLASSEXW
) );
102 if ( !IS_INTRESOURCE(w
.lpszMenuName
) && w
.lpszMenuName
)
105 lpwcx
->lpszMenuName
= heap_string_poolW ( str2
.Buffer
, str2
.Length
);
107 ((LPWNDCLASSEXA
) lpwcx
)->lpszMenuName
= heap_string_poolA ( str2
.Buffer
, str2
.Length
);
110 if ( !IS_ATOM(w
.lpszClassName
) && w
.lpszClassName
)
113 lpwcx
->lpszClassName
= heap_string_poolW ( str3
.Buffer
, str3
.Length
);
115 ((LPWNDCLASSEXA
) lpwcx
)->lpszClassName
= heap_string_poolA ( str3
.Buffer
, str3
.Length
);
118 HEAP_free ( str2
.Buffer
);
119 HEAP_free ( str3
.Buffer
);
135 return GetClassInfoExCommon(hinst
, (LPWSTR
)lpszClass
, (LPWNDCLASSEXW
)lpwcx
, FALSE
);
149 return GetClassInfoExCommon(hinst
, lpszClass
, lpwcx
, TRUE
);
161 LPWNDCLASSA lpWndClass
)
166 if ( !lpClassName
|| !lpWndClass
)
168 SetLastError(ERROR_INVALID_PARAMETER
);
172 retval
= GetClassInfoExA(hInstance
,lpClassName
,&w
);
175 RtlCopyMemory ( lpWndClass
, &w
.style
, sizeof(WNDCLASSA
) );
188 LPWNDCLASSW lpWndClass
)
193 if(!lpClassName
|| !lpWndClass
)
195 SetLastError(ERROR_INVALID_PARAMETER
);
199 retval
= GetClassInfoExW(hInstance
,lpClassName
,&w
);
200 RtlCopyMemory (lpWndClass
,&w
.style
,sizeof(WNDCLASSW
));
209 GetClassLongA(HWND hWnd
, int nIndex
)
213 case GCL_HBRBACKGROUND
:
215 DWORD hBrush
= NtUserGetClassLong(hWnd
, GCL_HBRBACKGROUND
, TRUE
);
216 if (hBrush
!= 0 && hBrush
< 0x4000)
217 hBrush
= (DWORD
)GetSysColorBrush((ULONG
)hBrush
- 1);
223 PUNICODE_STRING Name
;
224 Name
= (PUNICODE_STRING
)NtUserGetClassLong(hWnd
, nIndex
, TRUE
);
225 if (IS_INTRESOURCE(Name
))
228 return (DWORD
)heap_string_poolA(Name
->Buffer
, Name
->Length
);
232 return NtUserGetClassLong(hWnd
, nIndex
, TRUE
);
240 GetClassLongW ( HWND hWnd
, int nIndex
)
244 case GCL_HBRBACKGROUND
:
246 DWORD hBrush
= NtUserGetClassLong(hWnd
, GCL_HBRBACKGROUND
, TRUE
);
247 if (hBrush
!= 0 && hBrush
< 0x4000)
248 hBrush
= (DWORD
)GetSysColorBrush((ULONG
)hBrush
- 1);
254 PUNICODE_STRING Name
;
255 Name
= (PUNICODE_STRING
)NtUserGetClassLong(hWnd
, nIndex
, FALSE
);
256 if (IS_INTRESOURCE(Name
))
259 return (DWORD
)heap_string_poolW(Name
->Buffer
, Name
->Length
);
263 return NtUserGetClassLong(hWnd
, nIndex
, FALSE
);
284 ClassNameW
= HEAP_alloc ( (nMaxCount
+1)*sizeof(WCHAR
) );
286 result
= NtUserGetClassName ( hWnd
, ClassNameW
, nMaxCount
);
288 Status
= HEAP_strcpyWtoA ( lpClassName
, ClassNameW
, result
);
290 HEAP_free ( ClassNameW
);
292 if ( !NT_SUCCESS(Status
) )
309 return NtUserGetClassName(hWnd
, lpClassName
, nMaxCount
);
322 * NOTE: Obsoleted in 32-bit windows
325 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
328 return (WORD
) NtUserGetClassLong ( hWnd
, nIndex
, TRUE
);
337 GetWindowLongA ( HWND hWnd
, int nIndex
)
339 return NtUserGetWindowLong(hWnd
, nIndex
, TRUE
);
348 GetWindowLongW(HWND hWnd
, int nIndex
)
350 return NtUserGetWindowLong(hWnd
, nIndex
, FALSE
);
358 GetWindowWord(HWND hWnd
, int nIndex
)
360 return (WORD
)NtUserGetWindowLong(hWnd
, nIndex
, TRUE
);
368 SetWindowWord ( HWND hWnd
,int nIndex
,WORD wNewWord
)
370 return (WORD
)NtUserSetWindowLong ( hWnd
, nIndex
, (LONG
)wNewWord
, TRUE
);
383 /* FIXME: Implement correct functionality of RealGetWindowClass */
384 return GetClassNameW(hwnd
,pszType
,cchType
);
398 /* FIXME: Implement correct functionality of RealGetWindowClass */
399 return GetClassNameA(hwnd
,pszType
,cchType
);
406 RegisterClassExA(CONST WNDCLASSEXA
*lpwcx
)
409 WNDCLASSEXA WndClass
;
410 UNICODE_STRING ClassName
;
411 UNICODE_STRING MenuName
;
413 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
414 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
415 lpwcx
->lpszClassName
== NULL
)
417 SetLastError(ERROR_INVALID_PARAMETER
);
422 * On real Windows this looks more like:
423 * if (lpwcx->hInstance == User32Instance &&
424 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
425 * But since I have no idea what the magic field in the
426 * TEB structure means, I rather decided to omit that.
429 if (lpwcx
->hInstance
== User32Instance
)
431 SetLastError(ERROR_INVALID_PARAMETER
);
435 /* Yes, this is correct. We should modify the passed structure. */
436 if (lpwcx
->hInstance
== NULL
)
437 ((WNDCLASSEXA
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
439 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
441 if (IS_ATOM(lpwcx
->lpszMenuName
) || lpwcx
->lpszMenuName
== 0)
444 MenuName
.MaximumLength
= 0;
445 MenuName
.Buffer
= (LPWSTR
)lpwcx
->lpszMenuName
;
448 RtlCreateUnicodeStringFromAsciiz(&MenuName
, lpwcx
->lpszMenuName
);
451 if (IS_ATOM(lpwcx
->lpszClassName
))
454 ClassName
.MaximumLength
= 0;
455 ClassName
.Buffer
= (LPWSTR
)lpwcx
->lpszClassName
;
458 RtlCreateUnicodeStringFromAsciiz(&ClassName
, lpwcx
->lpszClassName
);
461 Atom
= NtUserRegisterClassExWOW(
462 (WNDCLASSEXW
*)&WndClass
,
470 if (!IS_ATOM(lpwcx
->lpszMenuName
))
471 RtlFreeUnicodeString(&MenuName
);
472 if (!IS_ATOM(lpwcx
->lpszClassName
))
473 RtlFreeUnicodeString(&ClassName
);
482 RegisterClassExW(CONST WNDCLASSEXW
*lpwcx
)
484 WNDCLASSEXW WndClass
;
485 UNICODE_STRING ClassName
;
486 UNICODE_STRING MenuName
;
488 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
489 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
490 lpwcx
->lpszClassName
== NULL
)
492 SetLastError(ERROR_INVALID_PARAMETER
);
497 * On real Windows this looks more like:
498 * if (lpwcx->hInstance == User32Instance &&
499 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
500 * But since I have no idea what the magic field in the
501 * TEB structure means, I rather decided to omit that.
504 if (lpwcx
->hInstance
== User32Instance
)
506 SetLastError(ERROR_INVALID_PARAMETER
);
510 /* Yes, this is correct. We should modify the passed structure. */
511 if (lpwcx
->hInstance
== NULL
)
512 ((WNDCLASSEXW
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
514 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
516 if (IS_ATOM(lpwcx
->lpszMenuName
))
519 MenuName
.MaximumLength
= 0;
520 MenuName
.Buffer
= (LPWSTR
)lpwcx
->lpszMenuName
;
523 RtlInitUnicodeString(&MenuName
, lpwcx
->lpszMenuName
);
526 if (IS_ATOM(lpwcx
->lpszClassName
))
529 ClassName
.MaximumLength
= 0;
530 ClassName
.Buffer
= (LPWSTR
)lpwcx
->lpszClassName
;
533 RtlInitUnicodeString(&ClassName
, lpwcx
->lpszClassName
);
536 return (ATOM
)NtUserRegisterClassExWOW(
550 RegisterClassA(CONST WNDCLASSA
*lpWndClass
)
554 if (lpWndClass
== NULL
)
557 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSA
));
558 Class
.cbSize
= sizeof(WNDCLASSEXA
);
559 Class
.hIconSm
= NULL
;
561 return RegisterClassExA(&Class
);
568 RegisterClassW(CONST WNDCLASSW
*lpWndClass
)
572 if (lpWndClass
== NULL
)
575 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSW
));
576 Class
.cbSize
= sizeof(WNDCLASSEXW
);
577 Class
.hIconSm
= NULL
;
579 return RegisterClassExW(&Class
);
592 UNICODE_STRING str2buf
;
594 PUNICODE_STRING str2
= &str2buf
;
596 if ( nIndex
!= GCL_MENUNAME
)
598 return NtUserSetClassLong ( hWnd
, nIndex
, dwNewLong
, TRUE
);
600 if ( IS_INTRESOURCE(dwNewLong
) )
602 str2
= (PUNICODE_STRING
)dwNewLong
;
606 RtlCreateUnicodeStringFromAsciiz ( &str2buf
,(LPSTR
)dwNewLong
);
609 str
= (PUNICODE_STRING
)NtUserSetClassLong(hWnd
, nIndex
, (DWORD
)str2
, TRUE
);
611 if ( !IS_INTRESOURCE(dwNewLong
) )
613 RtlFreeUnicodeString ( str2
);
615 if ( IS_INTRESOURCE(str
) )
621 return (DWORD
)heap_string_poolA ( str
->Buffer
, str
->Length
);
636 UNICODE_STRING str2buf
;
638 PUNICODE_STRING str2
= &str2buf
;
640 if (nIndex
!= GCL_MENUNAME
)
642 return NtUserSetClassLong ( hWnd
, nIndex
, dwNewLong
, FALSE
);
644 if ( IS_INTRESOURCE(dwNewLong
) )
646 str2
= (PUNICODE_STRING
)dwNewLong
;
650 RtlCreateUnicodeString ( &str2buf
, (LPWSTR
)dwNewLong
);
653 str
= (PUNICODE_STRING
)NtUserSetClassLong(hWnd
, nIndex
, (DWORD
)str2
, TRUE
);
655 if ( !IS_INTRESOURCE(dwNewLong
) )
657 RtlFreeUnicodeString(str2
);
659 if ( IS_INTRESOURCE(str
) )
665 return (DWORD
)heap_string_poolW ( str
->Buffer
, str
->Length
);
680 * NOTE: Obsoleted in 32-bit windows
683 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
686 return (WORD
) NtUserSetClassLong ( hWnd
, nIndex
, wNewWord
, TRUE
);
700 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, TRUE
);
714 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
731 if(!IS_ATOM(lpClassName
))
733 Status
= HEAP_strdupAtoW(&ClassName
, lpClassName
, NULL
);
734 if(!NT_SUCCESS(Status
))
736 SetLastError(RtlNtStatusToDosError(Status
));
741 ClassName
= (LPWSTR
)lpClassName
;
743 Result
= (BOOL
)NtUserUnregisterClass((LPCWSTR
)ClassName
, hInstance
, 0);
745 if(ClassName
&& !IS_ATOM(lpClassName
))
746 HEAP_free(ClassName
);
761 return (BOOL
)NtUserUnregisterClass(lpClassName
, hInstance
, 0);