2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 ReactOS Team
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* $Id: class.c,v 1.24 2003/08/07 04:03:25 royce Exp $
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * PURPOSE: Window classes
24 * FILE: subsys/win32k/ntuser/class.c
25 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
27 * 06-06-2001 CSH Created
29 /* INCLUDES ******************************************************************/
31 #include <ddk/ntddk.h>
32 #include <win32k/win32k.h>
33 #include <napi/win32.h>
34 #include <include/class.h>
35 #include <include/error.h>
36 #include <include/winsta.h>
37 #include <include/object.h>
38 #include <include/guicheck.h>
39 #include <include/window.h>
44 /* FUNCTIONS *****************************************************************/
49 return(STATUS_SUCCESS
);
53 CleanupClassImpl(VOID
)
55 return(STATUS_SUCCESS
);
60 ClassReferenceClassByAtom(PWNDCLASS_OBJECT
* Class
,
63 PWNDCLASS_OBJECT Current
;
64 PLIST_ENTRY CurrentEntry
;
65 PW32PROCESS Process
= PsGetWin32Process();
67 ExAcquireFastMutexUnsafe (&Process
->ClassListLock
);
68 CurrentEntry
= Process
->ClassListHead
.Flink
;
69 while (CurrentEntry
!= &Process
->ClassListHead
)
71 Current
= CONTAINING_RECORD(CurrentEntry
, WNDCLASS_OBJECT
, ListEntry
);
73 if (Current
->lpszClassName
== (PUNICODE_STRING
)(ULONG
)Atom
)
76 ObmReferenceObject(Current
);
77 ExReleaseFastMutexUnsafe (&Process
->ClassListLock
);
78 return(STATUS_SUCCESS
);
81 CurrentEntry
= CurrentEntry
->Flink
;
83 ExReleaseFastMutexUnsafe (&Process
->ClassListLock
);
85 return(STATUS_NOT_FOUND
);
89 ClassReferenceClassByName(PWNDCLASS_OBJECT
*Class
,
92 PWINSTATION_OBJECT WinStaObject
;
98 return(STATUS_INVALID_PARAMETER
);
101 Status
= ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
105 if (!NT_SUCCESS(Status
))
107 DPRINT("Validation of window station handle (0x%X) failed\n",
108 PROCESS_WINDOW_STATION());
109 return(STATUS_UNSUCCESSFUL
);
112 Status
= RtlLookupAtomInAtomTable(WinStaObject
->AtomTable
,
116 if (!NT_SUCCESS(Status
))
118 ObDereferenceObject(WinStaObject
);
121 Status
= ClassReferenceClassByAtom(Class
,
124 ObDereferenceObject(WinStaObject
);
129 ClassReferenceClassByNameOrAtom(PWNDCLASS_OBJECT
*Class
,
130 LPWSTR ClassNameOrAtom
)
134 if (IS_ATOM(ClassNameOrAtom
))
136 Status
= ClassReferenceClassByAtom(Class
,
137 (RTL_ATOM
)((ULONG_PTR
)ClassNameOrAtom
));
141 Status
= ClassReferenceClassByName(Class
,
145 if (!NT_SUCCESS(Status
))
147 SetLastNtError(Status
);
154 NtUserGetClassInfo(IN LPWSTR ClassName
,
158 OUT PULONG ReturnedLength
)
166 W32kGetClassName(struct _WINDOW_OBJECT
*WindowObject
,
172 if (IS_ATOM(WindowObject
->Class
->lpszClassName
))
174 /* FIXME find the string from the atom */
176 length
= wcslen(name
);
180 name
= WindowObject
->Class
->lpszClassName
->Buffer
;
181 length
= WindowObject
->Class
->lpszClassName
->Length
/ sizeof(WCHAR
);
183 if (length
> nMaxCount
)
187 *(lpClassName
+length
) = 0;
188 wcsncpy(lpClassName
,name
,length
);
193 NtUserGetClassName(HWND hWnd
,
197 PWINDOW_OBJECT WindowObject
;
200 WindowObject
= W32kGetWindowObject(hWnd
);
201 if (WindowObject
== NULL
)
205 Ret
= W32kGetClassName(WindowObject
, lpClassName
, nMaxCount
);
206 W32kReleaseWindowObject(WindowObject
);
211 NtUserGetWOWClass(DWORD Unknown0
,
219 PWNDCLASS_OBJECT FASTCALL
220 W32kCreateClass(CONST WNDCLASSEXW
*lpwcx
,
224 PWNDCLASS_OBJECT ClassObject
;
226 objectSize
= sizeof(WNDCLASS_OBJECT
);
227 ClassObject
= ObmCreateObject(NULL
, NULL
, otClass
, objectSize
);
228 if (ClassObject
== 0)
233 ClassObject
->cbSize
= lpwcx
->cbSize
;
234 ClassObject
->style
= lpwcx
->style
;
235 ClassObject
->cbClsExtra
= lpwcx
->cbClsExtra
;
236 ClassObject
->cbWndExtra
= lpwcx
->cbWndExtra
;
237 ClassObject
->hInstance
= lpwcx
->hInstance
;
238 ClassObject
->hIcon
= lpwcx
->hIcon
;
239 ClassObject
->hCursor
= lpwcx
->hCursor
;
240 ClassObject
->hbrBackground
= lpwcx
->hbrBackground
;
241 ClassObject
->Unicode
= bUnicodeClass
;
242 ClassObject
->hIconSm
= lpwcx
->hIconSm
;
243 ClassObject
->lpszClassName
= (PUNICODE_STRING
)(ULONG
)Atom
;
246 ClassObject
->lpfnWndProcW
= lpwcx
->lpfnWndProc
;
247 ClassObject
->lpfnWndProcA
= (WNDPROC
)0xCCCCCCCC;
251 ClassObject
->lpfnWndProcA
= lpwcx
->lpfnWndProc
;
252 ClassObject
->lpfnWndProcW
= (WNDPROC
)0xCCCCCCCC;
254 if (HIWORD(lpwcx
->lpszMenuName
) == 0)
256 ClassObject
->lpszMenuName
= (PUNICODE_STRING
)lpwcx
->lpszMenuName
;
260 RtlCreateUnicodeString(ClassObject
->lpszMenuName
,(LPWSTR
)lpwcx
->lpszMenuName
);
266 NtUserRegisterClassExWOW(
267 CONST WNDCLASSEXW
*lpwcx
,
275 * Registers a new class with the window manager
277 * lpwcx = Win32 extended window class structure
278 * bUnicodeClass = Whether to send ANSI or unicode strings
279 * to window procedures
281 * Atom identifying the new class
284 PWINSTATION_OBJECT WinStaObject
;
285 PWNDCLASS_OBJECT ClassObject
;
288 DPRINT("About to open window station handle (0x%X)\n",
289 PROCESS_WINDOW_STATION());
290 Status
= ValidateWindowStationHandle(PROCESS_WINDOW_STATION(),
294 if (!NT_SUCCESS(Status
))
296 DPRINT("Validation of window station handle (0x%X) failed\n",
297 PROCESS_WINDOW_STATION());
300 if (!IS_ATOM(lpwcx
->lpszClassName
))
302 Status
= RtlAddAtomToAtomTable(WinStaObject
->AtomTable
,
303 (LPWSTR
)lpwcx
->lpszClassName
,
305 if (!NT_SUCCESS(Status
))
307 ObDereferenceObject(WinStaObject
);
308 DPRINT("Failed adding class name (%wS) to atom table\n",
309 lpwcx
->lpszClassName
);
310 SetLastNtError(Status
);
316 Atom
= (RTL_ATOM
)(ULONG
)lpwcx
->lpszClassName
;
318 ClassObject
= W32kCreateClass(lpwcx
, bUnicodeClass
, Atom
);
319 if (ClassObject
== NULL
)
321 if (!IS_ATOM(lpwcx
->lpszClassName
))
323 RtlDeleteAtomFromAtomTable(WinStaObject
->AtomTable
, Atom
);
325 ObDereferenceObject(WinStaObject
);
326 DPRINT("Failed creating window class object\n");
327 SetLastNtError(STATUS_INSUFFICIENT_RESOURCES
);
330 ExAcquireFastMutex(&PsGetWin32Process()->ClassListLock
);
331 InsertTailList(&PsGetWin32Process()->ClassListHead
, &ClassObject
->ListEntry
);
332 ExReleaseFastMutex(&PsGetWin32Process()->ClassListLock
);
333 ObDereferenceObject(WinStaObject
);
338 W32kGetClassLong(struct _WINDOW_OBJECT
*WindowObject
, ULONG Offset
, BOOL Ansi
)
344 Ret
= WindowObject
->Class
->cbWndExtra
;
347 Ret
= WindowObject
->Class
->cbClsExtra
;
349 case GCL_HBRBACKGROUND
:
350 Ret
= (ULONG
)WindowObject
->Class
->hbrBackground
;
353 Ret
= (ULONG
)WindowObject
->Class
->hCursor
;
356 Ret
= (ULONG
)WindowObject
->Class
->hIcon
;
359 Ret
= (ULONG
)WindowObject
->Class
->hIconSm
;
362 Ret
= (ULONG
)WindowObject
->Class
->hInstance
;
367 Ret = (ULONG)WindowObject->Class->ClassA.lpszMenuName;
371 Ret = (ULONG)WindowObject->Class->ClassW.lpszMenuName;
375 Ret
= WindowObject
->Class
->style
;
378 if (WindowObject
->Unicode
)
380 Ret
= (ULONG
)WindowObject
->Class
->lpfnWndProcW
;
384 Ret
= (ULONG
)WindowObject
->Class
->lpfnWndProcA
;
395 NtUserGetClassLong(HWND hWnd
, DWORD Offset
, BOOL Ansi
)
397 PWINDOW_OBJECT WindowObject
;
400 WindowObject
= W32kGetWindowObject(hWnd
);
401 if (WindowObject
== NULL
)
405 Ret
= W32kGetClassLong(WindowObject
, Offset
, Ansi
);
406 W32kReleaseWindowObject(WindowObject
);
411 W32kSetClassLong(PWINDOW_OBJECT WindowObject
, ULONG Offset
, LONG dwNewLong
, BOOL Ansi
)
416 WindowObject
->Class
->cbWndExtra
= dwNewLong
;
419 WindowObject
->Class
->cbClsExtra
= dwNewLong
;
421 case GCL_HBRBACKGROUND
:
422 WindowObject
->Class
->hbrBackground
= (HBRUSH
)dwNewLong
;
425 WindowObject
->Class
->hCursor
= (HCURSOR
)dwNewLong
;
428 WindowObject
->Class
->hIcon
= (HICON
)dwNewLong
;
431 WindowObject
->Class
->hIconSm
= (HICON
)dwNewLong
;
434 WindowObject
->Class
->hInstance
= (HINSTANCE
)dwNewLong
;
437 WindowObject->Class->Class.lpszMenuName = (LPCWSTR)dwNewLong;
440 WindowObject
->Class
->style
= dwNewLong
;
443 WindowObject->Class->Class.lpfnWndProc = (WNDPROC)dwNewLong;
449 NtUserSetClassLong(HWND hWnd
,
454 PWINDOW_OBJECT WindowObject
;
457 WindowObject
= W32kGetWindowObject(hWnd
);
458 if (WindowObject
== NULL
)
462 Ret
= W32kGetClassLong(WindowObject
, Offset
, Ansi
);
463 W32kSetClassLong(WindowObject
, Offset
, dwNewLong
, Ansi
);
464 W32kReleaseWindowObject(WindowObject
);
469 NtUserSetClassWord(DWORD Unknown0
,
479 NtUserUnregisterClass(DWORD Unknown0
,