source: trunk/src/user32/windowclass.cpp@ 7663

Last change on this file since 7663 was 7663, checked in by sandervl, 24 years ago

GetClassNameW fix; return size in characters and truncate name if not enough room in buffer

File size: 18.6 KB
Line 
1/* $Id: windowclass.cpp,v 1.24 2001-12-20 20:45:56 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//******************************************************************************
52
53ODINFUNCTION1(ATOM, RegisterClassA,
54 CONST WNDCLASSA *, lpWndClass)
55{
56 WNDCLASSEXA wc;
57 Win32WndClass *wclass;
58
59 //CB: size new in ex structure
60 wc.cbSize = sizeof(wc);
61 memcpy(&wc.style, lpWndClass, sizeof(WNDCLASSA));
62 wc.hIconSm = 0;
63
64 wclass = Win32WndClass::FindClass(wc.hInstance, (LPSTR)wc.lpszClassName);
65 if(wclass) {
66 RELEASE_CLASSOBJ(wclass);
67 if(HIWORD(wc.lpszClassName)) {
68 dprintf(("RegisterClassA %x %s already exists", wc.hInstance, wc.lpszClassName));
69 }
70 else dprintf(("RegisterClassA %x %x already exists", wc.hInstance, wc.lpszClassName));
71 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
72 return 0;
73 }
74
75 //TODO: not destroyed when class is unregistered (neither does Wine, but that might be a bug)
76 dprintf(("RegisterClassA"));
77 int iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
78 int iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
79
80 if(wc.hIcon)
81 wc.hIconSm = CopyImage(wc.hIcon, IMAGE_ICON, iSmIconWidth, iSmIconHeight,
82 LR_COPYFROMRESOURCE);
83
84 wclass = new Win32WndClass(&wc,FALSE);
85 if(wclass == NULL) {
86 dprintf(("ERROR: RegisterClassA winclass == NULL!"));
87 DebugInt3();
88 return(0);
89 }
90 ATOM atom = wclass->getAtom();
91 RELEASE_CLASSOBJ(wclass);
92 return atom;
93}
94//******************************************************************************
95//Note: RegisterClassA does NOT change the last error if successful! (verified in NT 4, SP6)
96//******************************************************************************
97ODINFUNCTION1(ATOM, RegisterClassExA,
98 CONST WNDCLASSEXA *, lpWndClass)
99{
100 Win32WndClass *wclass;
101
102 wclass = Win32WndClass::FindClass(lpWndClass->hInstance, (LPSTR)lpWndClass->lpszClassName);
103 if(wclass) {
104 RELEASE_CLASSOBJ(wclass);
105 if(HIWORD(lpWndClass->lpszClassName)) {
106 dprintf(("RegisterClassExA %x %s already exists", lpWndClass->hInstance, lpWndClass->lpszClassName));
107 }
108 else dprintf(("RegisterClassExA %x %x already exists", lpWndClass->hInstance, lpWndClass->lpszClassName));
109 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
110 return 0;
111 }
112
113 dprintf(("RegisterClassExA"));
114 wclass = new Win32WndClass((WNDCLASSEXA *)lpWndClass,FALSE);
115 if(wclass == NULL) {
116 dprintf(("ERROR: RegisterClassExA winclass == NULL!"));
117 DebugInt3();
118 return(0);
119 }
120 ATOM atom = wclass->getAtom();
121 RELEASE_CLASSOBJ(wclass);
122 return atom;
123}
124//******************************************************************************
125//Note: RegisterClassA does NOT change the last error if successful! (verified in NT 4, SP6)
126//******************************************************************************
127ODINFUNCTION1(ATOM, RegisterClassW,
128 CONST WNDCLASSW *, lpwc)
129{
130 ATOM rc;
131 WNDCLASSEXA wc;
132 Win32WndClass *winclass;
133
134 //CB: size new in ex structure
135 wc.cbSize = sizeof(wc);
136 memcpy(&wc.style, lpwc, sizeof(WNDCLASSA));
137
138 winclass = Win32WndClass::FindClass(wc.hInstance, (LPWSTR)wc.lpszClassName);
139 if(winclass) {
140 RELEASE_CLASSOBJ(winclass);
141 if(HIWORD(wc.lpszClassName)) {
142 dprintf(("RegisterClassW %x %ls already exists", wc.hInstance, wc.lpszClassName));
143 }
144 else dprintf(("RegisterClassW %x %x already exists", wc.hInstance, wc.lpszClassName));
145 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
146 return 0;
147 }
148
149 //TODO: not destroyed when class is unregistered (neither does Wine, but that might be a bug)
150 int iSmIconWidth = GetSystemMetrics(SM_CXSMICON);
151 int iSmIconHeight = GetSystemMetrics(SM_CYSMICON);
152
153 if(wc.hIcon)
154 wc.hIconSm = CopyImage(wc.hIcon, IMAGE_ICON, iSmIconWidth, iSmIconHeight,
155 LR_COPYFROMRESOURCE);
156
157 dprintf(("RegisterClassW"));
158 winclass = new Win32WndClass((WNDCLASSEXA *)&wc, TRUE);
159 if(winclass == NULL) {
160 dprintf(("ERROR: RegisterClassW winclass == NULL!"));
161 DebugInt3();
162 return 0;
163 }
164 rc = winclass->getAtom();
165 RELEASE_CLASSOBJ(winclass);
166 return(rc);
167}
168//******************************************************************************
169//Note: RegisterClassA does NOT change the last error if successful! (verified in NT 4, SP6)
170//******************************************************************************
171ODINFUNCTION1(ATOM, RegisterClassExW,
172 CONST WNDCLASSEXW *, lpwc)
173{
174 ATOM rc;
175 WNDCLASSEXA wc;
176 Win32WndClass *winclass;
177
178 memcpy(&wc, lpwc, sizeof(WNDCLASSEXA));
179
180 winclass = Win32WndClass::FindClass(wc.hInstance, (LPWSTR)wc.lpszClassName);
181 if(winclass) {
182 RELEASE_CLASSOBJ(winclass);
183 if(HIWORD(wc.lpszClassName)) {
184 dprintf(("RegisterClassExW %x %ls already exists", wc.hInstance, wc.lpszClassName));
185 }
186 else dprintf(("RegisterClassExW %x %x already exists", wc.hInstance, wc.lpszClassName));
187 SetLastError(ERROR_CLASS_ALREADY_EXISTS);
188 return 0;
189 }
190
191 dprintf(("RegisterClassExW"));
192 winclass = new Win32WndClass((WNDCLASSEXA *)&wc, TRUE);
193 if(winclass == NULL) {
194 dprintf(("ERROR: RegisterClassExW winclass == NULL!"));
195 DebugInt3();
196 return(0);
197 }
198 rc = winclass->getAtom();
199 RELEASE_CLASSOBJ(winclass);
200
201 return(rc);
202}
203//******************************************************************************
204//******************************************************************************
205ODINFUNCTION2(BOOL, UnregisterClassA,
206 LPCSTR, lpszClassName,
207 HINSTANCE, hinst)
208{
209 BOOL ret;
210
211 ret = Win32WndClass::UnregisterClassA(hinst, (LPSTR)lpszClassName);
212 return ret;
213}
214//******************************************************************************
215//******************************************************************************
216ODINFUNCTION2(BOOL, UnregisterClassW,
217 LPCWSTR, lpszClassName,
218 HINSTANCE, hinst)
219{
220 char *astring = NULL;
221 BOOL ret;
222
223 dprintf(("USER32: UnregisterClassW\n"));
224 if(HIWORD(lpszClassName) != 0) {
225 astring = UnicodeToAsciiString((LPWSTR)lpszClassName);
226 }
227 else astring = (char *)lpszClassName;
228
229 ret = Win32WndClass::UnregisterClassA(hinst, (LPSTR)astring);
230 if(HIWORD(astring) != 0)
231 FreeAsciiString((char *)astring);
232
233 return ret;
234}
235//******************************************************************************
236//******************************************************************************
237ODINFUNCTION3(BOOL, GetClassInfoA,
238 HINSTANCE, hInstance,
239 LPCSTR, lpszClass,
240 WNDCLASSA *, lpwc)
241{
242 WNDCLASSEXA wc;
243 BOOL rc;
244 Win32WndClass *wndclass;
245
246 if(HIWORD(lpszClass) != 0) {
247 dprintf(("USER32: GetClassInfoA %x %s %x", hInstance, lpszClass, lpwc));
248 }
249 else dprintf(("USER32: GetClassInfoA %x %x %x", hInstance, lpszClass, lpwc));
250
251 wndclass = Win32WndClass::FindClass(hInstance, (LPSTR)lpszClass);
252 if(wndclass) {
253 wndclass->getClassInfo(&wc);
254 RELEASE_CLASSOBJ(wndclass);
255 memcpy(lpwc, &wc.style, sizeof(WNDCLASSA));
256 SetLastError(ERROR_SUCCESS);
257 return(TRUE);
258 }
259 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
260 return(FALSE);
261}
262//******************************************************************************
263//******************************************************************************
264ODINFUNCTION3(BOOL, GetClassInfoW,
265 HINSTANCE, hinst,
266 LPCWSTR, lpszClass,
267 WNDCLASSW *, lpwc)
268{
269 WNDCLASSEXW wc;
270 BOOL rc;
271 Win32WndClass *wndclass;
272 char *astring = NULL;
273
274 dprintf(("USER32: GetClassInfoW\n"));
275
276 if(HIWORD(lpszClass) != 0) {
277 astring = UnicodeToAsciiString((LPWSTR)lpszClass);
278 }
279 else astring = (char *)lpszClass;
280
281 wndclass = Win32WndClass::FindClass(hinst, astring);
282 if(HIWORD(astring) != 0)
283 FreeAsciiString((char *)astring);
284
285 if(wndclass) {
286 wndclass->getClassInfo(&wc);
287 RELEASE_CLASSOBJ(wndclass);
288 memcpy(lpwc, &wc.style, sizeof(WNDCLASSW));
289 SetLastError(ERROR_SUCCESS);
290 return(TRUE);
291 }
292 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
293 return(FALSE);
294}
295/****************************************************************************
296 * Name : BOOL WIN32API GetClassInfoExA
297 * Purpose : The GetClassInfoEx function retrieves information about a window
298 * class, including the handle of the small icon associated with the
299 * window class. GetClassInfo does not retrieve the handle of the small icon.
300 * Parameters: HINSTANCE hinst handle of application instance
301 * LPCTSTR lpszClass address of class name string
302 * LPWNDCLASSEX lpwcx address of structure for class data
303 * Variables :
304 * Result : If the function finds a matching class and successfully copies
305 * the data, the return value is TRUE;
306 * otherwise, it is FALSE.
307 * To get extended error information, call GetLastError.
308 * Remark : PH: does not obtain handle of the small icon
309 *****************************************************************************/
310ODINFUNCTION3(BOOL, GetClassInfoExA,
311 HINSTANCE, hInstance,
312 LPCTSTR, lpszClass,
313 LPWNDCLASSEXA, lpwcx)
314{
315 BOOL rc;
316 Win32WndClass *wndclass;
317
318 if(HIWORD(lpszClass)) {
319 dprintf(("USER32:GetClassInfoExA (%08xh,%s,%08x)",
320 hInstance, lpszClass, lpwcx));
321 }
322 else dprintf(("USER32:GetClassInfoExA (%08xh,%x,%08x)",
323 hInstance, lpszClass, lpwcx));
324
325 wndclass = Win32WndClass::FindClass(hInstance, (LPSTR)lpszClass);
326 if(wndclass) {
327 wndclass->getClassInfo(lpwcx);
328 RELEASE_CLASSOBJ(wndclass);
329 lpwcx->cbSize = sizeof(WNDCLASSEXA);
330 SetLastError(ERROR_SUCCESS);
331 return(TRUE);
332 }
333 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
334 return(FALSE);
335}
336
337
338/*****************************************************************************
339 * Name : BOOL WIN32API GetClassInfoExW
340 * Purpose : The GetClassInfoEx function retrieves information about a window
341 * class, including the handle of the small icon associated with the
342 * window class. GetClassInfo does not retrieve the handle of the small icon.
343 * Parameters: HINSTANCE hinst handle of application instance
344 * LPCWSTR lpszClass address of class name string
345 * LPWNDCLASSEX lpwcx address of structure for class data
346 * Variables :
347 * Result : If the function finds a matching class and successfully copies
348 * the data, the return value is TRUE;
349 * otherwise, it is FALSE.
350 * To get extended error information, call GetLastError.
351 * Remark : does not obtain handle of the small icon
352 *
353 *****************************************************************************/
354
355ODINFUNCTION3(BOOL, GetClassInfoExW,
356 HINSTANCE, hInstance,
357 LPCWSTR, lpszClass,
358 LPWNDCLASSEXW, lpwcx)
359{
360 BOOL rc;
361 Win32WndClass *wndclass;
362 char *astring = NULL;
363
364 if(HIWORD(lpszClass)) {
365 dprintf(("USER32:GetClassInfoExW (%08xh,%ls,%08x)",
366 hInstance, lpszClass, lpwcx));
367 }
368 else dprintf(("USER32:GetClassInfoExW (%08xh,%x,%08x)",
369 hInstance, lpszClass, lpwcx));
370
371 if(HIWORD(lpszClass) != 0) {
372 astring = UnicodeToAsciiString((LPWSTR)lpszClass);
373 }
374 else astring = (char *)lpszClass;
375
376 wndclass = Win32WndClass::FindClass(hInstance, astring);
377 if(HIWORD(astring) != 0)
378 FreeAsciiString((char *)astring);
379
380 if(wndclass) {
381 wndclass->getClassInfo(lpwcx);
382 RELEASE_CLASSOBJ(wndclass);
383 lpwcx->cbSize = sizeof(WNDCLASSEXW);
384 SetLastError(ERROR_SUCCESS);
385 return(TRUE);
386 }
387 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
388 return(FALSE);
389}
390//******************************************************************************
391//******************************************************************************
392ODINFUNCTION3(int, GetClassNameA,
393 HWND, hwnd,
394 LPSTR, lpszClassName,
395 int, cchClassName)
396{
397 Win32BaseWindow *wnd;
398 int rc;
399
400 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
401 if(!wnd) {
402 dprintf(("GetClassNameA wnd == NULL"));
403 return(0);
404 }
405 *lpszClassName = 0;
406 rc = (wnd->getClass())->getClassName(lpszClassName, cchClassName);
407 RELEASE_WNDOBJ(wnd);
408 if(HIWORD(lpszClassName)) {
409 dprintf(("USER32: GetClassNameA %x %s", hwnd, lpszClassName));
410 }
411 else dprintf(("USER32: GetClassNameA %x %x", hwnd, lpszClassName));
412 return rc;
413}
414//******************************************************************************
415//******************************************************************************
416ODINFUNCTION3(int, GetClassNameW,
417 HWND, hwnd,
418 LPWSTR, lpszClassName,
419 int, cchClassName)
420{
421 Win32BaseWindow *wnd;
422 int ret;
423
424 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
425 if(!wnd) {
426 dprintf(("GetClassNameA wnd == NULL"));
427 return(0);
428 }
429 ret = (wnd->getClass())->getClassName(lpszClassName, cchClassName);
430 RELEASE_WNDOBJ(wnd);
431 if(HIWORD(lpszClassName)) {
432 dprintf(("USER32: GetClassNameW %x %ls", hwnd, lpszClassName));
433 }
434 else dprintf(("USER32: GetClassNameW %x %x", hwnd, lpszClassName));
435 return ret;
436}
437//******************************************************************************
438//******************************************************************************
439ODINFUNCTION3(LONG, SetClassLongA,
440 HWND, hwnd,
441 int, nIndex,
442 LONG, lNewVal)
443{
444 Win32BaseWindow *wnd;
445 LONG ret;
446
447 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
448 if(!wnd) {
449 dprintf(("SetClassLongA %x %d %x wnd == NULL", hwnd, nIndex, lNewVal));
450 return(0);
451 }
452 ret = (wnd->getClass())->setClassLongA(nIndex, lNewVal);
453 RELEASE_WNDOBJ(wnd);
454 return ret;
455}
456//******************************************************************************
457//******************************************************************************
458ODINFUNCTION3(LONG, SetClassLongW,
459 HWND, hwnd,
460 int, nIndex,
461 LONG, lNewVal)
462{
463 Win32BaseWindow *wnd;
464 LONG ret;
465
466 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
467 if(!wnd) {
468 dprintf(("SetClassLongW %x %d %x wnd == NULL", hwnd, nIndex, lNewVal));
469 return(0);
470 }
471 ret = (wnd->getClass())->setClassLongW(nIndex, lNewVal);
472 RELEASE_WNDOBJ(wnd);
473 return ret;
474}
475//******************************************************************************
476//******************************************************************************
477ODINFUNCTION3(WORD, SetClassWord,
478 HWND, hwnd,
479 int, nIndex,
480 WORD, wNewVal)
481{
482 Win32BaseWindow *wnd;
483 LONG ret;
484
485 dprintf(("USER32: SetClassWord %x %d %x", hwnd, nIndex, (ULONG)wNewVal));
486 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
487 if(!wnd) {
488 dprintf(("SetClassWordA %x %d %x wnd == NULL", hwnd, nIndex, wNewVal));
489 return(0);
490 }
491 ret = (wnd->getClass())->setClassWord(nIndex, wNewVal);
492 RELEASE_WNDOBJ(wnd);
493 return ret;
494}
495//******************************************************************************
496//******************************************************************************
497ODINFUNCTION2(WORD, GetClassWord,
498 HWND, hwnd,
499 int, nIndex)
500{
501 Win32BaseWindow *wnd;
502 WORD ret;
503
504 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
505 if(!wnd) {
506 dprintf(("GetClassWordA %x %d wnd == NULL", hwnd, nIndex));
507 return(0);
508 }
509 ret = (wnd->getClass())->getClassWord(nIndex);
510 RELEASE_WNDOBJ(wnd);
511 dprintf(("USER32: GetClassWord %x %d returned %x", hwnd, nIndex, (ULONG)ret));
512 return ret;
513}
514//******************************************************************************
515//******************************************************************************
516ODINFUNCTION2(LONG, GetClassLongA,
517 HWND, hwnd,
518 int, nIndex)
519{
520 Win32BaseWindow *wnd;
521 LONG ret;
522
523 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
524 if(!wnd) {
525 dprintf(("GetClassLongA %x %d wnd == NULL", hwnd, nIndex));
526 return(0);
527 }
528 ret = (wnd->getClass())->getClassLongA(nIndex);
529 RELEASE_WNDOBJ(wnd);
530 dprintf(("USER32: GetClassLongA %x %d returned %x", hwnd, nIndex, ret));
531 return ret;
532}
533//******************************************************************************
534//******************************************************************************
535ODINFUNCTION2(LONG, GetClassLongW,
536 HWND, hwnd,
537 int, nIndex)
538{
539 Win32BaseWindow *wnd;
540 LONG ret;
541
542 wnd = Win32BaseWindow::GetWindowFromHandle(hwnd);
543 if(!wnd) {
544 dprintf(("GetClassLongW %x %d wnd == NULL", hwnd, nIndex));
545 return(0);
546 }
547 ret = (wnd->getClass())->getClassLongW(nIndex);
548 RELEASE_WNDOBJ(wnd);
549 dprintf(("USER32: GetClassLongW %x %d returned %x", hwnd, nIndex, ret));
550 return ret;
551}
552//******************************************************************************
553//******************************************************************************
Note: See TracBrowser for help on using the repository browser.