Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

win32class.cpp

Go to the documentation of this file.
00001 /* $Id: win32class.cpp,v 1.29 2001/12/20 20:45:55 sandervl Exp $ */
00002 /*
00003  * Win32 Window Class Managment Code for OS/2
00004  *
00005  * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
00006  *
00007  *
00008  * TODO: Right now all class atoms are global. This must be changed.
00009  * TODO: Global atoms of classes with CS_GLOBALCLASS flag are not deleted
00010  *       Must all be changed if we want to support global app classes
00011  *       that can be used by other apps. (low priority)
00012  *
00013  * NOTE: To access a class object, you must call FindClass. This method 
00014  *       increases the reference count of the object. When you're done 
00015  *       with the object, you MUST call the release method!
00016  *       This mechanism prevents premature destruction of objects when there
00017  *       are still clients using it.
00018  *
00019  * Project Odin Software License can be found in LICENSE.TXT
00020  *
00021  */
00022 #include <os2win.h>
00023 #include <stdio.h>
00024 #include <stdlib.h>
00025 #include <string.h>
00026 #include <stdarg.h>
00027 #include <assert.h>
00028 #include <misc.h>
00029 #include <win32class.h>
00030 #include <win32wnd.h>
00031 #include <win\winproc.h>
00032 #include <unicode.h>
00033 
00034 #define DBG_LOCALLOG    DBG_win32class
00035 #include "dbglocal.h"
00036 
00037 static fDestroyAll = FALSE;
00038 
00039 //******************************************************************************
00040 //Win32WndClass methods:
00041 //******************************************************************************
00042 Win32WndClass::Win32WndClass(WNDCLASSEXA *wndclass, BOOL fUnicode) 
00043                   : GenericObject(&wndclasses, &critsect)
00044 {
00045   isUnicode = fUnicode;
00046   processId = 0;
00047 
00048   if(HIWORD(wndclass->lpszClassName)) {
00049         if(isUnicode) {
00050                 INT len = lstrlenW((LPWSTR)wndclass->lpszClassName)+1;
00051 
00052                 classNameA = (PCHAR)_smalloc(len);
00053                 classNameW = (WCHAR *)_smalloc(len*sizeof(WCHAR));
00054         }
00055         else {
00056                 INT len = strlen(wndclass->lpszClassName)+1;
00057 
00058                 classNameA = (PCHAR)_smalloc(len);
00059                 classNameW = (WCHAR *)_smalloc(len*sizeof(WCHAR));
00060         }
00061         if(classNameA == NULL || classNameW == NULL) {
00062                 dprintf(("Win32Class ctr; classNameA/classNameW == NULL"));
00063                 exit(1);
00064         }
00065         if(isUnicode) {
00066                 lstrcpyW(classNameW, (LPWSTR)wndclass->lpszClassName);
00067                 UnicodeToAscii(classNameW, classNameA);
00068         }
00069         else {
00070                 strcpy((char *)classNameA, wndclass->lpszClassName);
00071                 AsciiToUnicode(classNameA, classNameW);
00072         }
00073         classAtom = 0;
00074         //SvL: If a system control has already be registered, use that atom instead
00075         //     of creating a new one
00076         if(wndclass->style & CS_GLOBALCLASS) {
00077                 classAtom = GlobalFindAtomA(classNameA);
00078         }
00079         if(!classAtom) classAtom = GlobalAddAtomA(classNameA);
00080   }
00081   else {
00082         classNameA      = NULL;
00083         classNameW      = NULL;
00084         classAtom       = (DWORD)wndclass->lpszClassName;
00085   }
00086   if(!(wndclass->style & CS_GLOBALCLASS)) {
00087         processId = GetCurrentProcessId();
00088   }
00089   menuNameA = 0;
00090   menuNameW = 0;
00091   setMenuName((LPSTR)wndclass->lpszMenuName);
00092 
00093   dprintf(("USER32:  Win32Class ctor\n"));
00094   dprintf(("USER32:  wndclass->style %X\n", wndclass->style));
00095   dprintf(("USER32:  wndclass->lpfnWndProc %X\n", wndclass->lpfnWndProc));
00096   dprintf(("USER32:  wndclass->cbClsExtra %X\n", wndclass->cbClsExtra));
00097   dprintf(("USER32:  wndclass->cbWndExtra %X\n", wndclass->cbWndExtra));
00098   dprintf(("USER32:  wndclass->hInstance %X\n", wndclass->hInstance));
00099   dprintf(("USER32:  wndclass->hIcon %X\n", wndclass->hIcon));
00100   dprintf(("USER32:  wndclass->hCursor %X\n", wndclass->hCursor));
00101   dprintf(("USER32:  wndclass->hbrBackground %X\n", wndclass->hbrBackground));
00102   if(HIWORD(wndclass->lpszClassName))
00103        dprintf(("USER32:  wndclass->lpszClassName %s\n", classNameA));
00104   else dprintf(("USER32:  wndclass->lpszClassName %X\n", wndclass->lpszClassName));
00105 
00106   dprintf(("USER32:  wndclass->classAtom %x", classAtom));
00107 
00108   if(HIWORD(wndclass->lpszMenuName)) {//convert string name identifier to numeric id
00109        dprintf(("USER32:  lpszMenuName %s\n", menuNameA));
00110   }
00111   else dprintf(("USER32:  wndclass->lpszMenuName %X\n", menuNameA));
00112   dprintf(("USER32:  wndclass->hIconSm %X\n", wndclass->hIconSm));
00113 
00114   nrExtraClassBytes     = wndclass->cbClsExtra;
00115   nrExtraWindowBytes    = wndclass->cbWndExtra;
00116   backgroundBrush       = wndclass->hbrBackground;
00117   hCursor               = wndclass->hCursor;
00118   hIcon                 = wndclass->hIcon;
00119   hInstance             = wndclass->hInstance;
00120 
00121   if(wndclass->style & CS_CLASSDC) {
00122         hdcClass = 0; //TODO:
00123   }
00124   else  hdcClass = 0;
00125 
00126   windowStyle           = wndclass->style;
00127 
00128   windowProc = 0;
00129   WINPROC_SetProc((HWINDOWPROC *)&windowProc, wndclass->lpfnWndProc, (isUnicode) ? WIN_PROC_32W : WIN_PROC_32A, WIN_PROC_CLASS);
00130   dprintf2(("Window class ptr %x", windowProc));
00131 
00132   //User data class words/longs
00133   if(nrExtraClassBytes) {
00134         userClassBytes = (char *)_smalloc(nrExtraClassBytes);
00135         if(userClassBytes == NULL) {
00136                 dprintf(("Win32Class ctr: userClassBytes == NULL!"));
00137                 exit(1);
00138         }
00139         memset(userClassBytes, 0, nrExtraClassBytes);
00140   }
00141   else  userClassBytes = NULL;
00142 
00143   hIconSm  = wndclass->hIconSm;
00144 }
00145 //******************************************************************************
00146 //******************************************************************************
00147 Win32WndClass::~Win32WndClass()
00148 {
00149   if(classNameA) {
00150       dprintf(("Win32WndClass dtor, destroy class %s\n", classNameA));
00151   }
00152 
00153   //SvL: Don't delete global classes
00154   if(classNameA && !(windowStyle & CS_GLOBALCLASS)) {
00155       GlobalDeleteAtom(classAtom);
00156   }
00157 
00158   WINPROC_FreeProc(windowProc, WIN_PROC_CLASS);
00159 
00160   if(userClassBytes)    free(userClassBytes);
00161   if(classNameA)        free(classNameA);
00162   if(classNameW)        free(classNameW);
00163   if(menuNameA && HIWORD(menuNameA)) {
00164       free(menuNameA);
00165       assert(menuNameW);
00166       free(menuNameW);
00167   }
00168 }
00169 //******************************************************************************
00170 //******************************************************************************
00171 void Win32WndClass::DestroyAll()
00172 {
00173     fDestroyAll = TRUE;
00174     GenericObject::DestroyAll(wndclasses);
00175 }
00176 //******************************************************************************
00177 //******************************************************************************
00178 BOOL Win32WndClass::hasClassName(LPSTR classname, BOOL fUnicode)
00179 {
00180   if(HIWORD(classname) == 0) {
00181     return classAtom == (DWORD)classname;
00182   }
00183   if(fUnicode) {
00184         if(classNameW)
00185             return (lstrcmpW(classNameW, (LPWSTR)classname) == 0);
00186         return FALSE;
00187   }
00188   else {
00189         if(classNameA)
00190             return (strcmp(classNameA, classname) == 0);
00191         return FALSE;
00192   }
00193 }
00194 //******************************************************************************
00195 //Locates class in linked list and increases reference count (if found)
00196 //Class object must be unreferenced after usage
00197 //******************************************************************************
00198 Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPSTR id)
00199 {
00200   lock(&critsect);
00201 
00202   Win32WndClass *wndclass = (Win32WndClass *)wndclasses;
00203 
00204   if(wndclass == NULL) {
00205         unlock(&critsect);
00206         return(NULL);
00207   }
00208 
00209   if(HIWORD(id) != 0) {
00210 //CB: read comment below!
00211         if(lstrcmpiA(wndclass->classNameA, id) == 0 && wndclass->hInstance == hInstance) {
00212                 wndclass->addRef();
00213                 unlock(&critsect);
00214                 return(wndclass);
00215         }
00216         else {
00217                 wndclass = (Win32WndClass *)wndclass->GetNext();
00218                 while(wndclass != NULL) {
00219                         if(lstrcmpiA(wndclass->classNameA, id) == 0)
00220                         {
00221                                 //SvL: According to Wine, if the instance handle is the one of the main exe, everything is ok
00222                                 if(hInstance == NULL || GetModuleHandleA(NULL) == hInstance ||
00223                                    wndclass->hInstance == hInstance)
00224                                 {
00225                                     wndclass->addRef();
00226                                     unlock(&critsect);
00227                                     return(wndclass);
00228                                 }
00229                         }
00230                         wndclass = (Win32WndClass *)wndclass->GetNext();
00231                 }
00232         }
00233   }
00234   else {
00235 //CB: without HInstance check, test program finds class
00236 //CB: need more code to compare instance; convert 0 to exe module handle
00237         if(wndclass->classAtom == (DWORD)id /*&& wndclass->hInstance == hInstance*/) {
00238                 wndclass->addRef();
00239                 unlock(&critsect);
00240                 return(wndclass);
00241         }
00242         else {
00243                 wndclass = (Win32WndClass *)wndclass->GetNext();
00244                 while(wndclass != NULL) {
00245                         if(wndclass->classAtom == (DWORD)id /* && wndclass->hInstance == hInstance*/) {
00246                                 wndclass->addRef();
00247                                 unlock(&critsect);
00248                                 return(wndclass);
00249                         }
00250                         wndclass = (Win32WndClass *)wndclass->GetNext();
00251                 }
00252         }
00253   }
00254   unlock(&critsect);
00255   dprintf(("Class %X (inst %X) not found!", id, hInstance));
00256   return(NULL);
00257 }
00258 //******************************************************************************
00259 //Locates class in linked list and increases reference count (if found)
00260 //Class object must be unreferenced after usage
00261 //******************************************************************************
00262 Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPWSTR id)
00263 {
00264  LPSTR          lpszClassName;
00265  Win32WndClass *winclass;
00266 
00267   if(HIWORD(id)) {
00268        lpszClassName = UnicodeToAsciiString((LPWSTR)id);
00269   }
00270   else lpszClassName = (LPSTR)id;
00271 
00272   winclass = FindClass(hInstance, lpszClassName);
00273 
00274   if(HIWORD(id)) {
00275         FreeAsciiString((char *)lpszClassName);
00276   }
00277   return winclass;
00278 }
00279 //******************************************************************************
00280 //An app can only access another process' class if it's global
00281 //(all system classes are global)
00282 //NOTE: NOT USED NOW
00283 //******************************************************************************
00284 BOOL Win32WndClass::isAppClass(ULONG curProcessId)
00285 {
00286   if(windowStyle & CS_GLOBALCLASS)
00287     return TRUE;
00288 
00289   return curProcessId = processId;
00290 }
00291 //******************************************************************************
00292 //******************************************************************************
00293 BOOL Win32WndClass::getClassInfo(WNDCLASSEXA *wndclass)
00294 {
00295   wndclass->cbClsExtra    = nrExtraClassBytes;
00296   wndclass->cbWndExtra    = nrExtraWindowBytes;
00297   wndclass->hbrBackground = backgroundBrush;
00298   wndclass->hCursor       = hCursor;
00299   wndclass->hIcon         = hIcon;
00300   wndclass->hInstance     = hInstance;
00301   wndclass->lpszMenuName  = (LPCTSTR)menuNameA;
00302   wndclass->lpszClassName = (classNameA) ? (LPCTSTR)classNameA : (LPCTSTR)classAtom;
00303   wndclass->style         = windowStyle;
00304   wndclass->lpfnWndProc   = (WNDPROC)getClassLongA(GCL_WNDPROC, FALSE);
00305   wndclass->hIconSm       = hIconSm;
00306   return(TRUE);
00307 }
00308 //******************************************************************************
00309 //******************************************************************************
00310 BOOL Win32WndClass::getClassInfo(WNDCLASSEXW *wndclass)
00311 {
00312   wndclass->cbClsExtra    = nrExtraClassBytes;
00313   wndclass->cbWndExtra    = nrExtraWindowBytes;
00314   wndclass->hbrBackground = backgroundBrush;
00315   wndclass->hCursor       = hCursor;
00316   wndclass->hIcon         = hIcon;
00317   wndclass->hInstance     = hInstance;
00318   wndclass->lpszMenuName  = (LPCWSTR)menuNameW;
00319   wndclass->lpszClassName = (classNameW) ? (LPCWSTR)classNameW : (LPCWSTR)classAtom;
00320   wndclass->style         = windowStyle;
00321   wndclass->lpfnWndProc   = (WNDPROC)getClassLongA(GCL_WNDPROC, TRUE);
00322   wndclass->hIconSm       = hIconSm;
00323   return(TRUE);
00324 }
00325 //******************************************************************************
00326 //******************************************************************************
00327 ULONG Win32WndClass::getClassName(LPSTR lpszClassName, ULONG cchClassName)
00328 {
00329   if(HIWORD(classNameA)) {
00330         lstrcpynA(lpszClassName, classNameA, cchClassName-1);
00331         return strlen(lpszClassName);
00332   }
00333   *(ULONG *)lpszClassName = classAtom;
00334   return(sizeof(ULONG));
00335 }
00336 //******************************************************************************
00337 //******************************************************************************
00338 ULONG Win32WndClass::getClassName(LPWSTR lpszClassName, ULONG cchClassName)
00339 {
00340  ULONG len;
00341 
00342   if(HIWORD(classNameW)) {
00343         lstrcpynW(lpszClassName, classNameW, cchClassName-1);
00344         return lstrlenW(lpszClassName);
00345   }
00346   *(ULONG *)lpszClassName = classAtom;
00347   return(sizeof(ULONG));
00348 }
00349 //******************************************************************************
00350 //******************************************************************************
00351 void Win32WndClass::setMenuName(LPSTR newMenuName)
00352 {
00353   if(HIWORD(menuNameA)) {
00354         free(menuNameA);
00355         free(menuNameW);
00356         menuNameA = 0;
00357         menuNameW = 0;
00358   }
00359   if(HIWORD(newMenuName)) {
00360         if(isUnicode) {
00361                 menuNameA = (PCHAR)_smalloc(lstrlenW((LPWSTR)newMenuName)+1);
00362                 menuNameW = (WCHAR *)_smalloc((lstrlenW((LPWSTR)newMenuName)+1)*sizeof(WCHAR));
00363         }
00364         else {
00365                 menuNameA = (PCHAR)_smalloc(strlen(newMenuName)+1);
00366                 menuNameW = (WCHAR *)_smalloc((strlen(newMenuName)+1)*sizeof(WCHAR));
00367         }
00368         if(menuNameA == NULL || menuNameW == NULL) {
00369                 dprintf(("Win32Class ctr; menuName/menuNameW == NULL"));
00370                 exit(1);
00371         }
00372         if(isUnicode) {
00373                 lstrcpyW(menuNameW, (LPWSTR)newMenuName);
00374                 UnicodeToAscii(menuNameW, menuNameA);
00375         }
00376         else {
00377                 strcpy((char *)menuNameA, newMenuName);
00378                 AsciiToUnicode(menuNameA, menuNameW);
00379         }
00380 
00381   }
00382   else {//id
00383         menuNameA = (PCHAR)newMenuName;
00384         menuNameW = (WCHAR *)newMenuName;
00385   }
00386 }
00387 //******************************************************************************
00388 //******************************************************************************
00389 ULONG Win32WndClass::getClassLongA(int index, BOOL fUnicode)
00390 {
00391   switch(index) {
00392         case GCL_CBCLSEXTRA:
00393                 return nrExtraClassBytes;
00394         case GCL_CBWNDEXTRA:
00395                 return nrExtraWindowBytes;
00396         case GCL_HBRBACKGROUND:
00397                 return backgroundBrush;
00398         case GCL_HCURSOR:
00399                 return hCursor;
00400         case GCL_HICON:
00401                 return hIcon;
00402         case GCL_HICONSM:
00403                 return hIconSm;
00404         case GCL_HMODULE:
00405                 return hInstance;
00406         case GCL_MENUNAME:
00407                 return (isUnicode) ? (ULONG)menuNameW : (ULONG)menuNameA;
00408         case GCL_STYLE:
00409                 return windowStyle;
00410         case GCL_WNDPROC:
00411                 return (ULONG) WINPROC_GetProc(windowProc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A);
00412         case GCW_ATOM: //TODO: does this really happen in windows?
00413                 SetLastError(ERROR_INVALID_PARAMETER);
00414                 return 0;
00415         default:
00416                 if(index >= 0 && index + sizeof(ULONG) <= nrExtraClassBytes) {
00417                         //Note: NT4, SP6 does not set the last error to 0
00418                         SetLastError(ERROR_SUCCESS);
00419                         return *(ULONG *)(userClassBytes + index);
00420                 }
00421                 if(classNameA) {
00422                      dprintf2(("WARNING: getClassLong %s: %d -> wrong INDEX", classNameA, index));
00423                 }
00424                 else dprintf2(("WARNING: getClassLong %d: %d -> wrong INDEX", classAtom, index));
00425                 SetLastError(ERROR_INVALID_INDEX);  //verified in NT4, SP6
00426                 return 0;
00427   }
00428 }
00429 //******************************************************************************
00430 //******************************************************************************
00431 WORD Win32WndClass::getClassWord(int index)
00432 {
00433   switch(index) {
00434         case GCW_ATOM:
00435                 return (WORD)classAtom;
00436         default:
00437                 if(index >= 0 && index + sizeof(WORD) <= nrExtraClassBytes) {
00438                         //Note: NT4, SP6 does not set the last error to 0
00439                         SetLastError(ERROR_SUCCESS);
00440                         return *(WORD *)(userClassBytes + index);
00441                 }
00442                 if(classNameA) {
00443                      dprintf2(("WARNING: getClassWord %s: %d -> wrong INDEX", classNameA, index));
00444                 }
00445                 else dprintf2(("WARNING: getClassWord %d: %d -> wrong INDEX", classAtom, index));
00446                 SetLastError(ERROR_INVALID_INDEX);  //verified in NT4, SP6
00447                 return 0;
00448   }
00449 }
00450 //******************************************************************************
00451 //TODO: What effects what immediately?
00452 //******************************************************************************
00453 ULONG Win32WndClass::setClassLongA(int index, LONG lNewVal, BOOL fUnicode)
00454 {
00455  ULONG rc;
00456 
00457   switch(index) {
00458         case GCL_CBCLSEXTRA: //TODO (doesn't affect allocated classes, so what does it do?)
00459                 rc = nrExtraClassBytes;
00460 //              nrExtraClassBytes = lNewVal;
00461                 break;
00462         case GCL_CBWNDEXTRA:
00463                 rc = nrExtraWindowBytes;
00464                 nrExtraWindowBytes = lNewVal;
00465                 break;
00466         case GCL_HBRBACKGROUND:
00467                 rc = backgroundBrush;
00468                 backgroundBrush = lNewVal;
00469                 break;
00470         case GCL_HCURSOR:
00471                 rc = hCursor;
00472                 hCursor = lNewVal;
00473                 break;
00474         case GCL_HICON:
00475                 rc = hIcon;
00476                 hIcon = lNewVal;
00477                 break;
00478         case GCL_HICONSM:
00479                 rc = hIconSm;
00480                 hIconSm = lNewVal;
00481                 break;
00482         case GCL_HMODULE:
00483                 rc = hInstance;
00484                 hInstance = lNewVal;
00485                 break;
00486         case GCL_MENUNAME:
00487                 rc = 0; //old value is meaningless (according to Wine)
00488                 setMenuName((LPSTR)lNewVal);
00489                 break;
00490         case GCL_STYLE:
00491                 rc = windowStyle;
00492                 windowStyle = lNewVal;
00493                 break;
00494         case GCL_WNDPROC:
00495                 //Note: Type of SetWindowLong determines new window proc type
00496                 //      UNLESS the new window proc has already been registered
00497                 //      (use the old type in that case)
00498                 //      (VERIFIED in NT 4, SP6)
00499                 //TODO: Is that also true for GCL_WNDPROC???????????????
00500                 rc = (LONG)WINPROC_GetProc(windowProc, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A );
00501                 WINPROC_SetProc((HWINDOWPROC *)&windowProc, (WNDPROC)lNewVal, (fUnicode) ? WIN_PROC_32W : WIN_PROC_32A, WIN_PROC_CLASS );
00502                 break;
00503         case GCW_ATOM: //TODO: does this really happen in windows?
00504                 SetLastError(ERROR_INVALID_PARAMETER);
00505                 return 0;
00506         default:
00507                 if(index >= 0 && index + sizeof(ULONG) <= nrExtraClassBytes) {
00508                         rc = *(ULONG *)(userClassBytes + index);
00509                         *(ULONG *)(userClassBytes + index) = lNewVal;
00510                         break;
00511                 }
00512                 SetLastError(ERROR_INVALID_INDEX);  //verified in NT4, SP6
00513                 if(classNameA) {
00514                      dprintf2(("WARNING: Win32WndClass::setClassLongA %s: %d %x -> wrong INDEX", classNameA, index, lNewVal));
00515                 }
00516                 else dprintf2(("WARNING: Win32WndClass::setClassLongA %d: %d %x -> wrong INDEX", classAtom, index, lNewVal));
00517                 return 0;
00518   }
00519   SetLastError(ERROR_SUCCESS);
00520   if(classNameA) {
00521         dprintf2(("Win32WndClass::setClassLongA %s: %d %x returned %x", classNameA, index, lNewVal, rc));
00522   }
00523   else  dprintf2(("Win32WndClass::setClassLongA %d: %d %x returned %x", classAtom, index, lNewVal, rc));
00524   return(rc);
00525 }
00526 //******************************************************************************
00527 //******************************************************************************
00528 WORD Win32WndClass::setClassWord(int index, WORD wNewVal)
00529 {
00530  WORD rc;
00531 
00532   switch(index) {
00533         case GCW_ATOM:
00534                 rc = (WORD)classAtom;
00535                 classAtom = wNewVal;
00536                 return(rc);
00537         default:
00538                 if(index >= 0 && index + sizeof(WORD) <= nrExtraClassBytes) {
00539                         rc = *(WORD *)(userClassBytes + index);
00540                         *(WORD *)(userClassBytes + index) = wNewVal;
00541                         //Note: NT4, SP6 does not set the last error to 0
00542                         SetLastError(ERROR_SUCCESS);
00543                         return(rc);
00544                 }
00545                 SetLastError(ERROR_INVALID_INDEX);  //verified in NT4, SP6
00546                 if(classNameA) {
00547                      dprintf2(("WARNING: setClassWord %s: %d %x -> wrong INDEX", classNameA, index, wNewVal));
00548                 }
00549                 else dprintf2(("WARNING: setClassWord %d: %d %x -> wrong INDEX", classAtom, index, wNewVal));
00550                 return 0;
00551   }
00552 }
00553 //******************************************************************************
00554 //FIXME: Windows that still exists with this class
00555 //******************************************************************************
00556 BOOL Win32WndClass::UnregisterClassA(HINSTANCE hinst, LPSTR id)
00557 {
00558   Win32WndClass *wndclass;
00559 
00560   if(HIWORD(id)) {
00561        dprintf(("Win32WndClass::UnregisterClassA class %s, instance %x!!", id, hinst));
00562   }
00563   else dprintf(("Win32WndClass::UnregisterClassA class %x, instance %x!!", id, hinst));
00564 
00565   wndclass = FindClass(hinst, id);
00566   if(wndclass) {
00567         if(wndclass->getRefCount() != 1) {
00568             wndclass->markDeleted();
00569             RELEASE_CLASSOBJ(wndclass);
00570             dprintf2(("Win32WndClass::UnregisterClassA class %x still has windows!!", id));
00571             SetLastError(ERROR_CLASS_HAS_WINDOWS);
00572             return FALSE;
00573         }   
00574         wndclass->markDeleted();
00575         RELEASE_CLASSOBJ(wndclass);
00576     
00577         SetLastError(ERROR_SUCCESS);
00578         return TRUE;
00579   }
00580   dprintf(("::UnregisterClass, couldn't find class %X!!\n", id));
00581   SetLastError(ERROR_CLASS_DOES_NOT_EXIST);
00582   return FALSE;
00583 }
00584 //******************************************************************************
00585 //******************************************************************************
00586 GenericObject   *Win32WndClass::wndclasses = NULL;
00587 CRITICAL_SECTION Win32WndClass::critsect   = {0};

Generated on Wed Jan 23 23:17:45 2002 for ODIN-user32 by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001