2 * Window classes functions
4 * Copyright 1993 Alexandre Julliard
16 /* #define DEBUG_CLASS */
20 static HCLASS firstClass
= 0;
23 /***********************************************************************
24 * CLASS_FindClassByName
26 * Return a handle and a pointer to the class.
27 * 'ptr' can be NULL if the pointer is not needed.
29 HCLASS
CLASS_FindClassByName( char * name
, WORD hinstance
, CLASS
**ptr
)
35 if (!(atom
= GlobalFindAtom( name
))) return 0;
37 /* First search task-specific classes */
39 for (class = firstClass
; (class); class = classPtr
->hNext
)
41 classPtr
= (CLASS
*) USER_HEAP_LIN_ADDR(class);
42 if (classPtr
->wc
.style
& CS_GLOBALCLASS
) continue;
43 if ((classPtr
->atomName
== atom
) &&
44 ((hinstance
==0xffff )|| (hinstance
== classPtr
->wc
.hInstance
)))
46 if (ptr
) *ptr
= classPtr
;
51 /* Then search global classes */
53 for (class = firstClass
; (class); class = classPtr
->hNext
)
55 classPtr
= (CLASS
*) USER_HEAP_LIN_ADDR(class);
56 if (!(classPtr
->wc
.style
& CS_GLOBALCLASS
)) continue;
57 if (classPtr
->atomName
== atom
)
59 if (ptr
) *ptr
= classPtr
;
68 /***********************************************************************
71 * Return a pointer to the CLASS structure corresponding to a HCLASS.
73 CLASS
* CLASS_FindClassPtr( HCLASS hclass
)
77 if (!hclass
) return NULL
;
78 ptr
= (CLASS
*) USER_HEAP_LIN_ADDR( hclass
);
79 if (ptr
->wMagic
!= CLASS_MAGIC
) return NULL
;
84 /***********************************************************************
85 * RegisterClass (USER.57)
87 ATOM
RegisterClass( LPWNDCLASS
class )
89 CLASS
* newClass
, * prevClassPtr
;
90 HCLASS handle
, prevClass
;
92 char *name
= PTR_SEG_TO_LIN( class->lpszClassName
);
94 dprintf_class(stddeb
, "RegisterClass: wndproc=%08lx hinst=%04x name='%s' background %04x\n",
95 (DWORD
)class->lpfnWndProc
, class->hInstance
, name
, class->hbrBackground
);
96 dprintf_class(stddeb
, " style %04x\n",class->style
);
98 /* Window classes are owned by modules, not instances */
99 class->hInstance
= GetExePtr( class->hInstance
);
101 /* Check if a class with this name already exists */
102 prevClass
= CLASS_FindClassByName( name
, class->hInstance
, &prevClassPtr
);
105 /* Class can be created only if it is local and */
106 /* if the class with the same name is global. */
108 if (class->style
& CS_GLOBALCLASS
) return 0;
109 if (!(prevClassPtr
->wc
.style
& CS_GLOBALCLASS
)) return 0;
114 classExtra
= (class->cbClsExtra
< 0) ? 0 : class->cbClsExtra
;
115 handle
= USER_HEAP_ALLOC( sizeof(CLASS
) + classExtra
);
116 if (!handle
) return 0;
117 newClass
= (CLASS
*) USER_HEAP_LIN_ADDR( handle
);
118 newClass
->hNext
= firstClass
;
119 newClass
->wMagic
= CLASS_MAGIC
;
120 newClass
->cWindows
= 0;
121 newClass
->wc
= *class;
122 newClass
->wc
.cbWndExtra
= (class->cbWndExtra
< 0) ? 0 : class->cbWndExtra
;
123 newClass
->wc
.cbClsExtra
= classExtra
;
125 newClass
->atomName
= GlobalAddAtom( name
);
126 newClass
->wc
.lpszClassName
= NULL
;
128 if (newClass
->wc
.style
& CS_CLASSDC
)
129 newClass
->hdce
= DCE_AllocDCE( DCE_CLASS_DC
);
130 else newClass
->hdce
= 0;
132 /* Make a copy of the menu name (only if it is a string) */
134 if ((int)class->lpszMenuName
& 0xffff0000)
136 char *menuname
= PTR_SEG_TO_LIN( class->lpszMenuName
);
137 HANDLE hname
= USER_HEAP_ALLOC( strlen(menuname
)+1 );
140 newClass
->wc
.lpszMenuName
= (char *)USER_HEAP_SEG_ADDR( hname
);
141 strcpy( USER_HEAP_LIN_ADDR( hname
), menuname
);
145 if (classExtra
) memset( newClass
->wExtra
, 0, classExtra
);
147 return newClass
->atomName
;
151 /***********************************************************************
152 * UnregisterClass (USER.403)
154 BOOL
UnregisterClass( LPSTR className
, HANDLE hinstance
)
156 HANDLE
class, prevClass
;
157 CLASS
* classPtr
, * prevClassPtr
;
159 hinstance
= GetExePtr( hinstance
);
160 /* Check if we can remove this class */
161 class = CLASS_FindClassByName( className
, hinstance
, &classPtr
);
162 if (!class) return FALSE
;
163 if ((classPtr
->wc
.hInstance
!= hinstance
) || (classPtr
->cWindows
> 0))
166 /* Remove the class from the linked list */
167 if (firstClass
== class) firstClass
= classPtr
->hNext
;
170 for (prevClass
= firstClass
; prevClass
; prevClass
=prevClassPtr
->hNext
)
172 prevClassPtr
= (CLASS
*) USER_HEAP_LIN_ADDR(prevClass
);
173 if (prevClassPtr
->hNext
== class) break;
177 fprintf(stderr
, "ERROR: Class list corrupted\n" );
180 prevClassPtr
->hNext
= classPtr
->hNext
;
183 /* Delete the class */
184 if (classPtr
->hdce
) DCE_FreeDCE( classPtr
->hdce
);
185 if (classPtr
->wc
.hbrBackground
) DeleteObject( classPtr
->wc
.hbrBackground
);
186 /*if (classPtr->wc.style & CS_GLOBALCLASS)*/ GlobalDeleteAtom( classPtr
->atomName
);
187 /*else DeleteAtom( classPtr->atomName );*/
188 if ((int)classPtr
->wc
.lpszMenuName
& 0xffff0000)
189 USER_HEAP_FREE( (int)classPtr
->wc
.lpszMenuName
& 0xffff );
190 USER_HEAP_FREE( class );
195 /***********************************************************************
196 * GetClassWord (USER.129)
198 WORD
GetClassWord( HWND hwnd
, short offset
)
200 return (WORD
)GetClassLong( hwnd
, offset
);
204 /***********************************************************************
205 * SetClassWord (USER.130)
207 WORD
SetClassWord( HWND hwnd
, short offset
, WORD newval
)
211 WORD
*ptr
, retval
= 0;
213 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
214 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
215 ptr
= (WORD
*)(((char *)classPtr
->wExtra
) + offset
);
222 /***********************************************************************
223 * GetClassLong (USER.131)
225 LONG
GetClassLong( HWND hwnd
, short offset
)
230 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
231 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
232 return *(LONG
*)(((char *)classPtr
->wExtra
) + offset
);
236 /***********************************************************************
237 * SetClassLong (USER.132)
239 LONG
SetClassLong( HWND hwnd
, short offset
, LONG newval
)
243 LONG
*ptr
, retval
= 0;
245 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
246 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
247 ptr
= (LONG
*)(((char *)classPtr
->wExtra
) + offset
);
254 /***********************************************************************
255 * GetClassName (USER.58)
257 int GetClassName(HWND hwnd
, LPSTR lpClassName
, short maxCount
)
262 /* FIXME: We have the find the correct hInstance */
263 dprintf_class(stddeb
,"GetClassName(%x,%p,%d)\n",hwnd
,lpClassName
,maxCount
);
264 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
265 if (!(classPtr
= CLASS_FindClassPtr(wndPtr
->hClass
))) return 0;
267 return GlobalGetAtomName(classPtr
->atomName
, lpClassName
, maxCount
);
271 /***********************************************************************
272 * GetClassInfo (USER.404)
274 BOOL
GetClassInfo(HANDLE hInstance
, SEGPTR ClassName
,
275 LPWNDCLASS lpWndClass
)
278 LPSTR lpClassName
= 0;
280 if (HIWORD(ClassName
)) {
281 lpClassName
= PTR_SEG_TO_LIN(ClassName
);
283 sprintf(temp
,"#%d",(int)LOWORD(ClassName
));
286 dprintf_class(stddeb
, "GetClassInfo hInstance=%04x lpClassName=%s\n",
287 hInstance
, lpClassName
);
289 hInstance
= GetExePtr(hInstance
);
291 /* if (!(CLASS_FindClassByName(lpClassName, &classPtr))) return FALSE; */
292 if (!(CLASS_FindClassByName(lpClassName
, hInstance
, &classPtr
)))
294 /* if (!HIWORD(lpClassName))
297 sprintf(temp, "#%d", (int)lpClassName);
298 if (!(CLASS_FindClassByName(temp, hInstance, &classPtr))) return FALSE;
304 if (hInstance
&& (hInstance
!= classPtr
->wc
.hInstance
)) return FALSE
;
306 memcpy(lpWndClass
, &(classPtr
->wc
), sizeof(WNDCLASS
));
311 /***********************************************************************
312 * ClassFirst (TOOLHELP.69)
314 BOOL
ClassFirst( CLASSENTRY
*pClassEntry
)
316 pClassEntry
->wNext
= firstClass
;
317 return ClassNext( pClassEntry
);
321 /***********************************************************************
322 * ClassNext (TOOLHELP.70)
324 BOOL
ClassNext( CLASSENTRY
*pClassEntry
)
326 CLASS
*classPtr
= (CLASS
*) USER_HEAP_LIN_ADDR( pClassEntry
->wNext
);
327 if (!classPtr
) return FALSE
;
329 pClassEntry
->hInst
= classPtr
->wc
.hInstance
;
330 pClassEntry
->wNext
= classPtr
->hNext
;
331 GlobalGetAtomName( classPtr
->atomName
, pClassEntry
->szClassName
,
332 sizeof(pClassEntry
->szClassName
) );