1 /* $Id: class.c,v 1.49 2004/05/17 16:38:57 navaraf Exp $
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>
19 #define NTOS_MODE_USER
24 static BOOL
GetClassInfoExCommon(
31 UNICODE_STRING str2
, str3
;
36 if ( !lpszClass
|| !lpwcx
)
38 SetLastError(ERROR_INVALID_PARAMETER
);
42 if(IS_ATOM(lpszClass
))
43 str
= (LPWSTR
)lpszClass
;
46 extern BOOL ControlsInitialized
;
50 str
= HEAP_strdupW ( lpszClass
, wcslen(lpszClass
) );
54 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
61 Status
= HEAP_strdupAtoW(&str
, (LPCSTR
)lpszClass
, NULL
);
63 if (! NT_SUCCESS(Status
))
65 SetLastError(RtlNtStatusToDosError(Status
));
70 /* Register built-in controls if not already done */
71 if ( !ControlsInitialized
)
73 ControlsInitialized
= ControlsInit(str
);
77 str2
.Length
= str3
.Length
= 0;
78 str2
.MaximumLength
= str3
.MaximumLength
= 255;
79 str2
.Buffer
= (PWSTR
)HEAP_alloc ( str2
.MaximumLength
* sizeof(WCHAR
) );
82 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
88 str3
.Buffer
= (PWSTR
)HEAP_alloc ( str3
.MaximumLength
* sizeof(WCHAR
) );
91 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY
));
97 w
.lpszMenuName
= (LPCWSTR
)&str2
;
98 w
.lpszClassName
= (LPCWSTR
)&str3
;
99 retval
= (BOOL
)NtUserGetClassInfo(hInst
, str
, &w
, TRUE
, 0);
103 RtlCopyMemory ( lpwcx
, &w
, sizeof(WNDCLASSEXW
) );
105 if ( !IS_INTRESOURCE(w
.lpszMenuName
) && w
.lpszMenuName
)
108 lpwcx
->lpszMenuName
= heap_string_poolW ( str2
.Buffer
, str2
.Length
);
110 ((LPWNDCLASSEXA
) lpwcx
)->lpszMenuName
= heap_string_poolA ( str2
.Buffer
, str2
.Length
);
113 if ( !IS_ATOM(w
.lpszClassName
) && w
.lpszClassName
)
116 lpwcx
->lpszClassName
= heap_string_poolW ( str3
.Buffer
, str3
.Length
);
118 ((LPWNDCLASSEXA
) lpwcx
)->lpszClassName
= heap_string_poolA ( str3
.Buffer
, str3
.Length
);
121 HEAP_free ( str2
.Buffer
);
122 HEAP_free ( str3
.Buffer
);
138 return GetClassInfoExCommon(hinst
, (LPWSTR
)lpszClass
, (LPWNDCLASSEXW
)lpwcx
, FALSE
);
152 return GetClassInfoExCommon(hinst
, lpszClass
, lpwcx
, TRUE
);
164 LPWNDCLASSA lpWndClass
)
169 if ( !lpClassName
|| !lpWndClass
)
171 SetLastError(ERROR_INVALID_PARAMETER
);
175 retval
= GetClassInfoExA(hInstance
,lpClassName
,&w
);
176 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
))
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 RtlFreeUnicodeString(&MenuName
);
471 RtlFreeUnicodeString(&ClassName
);
480 RegisterClassExW(CONST WNDCLASSEXW
*lpwcx
)
482 WNDCLASSEXW WndClass
;
483 UNICODE_STRING ClassName
;
484 UNICODE_STRING MenuName
;
486 if (lpwcx
== NULL
|| lpwcx
->cbSize
!= sizeof(WNDCLASSEXW
) ||
487 lpwcx
->cbClsExtra
< 0 || lpwcx
->cbWndExtra
< 0 ||
488 lpwcx
->lpszClassName
== NULL
)
490 SetLastError(ERROR_INVALID_PARAMETER
);
495 * On real Windows this looks more like:
496 * if (lpwcx->hInstance == User32Instance &&
497 * *(PULONG)((ULONG_PTR)NtCurrentTeb() + 0x6D4) & 0x400)
498 * But since I have no idea what the magic field in the
499 * TEB structure means, I rather decided to omit that.
502 if (lpwcx
->hInstance
== User32Instance
)
504 SetLastError(ERROR_INVALID_PARAMETER
);
508 /* Yes, this is correct. We should modify the passed structure. */
509 if (lpwcx
->hInstance
== NULL
)
510 ((WNDCLASSEXW
*)lpwcx
)->hInstance
= GetModuleHandleW(NULL
);
512 RtlCopyMemory(&WndClass
, lpwcx
, sizeof(WNDCLASSEXW
));
514 if (IS_ATOM(lpwcx
->lpszMenuName
))
517 MenuName
.MaximumLength
= 0;
518 MenuName
.Buffer
= (LPWSTR
)lpwcx
->lpszMenuName
;
521 RtlInitUnicodeString(&MenuName
, lpwcx
->lpszMenuName
);
524 if (IS_ATOM(lpwcx
->lpszClassName
))
527 ClassName
.MaximumLength
= 0;
528 ClassName
.Buffer
= (LPWSTR
)lpwcx
->lpszClassName
;
531 RtlInitUnicodeString(&ClassName
, lpwcx
->lpszClassName
);
534 return (ATOM
)NtUserRegisterClassExWOW(
548 RegisterClassA(CONST WNDCLASSA
*lpWndClass
)
552 if (lpWndClass
== NULL
)
555 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSA
));
556 Class
.cbSize
= sizeof(WNDCLASSEXA
);
557 Class
.hIconSm
= NULL
;
559 return RegisterClassExA(&Class
);
566 RegisterClassW(CONST WNDCLASSW
*lpWndClass
)
570 if (lpWndClass
== NULL
)
573 RtlCopyMemory(&Class
.style
, lpWndClass
, sizeof(WNDCLASSW
));
574 Class
.cbSize
= sizeof(WNDCLASSEXW
);
575 Class
.hIconSm
= NULL
;
577 return RegisterClassExW(&Class
);
591 PUNICODE_STRING str2
;
593 if ( nIndex
!= GCL_MENUNAME
)
595 return NtUserSetClassLong ( hWnd
, nIndex
, dwNewLong
, TRUE
);
597 if ( IS_INTRESOURCE(dwNewLong
) )
599 str2
= (PUNICODE_STRING
)dwNewLong
;
603 RtlCreateUnicodeString ( str2
, (LPWSTR
)dwNewLong
);
606 str
= (PUNICODE_STRING
)NtUserSetClassLong(hWnd
, nIndex
, (DWORD
)str2
, TRUE
);
608 if ( !IS_INTRESOURCE(dwNewLong
) )
610 RtlFreeUnicodeString ( str2
);
612 if ( IS_INTRESOURCE(str
) )
618 return (DWORD
)heap_string_poolA ( str
->Buffer
, str
->Length
);
634 PUNICODE_STRING str2
;
636 if (nIndex
!= GCL_MENUNAME
)
638 return NtUserSetClassLong ( hWnd
, nIndex
, dwNewLong
, FALSE
);
640 if ( IS_INTRESOURCE(dwNewLong
) )
642 str2
= (PUNICODE_STRING
)dwNewLong
;
646 RtlCreateUnicodeStringFromAsciiz ( str2
,(LPSTR
)dwNewLong
);
649 str
= (PUNICODE_STRING
)NtUserSetClassLong(hWnd
, nIndex
, (DWORD
)str2
, TRUE
);
651 if ( !IS_INTRESOURCE(dwNewLong
) )
653 RtlFreeUnicodeString(str2
);
655 if ( IS_INTRESOURCE(str
) )
661 return (DWORD
)heap_string_poolW ( str
->Buffer
, str
->Length
);
676 * NOTE: Obsoleted in 32-bit windows
679 if ((nIndex
< 0) && (nIndex
!= GCW_ATOM
))
682 return (WORD
) NtUserSetClassLong ( hWnd
, nIndex
, wNewWord
, TRUE
);
696 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, TRUE
);
710 return NtUserSetWindowLong(hWnd
, nIndex
, dwNewLong
, FALSE
);
727 if(!IS_ATOM(lpClassName
))
729 Status
= HEAP_strdupAtoW(&ClassName
, lpClassName
, NULL
);
730 if(!NT_SUCCESS(Status
))
732 SetLastError(RtlNtStatusToDosError(Status
));
737 ClassName
= (LPWSTR
)lpClassName
;
739 Result
= (BOOL
)NtUserUnregisterClass((LPCWSTR
)ClassName
, hInstance
, 0);
741 if(ClassName
&& !IS_ATOM(lpClassName
))
742 HEAP_free(ClassName
);
757 return (BOOL
)NtUserUnregisterClass(lpClassName
, hInstance
, 0);