Initial commit. Ported some code from wine.
[reactos.git] / reactos / lib / user32 / windows / class.c
1
2 #include <windows.h>
3 #include <user32/class.h>
4 #include <user32/win.h>
5 #include <user32/heapdup.h>
6
7 CLASS *rootClass;
8
9 ATOM STDCALL RegisterClassA(const WNDCLASS* wc)
10 {
11 WNDCLASSEX wcex;
12 wcex.cbSize = sizeof(WNDCLASSEX);
13 wcex.style = wc->style;
14 wcex.lpfnWndProc = wc->lpfnWndProc;
15 wcex.cbClsExtra = wc->cbClsExtra;
16 wcex.cbWndExtra = wc->cbWndExtra;
17 wcex.hInstance = wc->hInstance;
18 wcex.hIcon = wc->hIcon;
19 wcex.hCursor = wc->hCursor;
20 wcex.hbrBackground = wc->hbrBackground;
21 wcex.lpszMenuName = wc->lpszMenuName;
22 wcex.lpszClassName = wc->lpszClassName;
23 wcex.hIconSm = NULL;
24 return RegisterClassExA(&wcex);
25 }
26
27 ATOM STDCALL RegisterClassW(const WNDCLASS* wc)
28 {
29 WNDCLASSEX wcex;
30 wcex.cbSize = sizeof(WNDCLASSEX);
31 wcex.style = wc->style;
32 wcex.lpfnWndProc = wc->lpfnWndProc;
33 wcex.cbClsExtra = wc->cbClsExtra;
34 wcex.cbWndExtra = wc->cbWndExtra;
35 wcex.hInstance = wc->hInstance;
36 wcex.hIcon = wc->hIcon;
37 wcex.hCursor = wc->hCursor;
38 wcex.hbrBackground = wc->hbrBackground;
39 wcex.lpszMenuName = wc->lpszMenuName;
40 wcex.lpszClassName = wc->lpszClassName;
41 wcex.hIconSm = NULL;
42 return RegisterClassExW(&wcex);
43 }
44
45 ATOM STDCALL RegisterClassExA(const WNDCLASSEX* wc)
46 {
47 ATOM atom;
48 CLASS *classPtr;
49 INT classExtra, winExtra;
50 int len;
51
52
53 if ( wc == NULL || wc->cbSize != sizeof(WNDCLASSEX)) {
54 SetLastError(ERROR_INVALID_DATA);
55 return FALSE;
56 }
57
58 atom = GlobalAddAtomA( wc->lpszClassName );
59 if (!atom)
60 {
61 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
62 return FALSE;
63 }
64
65 classExtra = wc->cbClsExtra;
66 if (classExtra < 0)
67 classExtra = 0;
68 else if (classExtra > 40)
69 classExtra = 40;
70
71 winExtra = wc->cbClsExtra;
72 if (winExtra < 0)
73 winExtra = 0;
74 else if (winExtra > 40)
75 winExtra = 40;
76
77 classPtr = (CLASS *)HeapAlloc( GetProcessHeap(), 0, sizeof(CLASS) +
78 classExtra - sizeof(classPtr->wExtra) );
79
80
81 if (classExtra)
82 memset( classPtr->wExtra, 0, classExtra );
83
84 if (!classPtr) {
85 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
86 GlobalDeleteAtom( atom );
87 return FALSE;
88 }
89 classPtr->magic = CLASS_MAGIC;
90 classPtr->cWindows = 0;
91 classPtr->style = wc->style;
92 classPtr->winproc = wc->lpfnWndProc;
93 classPtr->cbWndExtra = winExtra;
94 classPtr->cbClsExtra = classExtra;
95 classPtr->hInstance = wc->hInstance;
96 classPtr->atomName = atom;
97 classPtr->hIcon = (HICON)wc->hIcon;
98 classPtr->hIconSm = (HICON)wc->hIconSm;
99 classPtr->hCursor = (HCURSOR)wc->hCursor;
100 classPtr->hbrBackground = (HBRUSH)wc->hbrBackground;
101 classPtr->bUnicode = FALSE;
102
103 classPtr->dce = (wc->style & CS_CLASSDC) ?
104 CreateDC( "DISPLAY", NULL,NULL,NULL ) : NULL;
105
106
107 if ( wc->lpszMenuName != NULL ) {
108 len = lstrlenA(wc->lpszMenuName);
109 classPtr->menuName = HeapAlloc(GetProcessHeap(),0,len+1);
110 lstrcpyA(classPtr->menuName,wc->lpszMenuName);
111 }
112 else
113 classPtr->menuName = NULL;
114
115
116
117 len = lstrlenA(wc->lpszClassName);
118 classPtr->className = HeapAlloc(GetProcessHeap(),0,len+1);
119 lstrcpyA(classPtr->className,wc->lpszClassName);
120
121
122
123 classPtr->next = rootClass;
124 rootClass = classPtr;
125
126 return atom;
127 }
128
129
130 ATOM STDCALL RegisterClassExW( const WNDCLASSEX* wc )
131 {
132 ATOM atom;
133 CLASS *classPtr;
134 INT classExtra, winExtra;
135
136 int i, len;
137 if ( wc == NULL || wc->cbSize != sizeof(WNDCLASSEX)) {
138 SetLastError(ERROR_INVALID_DATA);
139 return FALSE;
140 }
141
142 if (!(atom = GlobalAddAtomW( (LPWSTR)wc->lpszClassName )))
143 {
144 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
145 return FALSE;
146 }
147
148 classExtra = wc->cbClsExtra;
149 if (classExtra < 0)
150 classExtra = 0;
151 else if (classExtra > 40)
152 classExtra = 40;
153
154 winExtra = wc->cbClsExtra;
155 if (winExtra < 0)
156 winExtra = 0;
157 else if (winExtra > 40)
158 winExtra = 40;
159
160 classPtr = (CLASS *)HeapAlloc( GetProcessHeap(), 0, sizeof(CLASS) +
161 classExtra - sizeof(classPtr->wExtra) );
162
163
164 if (classExtra)
165 memset( classPtr->wExtra, 0, classExtra );
166
167 if (!classPtr) {
168 SetLastError(ERROR_NOT_ENOUGH_MEMORY);
169 GlobalDeleteAtom( atom );
170 return FALSE;
171 }
172 classPtr->magic = CLASS_MAGIC;
173 classPtr->cWindows = 0;
174 classPtr->style = wc->style;
175 classPtr->winproc = wc->lpfnWndProc;
176 classPtr->cbWndExtra = winExtra;
177 classPtr->cbClsExtra = classExtra;
178 classPtr->hInstance = wc->hInstance;
179 classPtr->atomName = atom;
180 classPtr->hIcon = (HICON)wc->hIcon;
181 classPtr->hIconSm = (HICON)wc->hIconSm;
182 classPtr->hCursor = (HCURSOR)wc->hCursor;
183 classPtr->hbrBackground = (HBRUSH)wc->hbrBackground;
184 classPtr->bUnicode = FALSE;
185
186 classPtr->dce = (wc->style & CS_CLASSDC) ?
187 CreateDC( "DISPLAY", NULL,NULL,NULL ) : NULL;
188
189 len = lstrlenW((LPWSTR)wc->lpszMenuName);
190 classPtr->menuName = HeapAlloc(GetProcessHeap(),0,(len+1)*2);
191 lstrcpyW((LPWSTR)classPtr->menuName, (LPWSTR)wc->lpszMenuName);
192
193
194 len = lstrlenW((LPWSTR)wc->lpszClassName);
195 classPtr->className = HeapAlloc(GetProcessHeap(),0,(len+1)*2);
196 lstrcpyW((LPWSTR)classPtr->className,(LPWSTR) wc->lpszClassName );
197
198 classPtr->next = rootClass;
199 rootClass = classPtr;
200
201 return atom;
202 }
203
204 WINBOOL UnregisterClassA(LPCSTR lpClassName, HINSTANCE hInstance )
205 {
206 CLASS *classPtr;
207 classPtr = CLASS_FindClassByAtom( STRING2ATOMA(lpClassName), hInstance );
208 if ( classPtr == NULL )
209 return FALSE;
210
211
212 if ( CLASS_FreeClass(classPtr) == TRUE )
213 GlobalDeleteAtom( classPtr->atomName );
214 return TRUE;
215 }
216
217
218
219
220 WINBOOL UnregisterClassW(LPCWSTR lpClassName, HINSTANCE hInstance )
221 {
222 CLASS *classPtr;
223 classPtr = CLASS_FindClassByAtom( STRING2ATOMW(lpClassName), hInstance );
224 if ( classPtr == NULL )
225 return FALSE;
226
227
228 if ( CLASS_FreeClass(classPtr) == TRUE )
229 GlobalDeleteAtom( classPtr->atomName );
230 return TRUE;
231 }
232
233
234 WINBOOL GetClassInfoA( HINSTANCE hInstance, LPCSTR lpClassName, LPWNDCLASS lpWndClass )
235 {
236
237 return FALSE;
238 }
239
240
241 WINBOOL GetClassInfoW( HINSTANCE hInstance, LPCWSTR lpClassName, LPWNDCLASS lpWndClass )
242 {
243 CLASS *classPtr;
244 ATOM a;
245
246 if ( HIWORD(lpClassName) != 0 )
247 a = FindAtomW(lpClassName);
248 else
249 a = lpClassName;
250
251 classPtr = CLASS_FindClassByAtom( a, hInstance );
252 if ( classPtr == NULL )
253 return FALSE;
254
255
256 lpWndClass->style = classPtr->style;
257 lpWndClass->lpfnWndProc = classPtr->winproc;
258 lpWndClass->cbClsExtra = classPtr->cbWndExtra;
259 lpWndClass->cbClsExtra = classPtr->cbClsExtra;
260 lpWndClass->hInstance = classPtr->hInstance;
261 lpWndClass->hIcon = classPtr->hIcon;
262 lpWndClass->hCursor = classPtr->hCursor;
263 lpWndClass->hbrBackground = classPtr->hbrBackground;
264 return TRUE;
265
266 }
267
268 WINBOOL GetClassInfoExA( HINSTANCE hInstance, LPCSTR lpClassName, LPWNDCLASSEX lpWndClass )
269 {
270
271 return FALSE;
272 }
273
274 WINBOOL GetClassInfoExW( HINSTANCE hInstance, LPCWSTR lpClassName, LPWNDCLASSEX lpWndClassEx )
275 {
276
277 CLASS *classPtr;
278 ATOM a;
279
280 if ( HIWORD(lpClassName) != 0 )
281 a = FindAtomW(lpClassName);
282 else
283 a = lpClassName;
284
285 classPtr = CLASS_FindClassByAtom( a, hInstance );
286 if ( classPtr == NULL )
287 return FALSE;
288
289
290 if ( lpWndClassEx ->cbSize != sizeof(WNDCLASSEX) )
291 return FALSE;
292
293
294 lpWndClassEx->style = classPtr->style;
295 lpWndClassEx->lpfnWndProc = classPtr->winproc;
296 lpWndClassEx->cbClsExtra = classPtr->cbWndExtra;
297 lpWndClassEx->cbClsExtra = classPtr->cbClsExtra;
298 lpWndClassEx->hInstance = classPtr->hInstance;
299 lpWndClassEx->hIcon = classPtr->hIcon;
300 lpWndClassEx->hCursor = classPtr->hCursor;
301 lpWndClassEx->hbrBackground = classPtr->hbrBackground;
302
303
304 return TRUE;
305 }
306
307 int GetClassNameA(HWND hWnd, LPSTR lpClassName, int nMaxCount )
308 {
309 WND *wndPtr = WIN_FindWndPtr(hWnd);
310
311 if ( wndPtr == NULL )
312 return 0;
313
314 if ( wndPtr->class->bUnicode == TRUE )
315 return 0;
316
317 return lpstrncpyA(lpClassName,wndPtr->class->className, nMaxCount);
318
319 }
320
321 int GetClassNameW(HWND hWnd, LPWSTR lpClassName, int nMaxCount )
322 {
323 WND *wndPtr = WIN_FindWndPtr(hWnd);
324
325 if ( wndPtr == NULL )
326 return 0;
327
328 if ( wndPtr->class->bUnicode == FALSE )
329 return 0;
330
331 return lpstrncpyW(lpClassName,wndPtr->class->className, nMaxCount);
332
333
334 }
335
336 DWORD GetClassLongA(HWND hWnd, int nIndex )
337 {
338 WND * wndPtr;
339
340 if (!(wndPtr = WIN_FindWndPtr( hWnd ))) return 0;
341 if (nIndex >= 0)
342 {
343 if (nIndex <= wndPtr->class->cbClsExtra - sizeof(LONG))
344 return (DWORD)((char *)wndPtr->class->wExtra) + nIndex;
345 }
346 switch(nIndex)
347 {
348 case GCL_STYLE: return (LONG)wndPtr->class->style;
349 case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
350 case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
351 case GCL_HMODULE: return (LONG)wndPtr->class->hInstance;
352 case GCL_WNDPROC: return (LONG)wndPtr->class->winproc;
353 case GCL_MENUNAME: return (LONG)wndPtr->class->menuName;
354 case GCW_ATOM:
355 case GCL_HBRBACKGROUND:
356 case GCL_HCURSOR:
357 case GCL_HICON:
358 case GCL_HICONSM:
359 return GetClassWord( hWnd, nIndex );
360 default:
361 return -1;
362 }
363
364 return 0;
365 }
366
367 DWORD GetClassLongW(HWND hWnd, int nIndex )
368 {
369 WND * wndPtr;
370
371 if (!(wndPtr = WIN_FindWndPtr( hWnd ))) return 0;
372 if (nIndex >= 0)
373 {
374 if (nIndex <= wndPtr->class->cbClsExtra - sizeof(LONG))
375 return (DWORD)((char *)wndPtr->class->wExtra) + nIndex;
376 }
377 switch(nIndex)
378 {
379 case GCL_STYLE: return (LONG)wndPtr->class->style;
380 case GCL_CBWNDEXTRA: return (LONG)wndPtr->class->cbWndExtra;
381 case GCL_CBCLSEXTRA: return (LONG)wndPtr->class->cbClsExtra;
382 case GCL_HMODULE: return (LONG)wndPtr->class->hInstance;
383 case GCL_WNDPROC: return (LONG)wndPtr->class->winproc;
384 case GCL_MENUNAME: return (LONG)wndPtr->class->menuName;
385 case GCW_ATOM:
386 case GCL_HBRBACKGROUND:
387 case GCL_HCURSOR:
388 case GCL_HICON:
389 case GCL_HICONSM:
390 return GetClassWord( hWnd, nIndex );
391 default:
392 return -1;
393 }
394
395 return 0;
396 }
397
398
399
400 WORD STDCALL GetClassWord( HWND hWnd, INT nIndex )
401 {
402 WND * wndPtr;
403
404 if (!(wndPtr = WIN_FindWndPtr( hWnd ))) return 0;
405 if (nIndex >= 0)
406 {
407 if (nIndex <= wndPtr->class->cbClsExtra - sizeof(WORD))
408 return (WORD)((char *)wndPtr->class->wExtra) + nIndex;
409 }
410 else switch(nIndex)
411 {
412 //case GCW_HBRBACKGROUND: return wndPtr->class->hbrBackground;
413 //case GCW_HCURSOR: return wndPtr->class->hCursor;
414 //case GCW_HICON: return wndPtr->class->hIcon;
415 // case GCW_HICONSM: return wndPtr->class->hIconSm;
416 case GCW_ATOM: return wndPtr->class->atomName;
417 //case GCW_STYLE:
418 //case GCW_CBWNDEXTRA:
419 //case GCW_CBCLSEXTRA:
420 //case GCW_HMODULE:
421 return (WORD)GetClassLongA( hWnd, nIndex );
422 default:
423 return -1;
424 }
425
426
427 return 0;
428 }
429
430
431 CLASS *CLASS_FindClassByAtom( ATOM classAtom, HINSTANCE hInstance )
432 {
433 CLASS *p = rootClass;
434 while(p != NULL ) {
435 if ( p->atomName == classAtom )
436 return p;
437 p = p->next;
438 }
439 return NULL;
440 }
441
442
443 WINBOOL CLASS_FreeClass(CLASS *classPtr)
444 {
445 CLASS *p = rootClass;
446 if( classPtr->cWindows > 0 )
447 return FALSE;
448
449 if (classPtr->dce)
450 DeleteDC( classPtr->dce );
451 if (classPtr->hbrBackground)
452 DeleteObject( classPtr->hbrBackground );
453
454
455 classPtr->atomName = 0;
456 HeapFree(GetProcessHeap(),0,classPtr->className);
457
458 while(p != NULL && p->next != classPtr )
459 p = p->next;
460
461 if ( p != NULL )
462 p->next = classPtr->next;
463
464 HeapFree(GetProcessHeap(),0,classPtr);
465 return TRUE;
466 }
467