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
RevLine 
[10587]1/* $Id: win32class.cpp,v 1.31 2004-04-20 10:11:42 sandervl Exp $ */
[2469]2/*
3 * Win32 Window Class Managment Code for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 *
7 *
[9523]8 * Parts copied from ReWind (Get/SetClassLong for GCL_WNDPROC)
9 * Copyright 1993, 1996 Alexandre Julliard
10 * 1998 Juergen Schmied (jsch)
11 *
12 *
[2469]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 *
[10587]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
[5935]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 *
[2469]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>
[21916]34#include "win32class.h"
35#include "win32wnd.h"
36#include <win/winproc.h>
[5472]37#include <unicode.h>
[2469]38
[3153]39#define DBG_LOCALLOG DBG_win32class
[2803]40#include "dbglocal.h"
41
[21916]42static BOOL fDestroyAll = FALSE;
[2469]43
44//******************************************************************************
45//Win32WndClass methods:
46//******************************************************************************
[10587]47Win32WndClass::Win32WndClass(WNDCLASSEXA *wndclass, WNDCLASS_TYPE fClassType)
[5935]48 : GenericObject(&wndclasses, &critsect)
[2469]49{
[9523]50 this->fClassType = fClassType;
[2469]51 processId = 0;
52
[10587]53 if(HIWORD(wndclass->lpszClassName))
[9523]54 {
55 if(fClassType == WNDCLASS_UNICODE) {
[2469]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 }
[9523]71 if(fClassType == WNDCLASS_UNICODE) {
[2469]72 lstrcpyW(classNameW, (LPWSTR)wndclass->lpszClassName);
73 UnicodeToAscii(classNameW, classNameA);
74 }
75 else {
76 strcpy((char *)classNameA, wndclass->lpszClassName);
77 AsciiToUnicode(classNameA, classNameW);
78 }
[3153]79 classAtom = 0;
80 //SvL: If a system control has already be registered, use that atom instead
[2469]81 // of creating a new one
[3153]82 if(wndclass->style & CS_GLOBALCLASS) {
83 classAtom = GlobalFindAtomA(classNameA);
84 }
85 if(!classAtom) classAtom = GlobalAddAtomA(classNameA);
[2469]86 }
87 else {
88 classNameA = NULL;
89 classNameW = NULL;
90 classAtom = (DWORD)wndclass->lpszClassName;
91 }
92 if(!(wndclass->style & CS_GLOBALCLASS)) {
[6483]93 processId = GetCurrentProcessId();
[2469]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
[4585]112 dprintf(("USER32: wndclass->classAtom %x", classAtom));
113
[2469]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));
[3153]118 dprintf(("USER32: wndclass->hIconSm %X\n", wndclass->hIconSm));
[2469]119
[5242]120 nrExtraClassBytes = wndclass->cbClsExtra;
121 nrExtraWindowBytes = wndclass->cbWndExtra;
[2469]122 backgroundBrush = wndclass->hbrBackground;
123 hCursor = wndclass->hCursor;
124 hIcon = wndclass->hIcon;
125 hInstance = wndclass->hInstance;
126
[2672]127 if(wndclass->style & CS_CLASSDC) {
128 hdcClass = 0; //TODO:
129 }
130 else hdcClass = 0;
131
[2469]132 windowStyle = wndclass->style;
[2860]133
[9523]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));
[2469]143
144 //User data class words/longs
[5242]145 if(nrExtraClassBytes) {
146 userClassBytes = (char *)_smalloc(nrExtraClassBytes);
147 if(userClassBytes == NULL) {
148 dprintf(("Win32Class ctr: userClassBytes == NULL!"));
[2469]149 exit(1);
150 }
[5242]151 memset(userClassBytes, 0, nrExtraClassBytes);
[2469]152 }
[5242]153 else userClassBytes = NULL;
[2469]154
155 hIconSm = wndclass->hIconSm;
156}
157//******************************************************************************
158//******************************************************************************
159Win32WndClass::~Win32WndClass()
160{
161 if(classNameA) {
[5935]162 dprintf(("Win32WndClass dtor, destroy class %s\n", classNameA));
[2469]163 }
164
165 //SvL: Don't delete global classes
166 if(classNameA && !(windowStyle & CS_GLOBALCLASS)) {
[5935]167 GlobalDeleteAtom(classAtom);
[2469]168 }
169
[9523]170 if(pfnWindowProcA)
[21916]171 WINPROC_FreeProc((HWINDOWPROC)pfnWindowProcA, WIN_PROC_CLASS);
[9523]172 if(pfnWindowProcW)
[21916]173 WINPROC_FreeProc((HWINDOWPROC)pfnWindowProcW, WIN_PROC_CLASS);
[2469]174
[5242]175 if(userClassBytes) free(userClassBytes);
[2469]176 if(classNameA) free(classNameA);
177 if(classNameW) free(classNameW);
178 if(menuNameA && HIWORD(menuNameA)) {
[5935]179 free(menuNameA);
180 assert(menuNameW);
181 free(menuNameW);
[2469]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) {
[9523]196 return classAtom == (DWORD)classname;
[2469]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//******************************************************************************
[5935]210//Locates class in linked list and increases reference count (if found)
211//Class object must be unreferenced after usage
[2469]212//******************************************************************************
213Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPSTR id)
214{
[5935]215 lock(&critsect);
[2469]216
217 Win32WndClass *wndclass = (Win32WndClass *)wndclasses;
218
219 if(wndclass == NULL) {
[5935]220 unlock(&critsect);
[2469]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) {
[5935]227 wndclass->addRef();
228 unlock(&critsect);
[2469]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 {
[5935]240 wndclass->addRef();
241 unlock(&critsect);
[2469]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*/) {
[5935]253 wndclass->addRef();
254 unlock(&critsect);
[2469]255 return(wndclass);
256 }
257 else {
258 wndclass = (Win32WndClass *)wndclass->GetNext();
259 while(wndclass != NULL) {
260 if(wndclass->classAtom == (DWORD)id /* && wndclass->hInstance == hInstance*/) {
[5935]261 wndclass->addRef();
262 unlock(&critsect);
[2469]263 return(wndclass);
264 }
265 wndclass = (Win32WndClass *)wndclass->GetNext();
266 }
267 }
268 }
[5935]269 unlock(&critsect);
[2469]270 dprintf(("Class %X (inst %X) not found!", id, hInstance));
271 return(NULL);
272}
273//******************************************************************************
[5935]274//Locates class in linked list and increases reference count (if found)
275//Class object must be unreferenced after usage
[3702]276//******************************************************************************
277Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPWSTR id)
278{
279 LPSTR lpszClassName;
280 Win32WndClass *winclass;
281
282 if(HIWORD(id)) {
[5935]283 lpszClassName = UnicodeToAsciiString((LPWSTR)id);
[3702]284 }
[5935]285 else lpszClassName = (LPSTR)id;
[3702]286
287 winclass = FindClass(hInstance, lpszClassName);
288
289 if(HIWORD(id)) {
290 FreeAsciiString((char *)lpszClassName);
291 }
292 return winclass;
293}
294//******************************************************************************
[2469]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{
[5242]310 wndclass->cbClsExtra = nrExtraClassBytes;
311 wndclass->cbWndExtra = nrExtraWindowBytes;
[2469]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{
[5242]327 wndclass->cbClsExtra = nrExtraClassBytes;
328 wndclass->cbWndExtra = nrExtraWindowBytes;
[2469]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)) {
[7663]358 lstrcpynW(lpszClassName, classNameW, cchClassName-1);
359 return lstrlenW(lpszClassName);
[2469]360 }
361 *(ULONG *)lpszClassName = classAtom;
362 return(sizeof(ULONG));
363}
364//******************************************************************************
365//******************************************************************************
[9523]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
[10587]375 return proc;
[9523]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//******************************************************************************
[2469]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)) {
[9523]399 if(fClassType == WNDCLASS_UNICODE) {
[2469]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"));
[9523]409 DebugInt3();
410 return;
[2469]411 }
[9523]412 if(fClassType == WNDCLASS_UNICODE) {
[2469]413 lstrcpyW(menuNameW, (LPWSTR)newMenuName);
414 UnicodeToAscii(menuNameW, menuNameA);
415 }
416 else {
417 strcpy((char *)menuNameA, newMenuName);
418 AsciiToUnicode(menuNameA, menuNameW);
419 }
[5083]420
[2469]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:
[5242]433 return nrExtraClassBytes;
[2469]434 case GCL_CBWNDEXTRA:
[5242]435 return nrExtraWindowBytes;
[2469]436 case GCL_HBRBACKGROUND:
437 return backgroundBrush;
438 case GCL_HCURSOR:
439 return hCursor;
440 case GCL_HICON:
441 return hIcon;
[3153]442 case GCL_HICONSM:
443 return hIconSm;
[2469]444 case GCL_HMODULE:
445 return hInstance;
446 case GCL_MENUNAME:
[9523]447 return (fUnicode) ? (ULONG)menuNameW : (ULONG)menuNameA;
[2469]448 case GCL_STYLE:
449 return windowStyle;
450 case GCL_WNDPROC:
[9523]451 {
452 WNDPROC pfnWindowProc = pfnWindowProcA;
453
[10587]454 if(pfnWindowProcW)
[9523]455 {
[10587]456 if(!pfnWindowProc || fUnicode)
[9523]457 pfnWindowProc = pfnWindowProcW;
458 }
[21916]459 return (ULONG) WINPROC_GetProc((HWINDOWPROC)pfnWindowProc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
[9523]460 }
[2469]461 case GCW_ATOM: //TODO: does this really happen in windows?
462 SetLastError(ERROR_INVALID_PARAMETER);
463 return 0;
464 default:
[5242]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);
[2469]469 }
[5242]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));
[5084]474 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
[2469]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:
[5242]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);
[2469]490 }
[5242]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));
[5084]495 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
[2469]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?)
[5242]508 rc = nrExtraClassBytes;
509// nrExtraClassBytes = lNewVal;
[2469]510 break;
511 case GCL_CBWNDEXTRA:
[5242]512 rc = nrExtraWindowBytes;
513 nrExtraWindowBytes = lNewVal;
[2469]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;
[3153]527 case GCL_HICONSM:
528 rc = hIconSm;
529 hIconSm = lNewVal;
530 break;
[2469]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:
[9523]544 {
[5242]545 //Note: Type of SetWindowLong determines new window proc type
[4194]546 // UNLESS the new window proc has already been registered
547 // (use the old type in that case)
548 // (VERIFIED in NT 4, SP6)
[5242]549 //TODO: Is that also true for GCL_WNDPROC???????????????
[9523]550 WNDPROC *proc = &pfnWindowProcA;
551 WINDOWPROCTYPE type = (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A;
552
[10587]553 if(pfnWindowProcW)
[9523]554 {
[10587]555 if(!*proc || fUnicode)
[9523]556 proc = &pfnWindowProcW;
557 }
[21916]558 rc = (LONG)WINPROC_GetProc((HWINDOWPROC)*proc, type );
[9523]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 {
[21916]566 WINPROC_FreeProc( (HWINDOWPROC)pfnWindowProcW, WIN_PROC_CLASS );
[9523]567 pfnWindowProcW = 0;
568 }
569 else
570 {
[21916]571 WINPROC_FreeProc( (HWINDOWPROC)pfnWindowProcA, WIN_PROC_CLASS );
[9523]572 pfnWindowProcA = 0;
573 }
574 }
[2469]575 break;
[9523]576 }
[2469]577 case GCW_ATOM: //TODO: does this really happen in windows?
578 SetLastError(ERROR_INVALID_PARAMETER);
579 return 0;
580 default:
[5242]581 if(index >= 0 && index + sizeof(ULONG) <= nrExtraClassBytes) {
582 rc = *(ULONG *)(userClassBytes + index);
583 *(ULONG *)(userClassBytes + index) = lNewVal;
[4194]584 break;
[2469]585 }
[5083]586 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
[5242]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));
[2469]591 return 0;
592 }
[4194]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));
[2469]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:
[5242]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);
[2469]617 return(rc);
618 }
[5084]619 SetLastError(ERROR_INVALID_INDEX); //verified in NT4, SP6
[5242]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));
[2469]624 return 0;
625 }
626}
627//******************************************************************************
628//FIXME: Windows that still exists with this class
629//******************************************************************************
[5056]630BOOL Win32WndClass::UnregisterClassA(HINSTANCE hinst, LPSTR id)
[2469]631{
632 Win32WndClass *wndclass;
633
[5056]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
[2469]639 wndclass = FindClass(hinst, id);
640 if(wndclass) {
[5935]641 if(wndclass->getRefCount() != 1) {
642 wndclass->markDeleted();
643 RELEASE_CLASSOBJ(wndclass);
[5056]644 dprintf2(("Win32WndClass::UnregisterClassA class %x still has windows!!", id));
645 SetLastError(ERROR_CLASS_HAS_WINDOWS);
646 return FALSE;
[10587]647 }
[6612]648 wndclass->markDeleted();
[5935]649 RELEASE_CLASSOBJ(wndclass);
[10587]650
[5056]651 SetLastError(ERROR_SUCCESS);
652 return TRUE;
[2469]653 }
654 dprintf(("::UnregisterClass, couldn't find class %X!!\n", id));
[5056]655 SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
656 return FALSE;
[2469]657}
658//******************************************************************************
659//******************************************************************************
[5935]660GenericObject *Win32WndClass::wndclasses = NULL;
[10587]661VMutex Win32WndClass::critsect;
Note: See TracBrowser for help on using the repository browser.