source: trunk/src/user32/win32class.cpp

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

Merge branch gcc-kmk to trunk.

File size: 24.9 KB
Line 
1/* $Id: win32class.cpp,v 1.31 2004-04-20 10:11:42 sandervl Exp $ */
2/*
3 * Win32 Window Class Managment Code for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 *
7 *
8 * Parts copied from ReWind (Get/SetClassLong for GCL_WNDPROC)
9 * Copyright 1993, 1996 Alexandre Julliard
10 * 1998 Juergen Schmied (jsch)
11 *
12 *
13 * TODO: Right now all class atoms are global. This must be changed.
14 * TODO: Global atoms of classes with CS_GLOBALCLASS flag are not deleted
15 * Must all be changed if we want to support global app classes
16 * that can be used by other apps. (low priority)
17 *
18 * NOTE: To access a class object, you must call FindClass. This method
19 * increases the reference count of the object. When you're done
20 * with the object, you MUST call the release method!
21 * This mechanism prevents premature destruction of objects when there
22 * are still clients using it.
23 *
24 * Project Odin Software License can be found in LICENSE.TXT
25 *
26 */
27#include <os2win.h>
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31#include <stdarg.h>
32#include <assert.h>
33#include <misc.h>
34#include "win32class.h"
35#include "win32wnd.h"
36#include <win/winproc.h>
37#include <unicode.h>
38
39#define DBG_LOCALLOG DBG_win32class
40#include "dbglocal.h"
41
42static BOOL fDestroyAll = FALSE;
43
44//******************************************************************************
45//Win32WndClass methods:
46//******************************************************************************
47Win32WndClass::Win32WndClass(WNDCLASSEXA *wndclass, WNDCLASS_TYPE fClassType)
48 : GenericObject(&wndclasses, &critsect)
49{
50 this->fClassType = fClassType;
51 processId = 0;
52
53 if(HIWORD(wndclass->lpszClassName))
54 {
55 if(fClassType == WNDCLASS_UNICODE) {
56 INT len = lstrlenW((LPWSTR)wndclass->lpszClassName)+1;
57
58 classNameA = (PCHAR)_smalloc(len);
59 classNameW = (WCHAR *)_smalloc(len*sizeof(WCHAR));
60 }
61 else {
62 INT len = strlen(wndclass->lpszClassName)+1;
63
64 classNameA = (PCHAR)_smalloc(len);
65 classNameW = (WCHAR *)_smalloc(len*sizeof(WCHAR));
66 }
67 if(classNameA == NULL || classNameW == NULL) {
68 dprintf(("Win32Class ctr; classNameA/classNameW == NULL"));
69 exit(1);
70 }
71 if(fClassType == WNDCLASS_UNICODE) {
72 lstrcpyW(classNameW, (LPWSTR)wndclass->lpszClassName);
73 UnicodeToAscii(classNameW, classNameA);
74 }
75 else {
76 strcpy((char *)classNameA, wndclass->lpszClassName);
77 AsciiToUnicode(classNameA, classNameW);
78 }
79 classAtom = 0;
80 //SvL: If a system control has already be registered, use that atom instead
81 // of creating a new one
82 if(wndclass->style & CS_GLOBALCLASS) {
83 classAtom = GlobalFindAtomA(classNameA);
84 }
85 if(!classAtom) classAtom = GlobalAddAtomA(classNameA);
86 }
87 else {
88 classNameA = NULL;
89 classNameW = NULL;
90 classAtom = (DWORD)wndclass->lpszClassName;
91 }
92 if(!(wndclass->style & CS_GLOBALCLASS)) {
93 processId = GetCurrentProcessId();
94 }
95 menuNameA = 0;
96 menuNameW = 0;
97 setMenuName((LPSTR)wndclass->lpszMenuName);
98
99 dprintf(("USER32: Win32Class ctor\n"));
100 dprintf(("USER32: wndclass->style %X\n", wndclass->style));
101 dprintf(("USER32: wndclass->lpfnWndProc %X\n", wndclass->lpfnWndProc));
102 dprintf(("USER32: wndclass->cbClsExtra %X\n", wndclass->cbClsExtra));
103 dprintf(("USER32: wndclass->cbWndExtra %X\n", wndclass->cbWndExtra));
104 dprintf(("USER32: wndclass->hInstance %X\n", wndclass->hInstance));
105 dprintf(("USER32: wndclass->hIcon %X\n", wndclass->hIcon));
106 dprintf(("USER32: wndclass->hCursor %X\n", wndclass->hCursor));
107 dprintf(("USER32: wndclass->hbrBackground %X\n", wndclass->hbrBackground));
108 if(HIWORD(wndclass->lpszClassName))
109 dprintf(("USER32: wndclass->lpszClassName %s\n", classNameA));
110 else dprintf(("USER32: wndclass->lpszClassName %X\n", wndclass->lpszClassName));
111
112 dprintf(("USER32: wndclass->classAtom %x", classAtom));
113
114 if(HIWORD(wndclass->lpszMenuName)) {//convert string name identifier to numeric id
115 dprintf(("USER32: lpszMenuName %s\n", menuNameA));
116 }
117 else dprintf(("USER32: wndclass->lpszMenuName %X\n", menuNameA));
118 dprintf(("USER32: wndclass->hIconSm %X\n", wndclass->hIconSm));
119
120 nrExtraClassBytes = wndclass->cbClsExtra;
121 nrExtraWindowBytes = wndclass->cbWndExtra;
122 backgroundBrush = wndclass->hbrBackground;
123 hCursor = wndclass->hCursor;
124 hIcon = wndclass->hIcon;
125 hInstance = wndclass->hInstance;
126
127 if(wndclass->style & CS_CLASSDC) {
128 hdcClass = 0; //TODO:
129 }
130 else hdcClass = 0;
131
132 windowStyle = wndclass->style;
133
134 pfnWindowProcA = 0;
135 pfnWindowProcW = 0;
136 if(fClassType == WNDCLASS_UNICODE) {
137 WINPROC_SetProc((HWINDOWPROC *)&pfnWindowProcW, wndclass->lpfnWndProc, WIN_PROC_32W, WIN_PROC_CLASS);
138 }
139 else {
140 WINPROC_SetProc((HWINDOWPROC *)&pfnWindowProcA, wndclass->lpfnWndProc, WIN_PROC_32A, WIN_PROC_CLASS);
141 }
142 dprintf2(("Window class ptr %x/%x", pfnWindowProcA, pfnWindowProcW));
143
144 //User data class words/longs
145 if(nrExtraClassBytes) {
146 userClassBytes = (char *)_smalloc(nrExtraClassBytes);
147 if(userClassBytes == NULL) {
148 dprintf(("Win32Class ctr: userClassBytes == NULL!"));
149 exit(1);
150 }
151 memset(userClassBytes, 0, nrExtraClassBytes);
152 }
153 else userClassBytes = NULL;
154
155 hIconSm = wndclass->hIconSm;
156}
157//******************************************************************************
158//******************************************************************************
159Win32WndClass::~Win32WndClass()
160{
161 if(classNameA) {
162 dprintf(("Win32WndClass dtor, destroy class %s\n", classNameA));
163 }
164
165 //SvL: Don't delete global classes
166 if(classNameA && !(windowStyle & CS_GLOBALCLASS)) {
167 GlobalDeleteAtom(classAtom);
168 }
169
170 if(pfnWindowProcA)
171 WINPROC_FreeProc((HWINDOWPROC)pfnWindowProcA, WIN_PROC_CLASS);
172 if(pfnWindowProcW)
173 WINPROC_FreeProc((HWINDOWPROC)pfnWindowProcW, WIN_PROC_CLASS);
174
175 if(userClassBytes) free(userClassBytes);
176 if(classNameA) free(classNameA);
177 if(classNameW) free(classNameW);
178 if(menuNameA && HIWORD(menuNameA)) {
179 free(menuNameA);
180 assert(menuNameW);
181 free(menuNameW);
182 }
183}
184//******************************************************************************
185//******************************************************************************
186void Win32WndClass::DestroyAll()
187{
188 fDestroyAll = TRUE;
189 GenericObject::DestroyAll(wndclasses);
190}
191//******************************************************************************
192//******************************************************************************
193BOOL Win32WndClass::hasClassName(LPSTR classname, BOOL fUnicode)
194{
195 if(HIWORD(classname) == 0) {
196 return classAtom == (DWORD)classname;
197 }
198 if(fUnicode) {
199 if(classNameW)
200 return (lstrcmpW(classNameW, (LPWSTR)classname) == 0);
201 return FALSE;
202 }
203 else {
204 if(classNameA)
205 return (strcmp(classNameA, classname) == 0);
206 return FALSE;
207 }
208}
209//******************************************************************************
210//Locates class in linked list and increases reference count (if found)
211//Class object must be unreferenced after usage
212//******************************************************************************
213Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPSTR id)
214{
215 lock(&critsect);
216
217 Win32WndClass *wndclass = (Win32WndClass *)wndclasses;
218
219 if(wndclass == NULL) {
220 unlock(&critsect);
221 return(NULL);
222 }
223
224 if(HIWORD(id) != 0) {
225//CB: read comment below!
226 if(lstrcmpiA(wndclass->classNameA, id) == 0 && wndclass->hInstance == hInstance) {
227 wndclass->addRef();
228 unlock(&critsect);
229 return(wndclass);
230 }
231 else {
232 wndclass = (Win32WndClass *)wndclass->GetNext();
233 while(wndclass != NULL) {
234 if(lstrcmpiA(wndclass->classNameA, id) == 0)
235 {
236 //SvL: According to Wine, if the instance handle is the one of the main exe, everything is ok
237 if(hInstance == NULL || GetModuleHandleA(NULL) == hInstance ||
238 wndclass->hInstance == hInstance)
239 {
240 wndclass->addRef();
241 unlock(&critsect);
242 return(wndclass);
243 }
244 }
245 wndclass = (Win32WndClass *)wndclass->GetNext();
246 }
247 }
248 }
249 else {
250//CB: without HInstance check, test program finds class
251//CB: need more code to compare instance; convert 0 to exe module handle
252 if(wndclass->classAtom == (DWORD)id /*&& wndclass->hInstance == hInstance*/) {
253 wndclass->addRef();
254 unlock(&critsect);
255 return(wndclass);
256 }
257 else {
258 wndclass = (Win32WndClass *)wndclass->GetNext();
259 while(wndclass != NULL) {
260 if(wndclass->classAtom == (DWORD)id /* && wndclass->hInstance == hInstance*/) {
261 wndclass->addRef();
262 unlock(&critsect);
263 return(wndclass);
264 }
265 wndclass = (Win32WndClass *)wndclass->GetNext();
266 }
267 }
268 }
269 unlock(&critsect);
270 dprintf(("Class %X (inst %X) not found!", id, hInstance));
271 return(NULL);
272}
273//******************************************************************************
274//Locates class in linked list and increases reference count (if found)
275//Class object must be unreferenced after usage
276//******************************************************************************
277Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPWSTR id)
278{
279 LPSTR lpszClassName;
280 Win32WndClass *winclass;
281
282 if(HIWORD(id)) {
283 lpszClassName = UnicodeToAsciiString((LPWSTR)id);
284 }
285 else lpszClassName = (LPSTR)id;
286
287 winclass = FindClass(hInstance, lpszClassName);
288
289 if(HIWORD(id)) {
290 FreeAsciiString((char *)lpszClassName);
291 }
292 return winclass;
293}
294//******************************************************************************
295//An app can only access another process' class if it's global
296//(all system classes are global)
297//NOTE: NOT USED NOW
298//******************************************************************************
299BOOL Win32WndClass::isAppClass(ULONG curProcessId)
300{
301 if(windowStyle & CS_GLOBALCLASS)
302 return TRUE;
303
304 return curProcessId = processId;
305}
306//******************************************************************************
307//******************************************************************************
308BOOL Win32WndClass::getClassInfo(WNDCLASSEXA *wndclass)
309{
310 wndclass->cbClsExtra = nrExtraClassBytes;
311 wndclass->cbWndExtra = nrExtraWindowBytes;
312 wndclass->hbrBackground = backgroundBrush;
313 wndclass->hCursor = hCursor;
314 wndclass->hIcon = hIcon;
315 wndclass->hInstance = hInstance;
316 wndclass->lpszMenuName = (LPCTSTR)menuNameA;
317 wndclass->lpszClassName = (classNameA) ? (LPCTSTR)classNameA : (LPCTSTR)classAtom;
318 wndclass->style = windowStyle;
319 wndclass->lpfnWndProc = (WNDPROC)getClassLongA(GCL_WNDPROC, FALSE);
320 wndclass->hIconSm = hIconSm;
321 return(TRUE);
322}
323//******************************************************************************
324//******************************************************************************
325BOOL Win32WndClass::getClassInfo(WNDCLASSEXW *wndclass)
326{
327 wndclass->cbClsExtra = nrExtraClassBytes;
328 wndclass->cbWndExtra = nrExtraWindowBytes;
329 wndclass->hbrBackground = backgroundBrush;
330 wndclass->hCursor = hCursor;
331 wndclass->hIcon = hIcon;
332 wndclass->hInstance = hInstance;
333 wndclass->lpszMenuName = (LPCWSTR)menuNameW;
334 wndclass->lpszClassName = (classNameW) ? (LPCWSTR)classNameW : (LPCWSTR)classAtom;
335 wndclass->style = windowStyle;
336 wndclass->lpfnWndProc = (WNDPROC)getClassLongA(GCL_WNDPROC, TRUE);
337 wndclass->hIconSm = hIconSm;
338 return(TRUE);
339}
340//******************************************************************************
341//******************************************************************************
342ULONG Win32WndClass::getClassName(LPSTR lpszClassName, ULONG cchClassName)
343{
344 if(HIWORD(classNameA)) {
345 lstrcpynA(lpszClassName, classNameA, cchClassName-1);
346 return strlen(lpszClassName);
347 }
348 *(ULONG *)lpszClassName = classAtom;
349 return(sizeof(ULONG));
350}
351//******************************************************************************
352//******************************************************************************
353ULONG Win32WndClass::getClassName(LPWSTR lpszClassName, ULONG cchClassName)
354{
355 ULONG len;
356
357 if(HIWORD(classNameW)) {
358 lstrcpynW(lpszClassName, classNameW, cchClassName-1);
359 return lstrlenW(lpszClassName);
360 }
361 *(ULONG *)lpszClassName = classAtom;
362 return(sizeof(ULONG));
363}
364//******************************************************************************
365//******************************************************************************
366WNDPROC Win32WndClass::getWindowProc(WNDPROC_TYPE type)
367{
368 WNDPROC proc;
369
370 if(type == WNDPROC_UNICODE) {
371 proc = (pfnWindowProcW) ? pfnWindowProcW : pfnWindowProcA;
372 }
373 else proc = (pfnWindowProcA) ? pfnWindowProcA : pfnWindowProcW;
374
375 return proc;
376};
377//******************************************************************************
378//NOTE: Only to be used when a class has both ascii & unicode window procedures!
379// Otherwise use SetClassLong GCL_WNDPROC
380//******************************************************************************
381void Win32WndClass::setWindowProc(WNDPROC pfnWindowProc, WNDPROC_TYPE type)
382{
383 if(type == WNDPROC_UNICODE) {
384 WINPROC_SetProc((HWINDOWPROC *)&pfnWindowProcW, pfnWindowProc, WIN_PROC_32W, WIN_PROC_CLASS);
385 }
386 else WINPROC_SetProc((HWINDOWPROC *)&pfnWindowProcA, pfnWindowProc, WIN_PROC_32A, WIN_PROC_CLASS);
387}
388//******************************************************************************
389//******************************************************************************
390void Win32WndClass::setMenuName(LPSTR newMenuName)
391{
392 if(HIWORD(menuNameA)) {
393 free(menuNameA);
394 free(menuNameW);
395 menuNameA = 0;
396 menuNameW = 0;
397 }
398 if(HIWORD(newMenuName)) {
399 if(fClassType == WNDCLASS_UNICODE) {
400 menuNameA = (PCHAR)_smalloc(lstrlenW((LPWSTR)newMenuName)+1);
401 menuNameW = (WCHAR *)_smalloc((lstrlenW((LPWSTR)newMenuName)+1)*sizeof(WCHAR));
402 }
403 else {
404 menuNameA = (PCHAR)_smalloc(strlen(newMenuName)+1);
405 menuNameW = (WCHAR *)_smalloc((strlen(newMenuName)+1)*sizeof(WCHAR));
406 }
407 if(menuNameA == NULL || menuNameW == NULL) {
408 dprintf(("Win32Class ctr; menuName/menuNameW == NULL"));
409 DebugInt3();
410 return;
411 }
412 if(fClassType == WNDCLASS_UNICODE) {
413 lstrcpyW(menuNameW, (LPWSTR)newMenuName);
414 UnicodeToAscii(menuNameW, menuNameA);
415 }
416 else {
417 strcpy((char *)menuNameA, newMenuName);
418 AsciiToUnicode(menuNameA, menuNameW);
419 }
420
421 }
422 else {//id
423 menuNameA = (PCHAR)newMenuName;
424 menuNameW = (WCHAR *)newMenuName;
425 }
426}
427//******************************************************************************
428//******************************************************************************
429ULONG Win32WndClass::getClassLongA(int index, BOOL fUnicode)
430{
431 switch(index) {
432 case GCL_CBCLSEXTRA:
433 return nrExtraClassBytes;
434 case GCL_CBWNDEXTRA:
435 return nrExtraWindowBytes;
436 case GCL_HBRBACKGROUND:
437 return backgroundBrush;
438 case GCL_HCURSOR:
439 return hCursor;
440 case GCL_HICON:
441 return hIcon;
442 case GCL_HICONSM:
443 return hIconSm;
444 case GCL_HMODULE:
445 return hInstance;
446 case GCL_MENUNAME:
447 return (fUnicode) ? (ULONG)menuNameW : (ULONG)menuNameA;
448 case GCL_STYLE:
449 return windowStyle;
450 case GCL_WNDPROC:
451 {
452 WNDPROC pfnWindowProc = pfnWindowProcA;
453
454 if(pfnWindowProcW)
455 {
456 if(!pfnWindowProc || fUnicode)
457 pfnWindowProc = pfnWindowProcW;
458 }
459 return (ULONG) WINPROC_GetProc((HWINDOWPROC)pfnWindowProc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
460 }
461 case GCW_ATOM: //TODO: does this really happen in windows?
462 SetLastError(ERROR_INVALID_PARAMETER);
463 return 0;
464 default:
465 if(index >= 0 && index + sizeof(ULONG) <= nrExtraClassBytes) {
466 //Note: NT4, SP6 does not set the last error to 0
467 SetLastError(ERROR_SUCCESS);
468 return *(ULONG *)(userClassBytes + index);
469 }
470 if(classNameA) {
471 dprintf2(("WARNING: getClassLong %s: %d -> wrong INDEX", classNameA, index));
472 }
473 else dprintf2(("WARNING: getClassLong %d: %d -> wrong INDEX", classAtom, index));
474 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
475 return 0;
476 }
477}
478//******************************************************************************
479//******************************************************************************
480WORD Win32WndClass::getClassWord(int index)
481{
482 switch(index) {
483 case GCW_ATOM:
484 return (WORD)classAtom;
485 default:
486 if(index >= 0 && index + sizeof(WORD) <= nrExtraClassBytes) {
487 //Note: NT4, SP6 does not set the last error to 0
488 SetLastError(ERROR_SUCCESS);
489 return *(WORD *)(userClassBytes + index);
490 }
491 if(classNameA) {
492 dprintf2(("WARNING: getClassWord %s: %d -> wrong INDEX", classNameA, index));
493 }
494 else dprintf2(("WARNING: getClassWord %d: %d -> wrong INDEX", classAtom, index));
495 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
496 return 0;
497 }
498}
499//******************************************************************************
500//TODO: What effects what immediately?
501//******************************************************************************
502ULONG Win32WndClass::setClassLongA(int index, LONG lNewVal, BOOL fUnicode)
503{
504 ULONG rc;
505
506 switch(index) {
507 case GCL_CBCLSEXTRA: //TODO (doesn't affect allocated classes, so what does it do?)
508 rc = nrExtraClassBytes;
509// nrExtraClassBytes = lNewVal;
510 break;
511 case GCL_CBWNDEXTRA:
512 rc = nrExtraWindowBytes;
513 nrExtraWindowBytes = lNewVal;
514 break;
515 case GCL_HBRBACKGROUND:
516 rc = backgroundBrush;
517 backgroundBrush = lNewVal;
518 break;
519 case GCL_HCURSOR:
520 rc = hCursor;
521 hCursor = lNewVal;
522 break;
523 case GCL_HICON:
524 rc = hIcon;
525 hIcon = lNewVal;
526 break;
527 case GCL_HICONSM:
528 rc = hIconSm;
529 hIconSm = lNewVal;
530 break;
531 case GCL_HMODULE:
532 rc = hInstance;
533 hInstance = lNewVal;
534 break;
535 case GCL_MENUNAME:
536 rc = 0; //old value is meaningless (according to Wine)
537 setMenuName((LPSTR)lNewVal);
538 break;
539 case GCL_STYLE:
540 rc = windowStyle;
541 windowStyle = lNewVal;
542 break;
543 case GCL_WNDPROC:
544 {
545 //Note: Type of SetWindowLong determines new window proc type
546 // UNLESS the new window proc has already been registered
547 // (use the old type in that case)
548 // (VERIFIED in NT 4, SP6)
549 //TODO: Is that also true for GCL_WNDPROC???????????????
550 WNDPROC *proc = &pfnWindowProcA;
551 WINDOWPROCTYPE type = (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A;
552
553 if(pfnWindowProcW)
554 {
555 if(!*proc || fUnicode)
556 proc = &pfnWindowProcW;
557 }
558 rc = (LONG)WINPROC_GetProc((HWINDOWPROC)*proc, type );
559 WINPROC_SetProc((HWINDOWPROC *)proc, (WNDPROC)lNewVal, type, WIN_PROC_CLASS);
560
561 /* now free the one that we didn't set */
562 if(pfnWindowProcA && pfnWindowProcW)
563 {
564 if (proc == &pfnWindowProcA)
565 {
566 WINPROC_FreeProc( (HWINDOWPROC)pfnWindowProcW, WIN_PROC_CLASS );
567 pfnWindowProcW = 0;
568 }
569 else
570 {
571 WINPROC_FreeProc( (HWINDOWPROC)pfnWindowProcA, WIN_PROC_CLASS );
572 pfnWindowProcA = 0;
573 }
574 }
575 break;
576 }
577 case GCW_ATOM: //TODO: does this really happen in windows?
578 SetLastError(ERROR_INVALID_PARAMETER);
579 return 0;
580 default:
581 if(index >= 0 && index + sizeof(ULONG) <= nrExtraClassBytes) {
582 rc = *(ULONG *)(userClassBytes + index);
583 *(ULONG *)(userClassBytes + index) = lNewVal;
584 break;
585 }
586 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
587 if(classNameA) {
588 dprintf2(("WARNING: Win32WndClass::setClassLongA %s: %d %x -> wrong INDEX", classNameA, index, lNewVal));
589 }
590 else dprintf2(("WARNING: Win32WndClass::setClassLongA %d: %d %x -> wrong INDEX", classAtom, index, lNewVal));
591 return 0;
592 }
593 SetLastError(ERROR_SUCCESS);
594 if(classNameA) {
595 dprintf2(("Win32WndClass::setClassLongA %s: %d %x returned %x", classNameA, index, lNewVal, rc));
596 }
597 else dprintf2(("Win32WndClass::setClassLongA %d: %d %x returned %x", classAtom, index, lNewVal, rc));
598 return(rc);
599}
600//******************************************************************************
601//******************************************************************************
602WORD Win32WndClass::setClassWord(int index, WORD wNewVal)
603{
604 WORD rc;
605
606 switch(index) {
607 case GCW_ATOM:
608 rc = (WORD)classAtom;
609 classAtom = wNewVal;
610 return(rc);
611 default:
612 if(index >= 0 && index + sizeof(WORD) <= nrExtraClassBytes) {
613 rc = *(WORD *)(userClassBytes + index);
614 *(WORD *)(userClassBytes + index) = wNewVal;
615 //Note: NT4, SP6 does not set the last error to 0
616 SetLastError(ERROR_SUCCESS);
617 return(rc);
618 }
619 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
620 if(classNameA) {
621 dprintf2(("WARNING: setClassWord %s: %d %x -> wrong INDEX", classNameA, index, wNewVal));
622 }
623 else dprintf2(("WARNING: setClassWord %d: %d %x -> wrong INDEX", classAtom, index, wNewVal));
624 return 0;
625 }
626}
627//******************************************************************************
628//FIXME: Windows that still exists with this class
629//******************************************************************************
630BOOL Win32WndClass::UnregisterClassA(HINSTANCE hinst, LPSTR id)
631{
632 Win32WndClass *wndclass;
633
634 if(HIWORD(id)) {
635 dprintf(("Win32WndClass::UnregisterClassA class %s, instance %x!!", id, hinst));
636 }
637 else dprintf(("Win32WndClass::UnregisterClassA class %x, instance %x!!", id, hinst));
638
639 wndclass = FindClass(hinst, id);
640 if(wndclass) {
641 if(wndclass->getRefCount() != 1) {
642 wndclass->markDeleted();
643 RELEASE_CLASSOBJ(wndclass);
644 dprintf2(("Win32WndClass::UnregisterClassA class %x still has windows!!", id));
645 SetLastError(ERROR_CLASS_HAS_WINDOWS);
646 return FALSE;
647 }
648 wndclass->markDeleted();
649 RELEASE_CLASSOBJ(wndclass);
650
651 SetLastError(ERROR_SUCCESS);
652 return TRUE;
653 }
654 dprintf(("::UnregisterClass, couldn't find class %X!!\n", id));
655 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
656 return FALSE;
657}
658//******************************************************************************
659//******************************************************************************
660GenericObject *Win32WndClass::wndclasses = NULL;
661VMutex Win32WndClass::critsect;
Note: See TracBrowser for help on using the repository browser.