source: trunk/src/user32/windowclass.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 20.2 KB
Line 
1/* $Id: windowclass.cpp,v 1.27 2003/01/03 16:33:02 sandervl Exp $ */
2/*
3 * Win32 Window Class Code for OS/2
4 *
5 *
6 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <stdarg.h>
17#include <assert.h>
18#include <misc.h>
19#include <unicode.h>
20#include "win32class.h"
21#include "win32wbase.h"
22#include "controls.h"
23
24#define DBG_LOCALLOG DBG_windowclass
25#include "dbglocal.h"
26
27
28#include <odin.h>
29#include <odinwrap.h>
30#include <os2sel.h>
31
32ODINDEBUGCHANNEL(USER32-CLASS)
33
34
35//******************************************************************************
36//******************************************************************************
37void RegisterSystemClasses(ULONG hModule)
38{
39 dprintf(("RegisterSystemClasses\n"));
40 CONTROLS_Register();
41}
42//******************************************************************************
43//******************************************************************************
44void UnregisterSystemClasses()
45{
46 dprintf(("UnregisterSystemClasses\n"));
47 CONTROLS_Unregister();
48}
49//******************************************************************************
50//Note: RegisterClassA does NOT change the last error if successful! (verified in NT 4, SP6)
51//******************************************************************************
52ATOM WIN32API RegisterClassA(CONST WNDCLASSA *lpWndClass)
53{
54 WNDCLASSEXA wc;
55 Win32WndClass *wclass;
56
57 //CB: size new in ex structure
58 wc.cbSize = sizeof(wc);
59 memcpy(&wc.style, lpWndClass, sizeof(WNDCLASSA));
60 wc.hIconSm = 0;
61
62 wclass = Win32WndClass::FindClass(wc.hInstance, (LPSTR)wc.lpszClassName);
63 if(wclass) {
64 RELEASE_CLASSOBJ(wclass);
65 if(HIWORD(wc.lpszClassName)) {
66 dprintf(("RegisterClassA %x %s already exists", wc.hInstance, wc.lpszClassName));
67 }
68 else dprintf(("RegisterClassA %x %x already exists", wc.hInstance, wc.lpszClassName));
69 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
70 return 0;
71 }
72
73 //TODO: not destroyed when class is unregistered (neither does Wine, but that might be a bug)
74 dprintf(("RegisterClassA"));
75 int iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
76 int iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
77
78 if(wc.hIcon)
79 wc.hIconSm = CopyImage(wc.hIcon, IMAGE_ICON, iSmIconWidth, iSmIconHeight,
80 LR_COPYFROMRESOURCE);
81
82 wclass = new Win32WndClass(&wc, WNDCLASS_ASCII);
83 if(wclass == NULL) {
84 dprintf(("ERROR: RegisterClassA winclass == NULL!"));
85 DebugInt3();
86 return(0);
87 }
88 ATOM atom = wclass->getAtom();
89 RELEASE_CLASSOBJ(wclass);
90 return atom;
91}
92//******************************************************************************
93//Note: RegisterClassA does NOT change the last error if successful! (verified in NT 4, SP6)
94//******************************************************************************
95ATOM WIN32API RegisterClassExA(CONST WNDCLASSEXA *lpWndClass)
96{
97 Win32WndClass *wclass;
98
99 wclass = Win32WndClass::FindClass(lpWndClass->hInstance, (LPSTR)lpWndClass->lpszClassName);
100 if(wclass) {
101 RELEASE_CLASSOBJ(wclass);
102 if(HIWORD(lpWndClass->lpszClassName)) {
103 dprintf(("RegisterClassExA %x %s already exists", lpWndClass->hInstance, lpWndClass->lpszClassName));
104 }
105 else dprintf(("RegisterClassExA %x %x already exists", lpWndClass->hInstance, lpWndClass->lpszClassName));
106 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
107 return 0;
108 }
109
110 dprintf(("RegisterClassExA"));
111 wclass = new Win32WndClass((WNDCLASSEXA *)lpWndClass, WNDCLASS_ASCII);
112 if(wclass == NULL) {
113 dprintf(("ERROR: RegisterClassExA winclass == NULL!"));
114 DebugInt3();
115 return(0);
116 }
117 ATOM atom = wclass->getAtom();
118 RELEASE_CLASSOBJ(wclass);
119 return atom;
120}
121//******************************************************************************
122//Used for user32 control class registration only
123//******************************************************************************
124ATOM WIN32API InternalRegisterClass(LPSTR lpszClassName, DWORD dwStyle,
125 WNDPROC pfnClassA, WNDPROC pfnClassW,
126 UINT cbExtraWindowWords, LPCSTR lpszCursor,
127 HBRUSH hBrush)
128{
129 WNDCLASSEXA wc;
130 Win32WndClass *wclass;
131
132 wclass = Win32WndClass::FindClass(0, lpszClassName);
133 if(wclass) {
134 RELEASE_CLASSOBJ(wclass);
135 DebugInt3(); //this must never happen
136 dprintf(("ERROR: InternalRegisterClass %s already exists", lpszClassName));
137 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
138 return 0;
139 }
140
141 if(HIWORD(lpszClassName)) {
142 dprintf(("InternalRegisterClass %s %x %x %x %d %x %x", lpszClassName, dwStyle, pfnClassA, pfnClassW, cbExtraWindowWords, lpszCursor, hBrush));
143 }
144 else dprintf(("InternalRegisterClass %x %x %x %x %d %x %x", lpszClassName, dwStyle, pfnClassA, pfnClassW, cbExtraWindowWords, lpszCursor, hBrush));
145
146 wc.cbSize = sizeof(wc);
147 wc.style = dwStyle;
148 wc.lpfnWndProc = pfnClassA;
149 wc.cbClsExtra = 0;
150 wc.cbWndExtra = cbExtraWindowWords;
151 wc.hInstance = NULL;
152 wc.hIcon = 0;
153 wc.hCursor = LoadCursorA(0, lpszCursor);
154 wc.hbrBackground = hBrush;
155 wc.lpszMenuName = NULL;
156 wc.lpszClassName = lpszClassName;
157 wc.hIconSm = 0;
158
159 wclass = new Win32WndClass(&wc, WNDCLASS_ASCII);
160 if(wclass == NULL) {
161 dprintf(("ERROR: InternalRegisterClass winclass == NULL!"));
162 DebugInt3();
163 return(0);
164 }
165 wclass->setWindowProc(pfnClassW, WNDPROC_UNICODE);
166 ATOM atom = wclass->getAtom();
167 RELEASE_CLASSOBJ(wclass);
168 return atom;
169}
170//******************************************************************************
171//Note: RegisterClassA does NOT change the last error if successful! (verified in NT 4, SP6)
172//******************************************************************************
173ATOM WIN32API RegisterClassW(CONST WNDCLASSW * lpwc)
174{
175 ATOM rc;
176 WNDCLASSEXA wc;
177 Win32WndClass *winclass;
178
179 //CB: size new in ex structure
180 wc.cbSize = sizeof(wc);
181 memcpy(&wc.style, lpwc, sizeof(WNDCLASSA));
182 wc.hIconSm = 0;
183
184 winclass = Win32WndClass::FindClass(wc.hInstance, (LPWSTR)wc.lpszClassName);
185 if(winclass)
186 {
187 RELEASE_CLASSOBJ(winclass);
188 if(HIWORD(wc.lpszClassName)) {
189 dprintf(("RegisterClassW %x %ls already exists", wc.hInstance, wc.lpszClassName));
190 }
191 else dprintf(("RegisterClassW %x %x already exists", wc.hInstance, wc.lpszClassName));
192 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
193 return 0;
194 }
195
196 //TODO: not destroyed when class is unregistered (neither does Wine, but that might be a bug)
197 int iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
198 int iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
199
200 if(wc.hIcon)
201 wc.hIconSm = CopyImage(wc.hIcon, IMAGE_ICON, iSmIconWidth, iSmIconHeight,
202 LR_COPYFROMRESOURCE);
203
204 dprintf(("RegisterClassW"));
205 winclass = new Win32WndClass((WNDCLASSEXA *)&wc, WNDCLASS_UNICODE);
206 if(winclass == NULL) {
207 dprintf(("ERROR: RegisterClassW winclass == NULL!"));
208 DebugInt3();
209 return 0;
210 }
211 rc = winclass->getAtom();
212 RELEASE_CLASSOBJ(winclass);
213 return(rc);
214}
215//******************************************************************************
216//Note: RegisterClassA does NOT change the last error if successful! (verified in NT 4, SP6)
217//******************************************************************************
218ATOM WIN32API RegisterClassExW(CONST WNDCLASSEXW *lpwc)
219{
220 ATOM rc;
221 WNDCLASSEXA wc;
222 Win32WndClass *winclass;
223
224 memcpy(&wc, lpwc, sizeof(WNDCLASSEXA));
225
226 winclass = Win32WndClass::FindClass(wc.hInstance, (LPWSTR)wc.lpszClassName);
227 if(winclass) {
228 RELEASE_CLASSOBJ(winclass);
229 if(HIWORD(wc.lpszClassName)) {
230 dprintf(("RegisterClassExW %x %ls already exists", wc.hInstance, wc.lpszClassName));
231 }
232 else dprintf(("RegisterClassExW %x %x already exists", wc.hInstance, wc.lpszClassName));
233 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
234 return 0;
235 }
236
237 dprintf(("RegisterClassExW"));
238 winclass = new Win32WndClass((WNDCLASSEXA *)&wc, WNDCLASS_UNICODE);
239 if(winclass == NULL) {
240 dprintf(("ERROR: RegisterClassExW winclass == NULL!"));
241 DebugInt3();
242 return(0);
243 }
244 rc = winclass->getAtom();
245 RELEASE_CLASSOBJ(winclass);
246
247 return(rc);
248}
249//******************************************************************************
250//******************************************************************************
251BOOL WIN32API UnregisterClassA(LPCSTR lpszClassName, HINSTANCE hinst)
252{
253 BOOL ret;
254
255 ret = Win32WndClass::UnregisterClassA(hinst, (LPSTR)lpszClassName);
256 return ret;
257}
258//******************************************************************************
259//******************************************************************************
260BOOL WIN32API UnregisterClassW(LPCWSTR lpszClassName, HINSTANCE hinst)
261{
262 char *astring = NULL;
263 BOOL ret;
264
265 dprintf(("USER32: UnregisterClassW\n"));
266 if(HIWORD(lpszClassName) != 0) {
267 astring = UnicodeToAsciiString((LPWSTR)lpszClassName);
268 }
269 else astring = (char *)lpszClassName;
270
271 ret = Win32WndClass::UnregisterClassA(hinst, (LPSTR)astring);
272 if(HIWORD(astring) != 0)
273 FreeAsciiString((char *)astring);
274
275 return ret;
276}
277//******************************************************************************
278//******************************************************************************
279BOOL WIN32API GetClassInfoA(HINSTANCE hInstance, LPCSTR lpszClass,
280 WNDCLASSA *lpwc)
281{
282 WNDCLASSEXA wc;
283 BOOL rc;
284 Win32WndClass *wndclass;
285
286 if(HIWORD(lpszClass) != 0) {
287 dprintf(("USER32: GetClassInfoA %x %s %x", hInstance, lpszClass, lpwc));
288 }
289 else dprintf(("USER32: GetClassInfoA %x %x %x", hInstance, lpszClass, lpwc));
290
291 wndclass = Win32WndClass::FindClass(hInstance, (LPSTR)lpszClass);
292 if(wndclass) {
293 wndclass->getClassInfo(&wc);
294 RELEASE_CLASSOBJ(wndclass);
295 memcpy(lpwc, &wc.style, sizeof(WNDCLASSA));
296 SetLastError(ERROR_SUCCESS);
297 return(TRUE);
298 }
299 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
300 return(FALSE);
301}
302//******************************************************************************
303//******************************************************************************
304BOOL WIN32API GetClassInfoW(HINSTANCE hinst, LPCWSTR lpszClass, WNDCLASSW *lpwc)
305{
306 WNDCLASSEXW wc;
307 BOOL rc;
308 Win32WndClass *wndclass;
309 char *astring = NULL;
310
311 dprintf(("USER32: GetClassInfoW\n"));
312
313 if(HIWORD(lpszClass) != 0) {
314 astring = UnicodeToAsciiString((LPWSTR)lpszClass);
315 }
316 else astring = (char *)lpszClass;
317
318 wndclass = Win32WndClass::FindClass(hinst, astring);
319 if(HIWORD(astring) != 0)
320 FreeAsciiString((char *)astring);
321
322 if(wndclass) {
323 wndclass->getClassInfo(&wc);
324 RELEASE_CLASSOBJ(wndclass);
325 memcpy(lpwc, &wc.style, sizeof(WNDCLASSW));
326 SetLastError(ERROR_SUCCESS);
327 return(TRUE);
328 }
329 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
330 return(FALSE);
331}
332/****************************************************************************
333 * Name : BOOL WIN32API GetClassInfoExA
334 * Purpose : The GetClassInfoEx function retrieves information about a window
335 * class, including the handle of the small icon associated with the
336 * window class. GetClassInfo does not retrieve the handle of the small icon.
337 * Parameters: HINSTANCE hinst handle of application instance
338 * LPCTSTR lpszClass address of class name string
339 * LPWNDCLASSEX lpwcx address of structure for class data
340 * Variables :
341 * Result : If the function finds a matching class and successfully copies
342 * the data, the return value is TRUE;
343 * otherwise, it is FALSE.
344 * To get extended error information, call GetLastError.
345 * Remark : PH: does not obtain handle of the small icon
346 *****************************************************************************/
347BOOL WIN32API GetClassInfoExA(HINSTANCE hInstance, LPCTSTR lpszClass,
348 LPWNDCLASSEXA lpwcx)
349{
350 BOOL rc;
351 Win32WndClass *wndclass;
352
353 if(HIWORD(lpszClass)) {
354 dprintf(("USER32:GetClassInfoExA (%08xh,%s,%08x)",
355 hInstance, lpszClass, lpwcx));
356 }
357 else dprintf(("USER32:GetClassInfoExA (%08xh,%x,%08x)",
358 hInstance, lpszClass, lpwcx));
359
360 wndclass = Win32WndClass::FindClass(hInstance, (LPSTR)lpszClass);
361 if(wndclass) {
362 wndclass->getClassInfo(lpwcx);
363 RELEASE_CLASSOBJ(wndclass);
364 lpwcx->cbSize = sizeof(WNDCLASSEXA);
365 SetLastError(ERROR_SUCCESS);
366 return(TRUE);
367 }
368 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
369 return(FALSE);
370}
371
372
373/*****************************************************************************
374 * Name : BOOL WIN32API GetClassInfoExW
375 * Purpose : The GetClassInfoEx function retrieves information about a window
376 * class, including the handle of the small icon associated with the
377 * window class. GetClassInfo does not retrieve the handle of the small icon.
378 * Parameters: HINSTANCE hinst handle of application instance
379 * LPCWSTR lpszClass address of class name string
380 * LPWNDCLASSEX lpwcx address of structure for class data
381 * Variables :
382 * Result : If the function finds a matching class and successfully copies
383 * the data, the return value is TRUE;
384 * otherwise, it is FALSE.
385 * To get extended error information, call GetLastError.
386 * Remark : does not obtain handle of the small icon
387 *
388 *****************************************************************************/
389BOOL WIN32API GetClassInfoExW(HINSTANCE hInstance, LPCWSTR lpszClass,
390 LPWNDCLASSEXW lpwcx)
391{
392 BOOL rc;
393 Win32WndClass *wndclass;
394 char *astring = NULL;
395
396 if(HIWORD(lpszClass)) {
397 dprintf(("USER32:GetClassInfoExW (%08xh,%ls,%08x)",
398 hInstance, lpszClass, lpwcx));
399 }
400 else dprintf(("USER32:GetClassInfoExW (%08xh,%x,%08x)",
401 hInstance, lpszClass, lpwcx));
402
403 if(HIWORD(lpszClass) != 0) {
404 astring = UnicodeToAsciiString((LPWSTR)lpszClass);
405 }
406 else astring = (char *)lpszClass;
407
408 wndclass = Win32WndClass::FindClass(hInstance, astring);
409 if(HIWORD(astring) != 0)
410 FreeAsciiString((char *)astring);
411
412 if(wndclass) {
413 wndclass->getClassInfo(lpwcx);
414 RELEASE_CLASSOBJ(wndclass);
415 lpwcx->cbSize = sizeof(WNDCLASSEXW);
416 SetLastError(ERROR_SUCCESS);
417 return(TRUE);
418 }
419 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
420 return(FALSE);
421}
422//******************************************************************************
423//******************************************************************************
424int WIN32API GetClassNameA(HWND hwnd, LPSTR lpszClassName, int cchClassName)
425{
426 Win32BaseWindow *wnd;
427 int rc;
428
429 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
430 if(!wnd) {
431 dprintf(("GetClassNameA wnd == NULL"));
432 return(0);
433 }
434 *lpszClassName = 0;
435 rc = (wnd->getClass())->getClassName(lpszClassName, cchClassName);
436 RELEASE_WNDOBJ(wnd);
437 if(HIWORD(lpszClassName)) {
438 dprintf(("USER32: GetClassNameA %x %s", hwnd, lpszClassName));
439 }
440 else dprintf(("USER32: GetClassNameA %x %x", hwnd, lpszClassName));
441 return rc;
442}
443//******************************************************************************
444//******************************************************************************
445int WIN32API GetClassNameW(HWND hwnd, LPWSTR lpszClassName, int cchClassName)
446{
447 Win32BaseWindow *wnd;
448 int ret;
449
450 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
451 if(!wnd) {
452 dprintf(("GetClassNameA wnd == NULL"));
453 return(0);
454 }
455 ret = (wnd->getClass())->getClassName(lpszClassName, cchClassName);
456 RELEASE_WNDOBJ(wnd);
457 if(HIWORD(lpszClassName)) {
458 dprintf(("USER32: GetClassNameW %x %ls", hwnd, lpszClassName));
459 }
460 else dprintf(("USER32: GetClassNameW %x %x", hwnd, lpszClassName));
461 return ret;
462}
463
464/*
465 * @implemented
466 */
467INT
468WINAPI
469RealGetWindowClassW(
470 HWND hwnd,
471 LPWSTR pszType,
472 INT cchType)
473{
474 /* FIXME: Implement correct functionality of RealGetWindowClass */
475 return GetClassNameW(hwnd,pszType,cchType);
476}
477
478INT
479WINAPI
480RealGetWindowClassA(
481 HWND hwnd,
482 LPSTR pszType,
483 INT cchType)
484{
485 /* FIXME: Implement correct functionality of RealGetWindowClass */
486 return GetClassNameA(hwnd,pszType,cchType);
487}
488
489//******************************************************************************
490//******************************************************************************
491LONG WIN32API SetClassLongA(HWND hwnd, int nIndex, LONG lNewVal)
492{
493 Win32BaseWindow *wnd;
494 LONG ret;
495
496 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
497 if(!wnd) {
498 dprintf(("SetClassLongA %x %d %x wnd == NULL", hwnd, nIndex, lNewVal));
499 return(0);
500 }
501 ret = (wnd->getClass())->setClassLongA(nIndex, lNewVal);
502 RELEASE_WNDOBJ(wnd);
503 return ret;
504}
505//******************************************************************************
506//******************************************************************************
507LONG WIN32API SetClassLongW(HWND hwnd, int nIndex, LONG lNewVal)
508{
509 Win32BaseWindow *wnd;
510 LONG ret;
511
512 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
513 if(!wnd) {
514 dprintf(("SetClassLongW %x %d %x wnd == NULL", hwnd, nIndex, lNewVal));
515 return(0);
516 }
517 ret = (wnd->getClass())->setClassLongW(nIndex, lNewVal);
518 RELEASE_WNDOBJ(wnd);
519 return ret;
520}
521//******************************************************************************
522//******************************************************************************
523WORD WIN32API SetClassWord(HWND hwnd, int nIndex, WORD wNewVal)
524{
525 Win32BaseWindow *wnd;
526 LONG ret;
527
528 dprintf(("USER32: SetClassWord %x %d %x", hwnd, nIndex, (ULONG)wNewVal));
529 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
530 if(!wnd) {
531 dprintf(("SetClassWordA %x %d %x wnd == NULL", hwnd, nIndex, wNewVal));
532 return(0);
533 }
534 ret = (wnd->getClass())->setClassWord(nIndex, wNewVal);
535 RELEASE_WNDOBJ(wnd);
536 return ret;
537}
538//******************************************************************************
539//******************************************************************************
540WORD WIN32API GetClassWord(HWND hwnd, int nIndex)
541{
542 Win32BaseWindow *wnd;
543 WORD ret;
544
545 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
546 if(!wnd) {
547 dprintf(("GetClassWordA %x %d wnd == NULL", hwnd, nIndex));
548 return(0);
549 }
550 ret = (wnd->getClass())->getClassWord(nIndex);
551 RELEASE_WNDOBJ(wnd);
552 dprintf(("USER32: GetClassWord %x %d returned %x", hwnd, nIndex, (ULONG)ret));
553 return ret;
554}
555//******************************************************************************
556//******************************************************************************
557LONG WIN32API GetClassLongA(HWND hwnd, int nIndex)
558{
559 Win32BaseWindow *wnd;
560 LONG ret;
561
562 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
563 if(!wnd) {
564 dprintf(("GetClassLongA %x %d wnd == NULL", hwnd, nIndex));
565 return(0);
566 }
567 ret = (wnd->getClass())->getClassLongA(nIndex);
568 RELEASE_WNDOBJ(wnd);
569 dprintf(("USER32: GetClassLongA %x %d returned %x", hwnd, nIndex, ret));
570 return ret;
571}
572//******************************************************************************
573//******************************************************************************
574LONG WIN32API GetClassLongW(HWND hwnd, int nIndex)
575{
576 Win32BaseWindow *wnd;
577 LONG ret;
578
579 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
580 if(!wnd) {
581 dprintf(("GetClassLongW %x %d wnd == NULL", hwnd, nIndex));
582 return(0);
583 }
584 ret = (wnd->getClass())->getClassLongW(nIndex);
585 RELEASE_WNDOBJ(wnd);
586 dprintf(("USER32: GetClassLongW %x %d returned %x", hwnd, nIndex, ret));
587 return ret;
588}
589//******************************************************************************
590//******************************************************************************
Note: See TracBrowser for help on using the repository browser.