minor fixes
[reactos.git] / reactos / lib / user32 / windows / class.c
1 /* $Id: class.c,v 1.33 2003/08/19 01:03:41 weiden Exp $
2 *
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)
8 * UPDATE HISTORY:
9 * 09-05-2001 CSH Created
10 */
11 #include <windows.h>
12 #include <user32.h>
13 #include <string.h>
14 #include <stdlib.h>
15 #include <debug.h>
16 #include <window.h>
17 #include <strpool.h>
18
19 /*
20 * @implemented
21 */
22 WINBOOL
23 STDCALL
24 GetClassInfoExA(
25 HINSTANCE hinst,
26 LPCSTR lpszClass,
27 LPWNDCLASSEXA lpwcx)
28 {
29 LPWSTR str;
30 UNICODE_STRING str2;
31 WNDCLASSEXW w;
32 BOOL retval;
33 NTSTATUS Status;
34
35 if(!lpszClass || !lpwcx)
36 {
37 SetLastError(ERROR_INVALID_PARAMETER);
38 return FALSE;
39 }
40
41 if(IS_ATOM(lpszClass))
42 str = (LPWSTR)lpszClass;
43 else
44 Status = HEAP_strdupAtoW (&str, lpszClass, NULL);
45 if ( !NT_SUCCESS (Status) )
46 {
47 SetLastError (RtlNtStatusToDosError(Status));
48 return FALSE;
49 }
50
51 str2.Length = 0;
52 str2.MaximumLength = 255;
53 str2.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(), 0,
54 str2.MaximumLength * sizeof(WCHAR));
55 if(!str2.Buffer)
56 {
57 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
58 return FALSE;
59 }
60
61 w.lpszMenuName = (LPCWSTR)&str2;
62 retval = (BOOL)NtUserGetClassInfo(hinst, str, &w, TRUE, 0);
63 if(!IS_ATOM(str))
64 HEAP_free(str);
65 RtlCopyMemory ( lpwcx, &w, sizeof(WNDCLASSEXW) );
66
67 if (!IS_INTRESOURCE(w.lpszMenuName) && w.lpszMenuName)
68 {
69 lpwcx->lpszMenuName = heap_string_poolA (str2.Buffer, str2.Length);
70 }
71 RtlFreeHeap(RtlGetProcessHeap(), 0, str2.Buffer);
72 return retval;
73 }
74
75
76 /*
77 * @implemented
78 */
79 WINBOOL
80 STDCALL
81 GetClassInfoExW(
82 HINSTANCE hinst,
83 LPCWSTR lpszClass,
84 LPWNDCLASSEXW lpwcx)
85 {
86 LPWSTR str;
87 UNICODE_STRING str2;
88 WNDCLASSEXW w;
89 WINBOOL retval;
90
91 if(!lpszClass || !lpwcx)
92 {
93 SetLastError(ERROR_INVALID_PARAMETER);
94 return FALSE;
95 }
96
97 if(IS_ATOM(lpszClass))
98 str = (LPWSTR)lpszClass;
99 else
100 str = HEAP_strdupW (lpszClass, wcslen(lpszClass) );
101
102 str2.Length = 0;
103 str2.MaximumLength = 255;
104 str2.Buffer = (PWSTR)RtlAllocateHeap(RtlGetProcessHeap(), 0,
105 str2.MaximumLength * sizeof(WCHAR));
106 if(!str2.Buffer)
107 {
108 SetLastError (RtlNtStatusToDosError(STATUS_NO_MEMORY));
109 return FALSE;
110 }
111
112 w.lpszMenuName = (LPCWSTR)&str2;
113 retval = (BOOL)NtUserGetClassInfo(hinst, str, &w, TRUE, 0);
114 if(!IS_ATOM(str))
115 HEAP_free(str);
116 RtlCopyMemory ( lpwcx, &w, sizeof(WNDCLASSEXW) );
117
118 if (!IS_INTRESOURCE(w.lpszMenuName) && w.lpszMenuName)
119 {
120 lpwcx->lpszMenuName = heap_string_poolW (str2.Buffer, str2.Length);
121 }
122
123 RtlFreeHeap(RtlGetProcessHeap(), 0, str2.Buffer);
124 return retval;
125 }
126
127
128 /*
129 * @implemented
130 */
131 WINBOOL
132 STDCALL
133 GetClassInfoA(
134 HINSTANCE hInstance,
135 LPCSTR lpClassName,
136 LPWNDCLASSA lpWndClass)
137 {
138 WNDCLASSEXA w;
139 WINBOOL retval;
140
141 if(!lpClassName || !lpWndClass)
142 {
143 SetLastError(ERROR_INVALID_PARAMETER);
144 return FALSE;
145 }
146
147 retval = GetClassInfoExA(hInstance,lpClassName,&w);
148 RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSA));
149 return retval;
150 }
151
152 /*
153 * @implemented
154 */
155 WINBOOL
156 STDCALL
157 GetClassInfoW(
158 HINSTANCE hInstance,
159 LPCWSTR lpClassName,
160 LPWNDCLASSW lpWndClass)
161 {
162 WNDCLASSEXW w;
163 WINBOOL retval;
164
165 if(!lpClassName || !lpWndClass)
166 {
167 SetLastError(ERROR_INVALID_PARAMETER);
168 return FALSE;
169 }
170
171 retval = GetClassInfoExW(hInstance,lpClassName,&w);
172 RtlCopyMemory (lpWndClass,&w.style,sizeof(WNDCLASSW));
173 return retval;
174 }
175
176
177 /*
178 * @implemented
179 */
180 DWORD STDCALL
181 GetClassLongA ( HWND hWnd, int nIndex )
182 {
183 PUNICODE_STRING str;
184
185 if ( nIndex != GCL_MENUNAME )
186 {
187 return NtUserGetClassLong ( hWnd, nIndex, TRUE );
188 }
189
190 str = (PUNICODE_STRING)NtUserGetClassLong ( hWnd, nIndex, TRUE );
191 if ( IS_INTRESOURCE(str) )
192 {
193 return (DWORD)str;
194 }
195 else
196 {
197 return (DWORD)heap_string_poolA ( str->Buffer, str->Length );
198 }
199 }
200
201 /*
202 * @implemented
203 */
204 DWORD STDCALL
205 GetClassLongW ( HWND hWnd, int nIndex )
206 {
207 PUNICODE_STRING str;
208
209 if ( nIndex != GCL_MENUNAME )
210 {
211 return NtUserGetClassLong ( hWnd, nIndex, FALSE );
212 }
213
214 str = (PUNICODE_STRING)NtUserGetClassLong(hWnd, nIndex, TRUE);
215 if ( IS_INTRESOURCE(str) )
216 {
217 return (DWORD)str;
218 }
219 else
220 {
221 return (DWORD)heap_string_poolW ( str->Buffer, str->Length );
222 }
223 }
224
225
226 /*
227 * @implemented
228 */
229 int STDCALL
230 GetClassNameA(
231 HWND hWnd,
232 LPSTR lpClassName,
233 int nMaxCount)
234 {
235 int result;
236 LPWSTR ClassNameW;
237 NTSTATUS Status;
238
239 if(!lpClassName)
240 return 0;
241
242 ClassNameW = HEAP_alloc ( (nMaxCount+1)*sizeof(WCHAR) );
243
244 result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount );
245
246 Status = HEAP_strcpyWtoA ( lpClassName, ClassNameW, result );
247
248 HEAP_free ( ClassNameW );
249
250 if ( !NT_SUCCESS(Status) )
251 return 0;
252
253 return result;
254 }
255
256
257 /*
258 * @implemented
259 */
260 int
261 STDCALL
262 GetClassNameW(
263 HWND hWnd,
264 LPWSTR lpClassName,
265 int nMaxCount)
266 {
267 int result;
268 LPWSTR ClassNameW;
269
270 if(!lpClassName)
271 return 0;
272
273 ClassNameW = HEAP_alloc ( (nMaxCount+1) * sizeof(WCHAR) );
274
275 result = NtUserGetClassName ( hWnd, ClassNameW, nMaxCount );
276
277 RtlCopyMemory ( lpClassName, ClassNameW, result );
278
279 HEAP_free ( ClassNameW );
280
281 return result;
282 }
283
284
285 /*
286 * @unimplemented
287 */
288 WORD
289 STDCALL
290 GetClassWord(
291 HWND hWnd,
292 int nIndex)
293 /*
294 * NOTE: Obsoleted in 32-bit windows
295 */
296 {
297 UNIMPLEMENTED;
298 return 0;
299 }
300
301
302 /*
303 * @implemented
304 */
305 LONG
306 STDCALL
307 GetWindowLongA ( HWND hWnd, int nIndex )
308 {
309 return NtUserGetWindowLong(hWnd, nIndex, TRUE);
310 }
311
312
313 /*
314 * @implemented
315 */
316 LONG
317 STDCALL
318 GetWindowLongW(HWND hWnd, int nIndex)
319 {
320 return NtUserGetWindowLong(hWnd, nIndex, FALSE);
321 }
322
323 /*
324 * @implemented
325 */
326 WORD
327 STDCALL
328 GetWindowWord(HWND hWnd, int nIndex)
329 {
330 return (WORD)NtUserGetWindowLong(hWnd, nIndex, TRUE);
331 }
332
333 /*
334 * @implemented
335 */
336 WORD
337 STDCALL
338 SetWindowWord ( HWND hWnd,int nIndex,WORD wNewWord )
339 {
340 return (WORD)NtUserSetWindowLong ( hWnd, nIndex, (LONG)wNewWord, TRUE );
341 }
342
343 /*
344 * @implemented
345 */
346 UINT
347 STDCALL
348 RealGetWindowClassW(
349 HWND hwnd,
350 LPWSTR pszType,
351 UINT cchType)
352 {
353 /* FIXME: Implement correct functionality of RealGetWindowClass */
354 return GetClassNameW(hwnd,pszType,cchType);
355 }
356
357
358 /*
359 * @implemented
360 */
361 UINT
362 STDCALL
363 RealGetWindowClassA(
364 HWND hwnd,
365 LPSTR pszType,
366 UINT cchType)
367 {
368 /* FIXME: Implement correct functionality of RealGetWindowClass */
369 return GetClassNameA(hwnd,pszType,cchType);
370 }
371
372 /*
373 * @implemented
374 */
375 ATOM
376 STDCALL
377 RegisterClassA(CONST WNDCLASSA *lpWndClass)
378 {
379 WNDCLASSEXA Class;
380
381 if ( !lpWndClass )
382 return 0;
383
384 RtlCopyMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSA) );
385
386 Class.cbSize = sizeof(WNDCLASSEXA);
387 Class.hIconSm = INVALID_HANDLE_VALUE;
388
389 return RegisterClassExA ( &Class );
390 }
391
392 /*
393 * @implemented
394 */
395 ATOM STDCALL
396 RegisterClassExA(CONST WNDCLASSEXA *lpwcx)
397 {
398 RTL_ATOM Atom;
399 WNDCLASSEXW wndclass;
400 NTSTATUS Status;
401 LPWSTR ClassName = NULL;
402 LPWSTR MenuName = NULL;
403
404 if ( !lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA)) )
405 return 0;
406
407 if ( !lpwcx->lpszClassName )
408 return 0;
409
410 RtlCopyMemory ( &wndclass, lpwcx, sizeof(WNDCLASSEXW) );
411
412 if ( !IS_ATOM(lpwcx->lpszClassName) )
413 {
414 Status = HEAP_strdupAtoW ( &ClassName, (LPCSTR)lpwcx->lpszClassName, NULL );
415 if ( !NT_SUCCESS (Status) )
416 {
417 SetLastError (RtlNtStatusToDosError(Status));
418 return 0;
419 }
420 wndclass.lpszClassName = ClassName;
421 }
422
423 if ( !IS_INTRESOURCE(lpwcx->lpszMenuName) )
424 {
425 Status = HEAP_strdupAtoW ( &MenuName, (LPCSTR)lpwcx->lpszMenuName, NULL );
426 if ( !NT_SUCCESS (Status) )
427 {
428 if ( ClassName )
429 HEAP_free ( ClassName );
430 SetLastError (RtlNtStatusToDosError(Status));
431 return 0;
432 }
433 wndclass.lpszMenuName = MenuName;
434 }
435
436 Atom = NtUserRegisterClassExWOW ( &wndclass, FALSE, 0, 0, 0 );
437
438 /* free strings if neccessary */
439 if ( MenuName ) HEAP_free ( MenuName );
440 if ( ClassName ) HEAP_free ( ClassName );
441
442 return (ATOM)Atom;
443 }
444
445
446
447 /*
448 * @implemented
449 */
450 ATOM STDCALL
451 RegisterClassExW(CONST WNDCLASSEXW *lpwcx)
452 {
453 RTL_ATOM Atom;
454 HANDLE hHeap;
455 WNDCLASSEXW wndclass;
456 LPWSTR ClassName = NULL;
457 LPWSTR MenuName = NULL;
458
459 if ( !lpwcx || (lpwcx->cbSize != sizeof(WNDCLASSEXA)) )
460 return 0;
461
462 if ( !lpwcx->lpszClassName )
463 return 0;
464
465 hHeap = RtlGetProcessHeap();
466 RtlCopyMemory ( &wndclass, lpwcx, sizeof(WNDCLASSEXW) );
467
468 /* copy strings if needed */
469
470 if ( !IS_ATOM(lpwcx->lpszClassName) )
471 {
472 ClassName = HEAP_strdupW ( lpwcx->lpszClassName, lstrlenW(lpwcx->lpszClassName) );
473 if ( !ClassName )
474 {
475 SetLastError(RtlNtStatusToDosError(STATUS_NO_MEMORY));
476 return 0;
477 }
478 wndclass.lpszClassName = ClassName;
479 }
480
481 if ( !IS_INTRESOURCE(lpwcx->lpszMenuName) )
482 {
483 MenuName = HEAP_strdupW ( lpwcx->lpszMenuName, lstrlenW(lpwcx->lpszMenuName) );
484 if ( !MenuName )
485 {
486 if ( ClassName )
487 HEAP_free ( MenuName );
488 SetLastError(RtlNtStatusToDosError(STATUS_NO_MEMORY));
489 return 0;
490 }
491 wndclass.lpszMenuName = MenuName;
492 }
493
494 Atom = NtUserRegisterClassExWOW ( &wndclass, TRUE, 0, 0, 0 );
495
496 /* free strings if neccessary */
497 if ( MenuName ) HEAP_free ( MenuName );
498 if ( ClassName ) HEAP_free ( ClassName );
499
500 return (ATOM)Atom;
501 }
502
503 /*
504 * @implemented
505 */
506 ATOM STDCALL
507 RegisterClassW(CONST WNDCLASSW *lpWndClass)
508 {
509 WNDCLASSEXW Class;
510
511 if ( !lpWndClass )
512 return 0;
513
514 RtlCopyMemory ( &Class.style, lpWndClass, sizeof(WNDCLASSW) );
515
516 Class.cbSize = sizeof(WNDCLASSEXW);
517 Class.hIconSm = INVALID_HANDLE_VALUE;
518
519 return RegisterClassExW ( &Class );
520 }
521
522 /*
523 * @implemented
524 */
525 DWORD
526 STDCALL
527 SetClassLongA (
528 HWND hWnd,
529 int nIndex,
530 LONG dwNewLong)
531 {
532 PUNICODE_STRING str;
533 PUNICODE_STRING str2;
534
535 if ( nIndex != GCL_MENUNAME )
536 {
537 return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, TRUE );
538 }
539 if ( IS_INTRESOURCE(dwNewLong) )
540 {
541 str2 = (PUNICODE_STRING)dwNewLong;
542 }
543 else
544 {
545 RtlCreateUnicodeString ( str2, (LPWSTR)dwNewLong );
546 }
547
548 str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE);
549
550 if ( !IS_INTRESOURCE(dwNewLong) )
551 {
552 RtlFreeUnicodeString ( str2 );
553 }
554 if ( IS_INTRESOURCE(str) )
555 {
556 return (DWORD)str;
557 }
558 else
559 {
560 return (DWORD)heap_string_poolA ( str->Buffer, str->Length );
561 }
562 }
563
564
565 /*
566 * @implemented
567 */
568 DWORD
569 STDCALL
570 SetClassLongW(
571 HWND hWnd,
572 int nIndex,
573 LONG dwNewLong)
574 {
575 PUNICODE_STRING str;
576 PUNICODE_STRING str2;
577
578 if (nIndex != GCL_MENUNAME )
579 {
580 return NtUserSetClassLong ( hWnd, nIndex, dwNewLong, FALSE );
581 }
582 if ( IS_INTRESOURCE(dwNewLong) )
583 {
584 str2 = (PUNICODE_STRING)dwNewLong;
585 }
586 else
587 {
588 RtlCreateUnicodeStringFromAsciiz ( str2,(LPSTR)dwNewLong );
589 }
590
591 str = (PUNICODE_STRING)NtUserSetClassLong(hWnd, nIndex, (DWORD)str2, TRUE);
592
593 if ( !IS_INTRESOURCE(dwNewLong) )
594 {
595 RtlFreeUnicodeString(str2);
596 }
597 if ( IS_INTRESOURCE(str) )
598 {
599 return (DWORD)str;
600 }
601 else
602 {
603 return (DWORD)heap_string_poolW ( str->Buffer, str->Length );
604 }
605 }
606
607
608 /*
609 * @unimplemented
610 */
611 WORD
612 STDCALL
613 SetClassWord(
614 HWND hWnd,
615 int nIndex,
616 WORD wNewWord)
617 /*
618 * NOTE: Obsoleted in 32-bit windows
619 */
620 {
621 UNIMPLEMENTED;
622 return 0;
623 }
624
625
626 /*
627 * @implemented
628 */
629 LONG
630 STDCALL
631 SetWindowLongA(
632 HWND hWnd,
633 int nIndex,
634 LONG dwNewLong)
635 {
636 return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, TRUE);
637 }
638
639
640 /*
641 * @implemented
642 */
643 LONG
644 STDCALL
645 SetWindowLongW(
646 HWND hWnd,
647 int nIndex,
648 LONG dwNewLong)
649 {
650 return NtUserSetWindowLong(hWnd, nIndex, dwNewLong, FALSE);
651 }
652
653
654 /*
655 * @unimplemented
656 */
657 WINBOOL
658 STDCALL
659 UnregisterClassA(
660 LPCSTR lpClassName,
661 HINSTANCE hInstance)
662 {
663 UNIMPLEMENTED;
664 return FALSE;
665 }
666
667
668 /*
669 * @unimplemented
670 */
671 WINBOOL
672 STDCALL
673 UnregisterClassW(
674 LPCWSTR lpClassName,
675 HINSTANCE hInstance)
676 {
677 UNIMPLEMENTED;
678 return FALSE;
679 }
680
681 /* EOF */