Release 941210
[wine/multimedia.git] / windows / class.c
blob7f937bbd19f4ee29649c0427ca57b4ca335ef4bf
1 /*
2 * Window classes functions
4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
7 */
9 #include <stdlib.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include "class.h"
13 #include "user.h"
14 #include "win.h"
15 #include "dce.h"
16 #include "stddebug.h"
17 /* #define DEBUG_CLASS */
18 #include "debug.h"
21 static HCLASS firstClass = 0;
24 /***********************************************************************
25 * CLASS_FindClassByName
27 * Return a handle and a pointer to the class.
28 * 'ptr' can be NULL if the pointer is not needed.
30 HCLASS CLASS_FindClassByName( char * name, WORD hinstance, CLASS **ptr )
32 ATOM atom;
33 HCLASS class;
34 CLASS * classPtr;
36 /* First search task-specific classes */
38 if ((atom = /*FindAtom*/GlobalFindAtom( name )) != 0)
40 for (class = firstClass; (class); class = classPtr->hNext)
42 classPtr = (CLASS *) USER_HEAP_ADDR(class);
43 if (classPtr->wc.style & CS_GLOBALCLASS) continue;
44 if ((classPtr->atomName == atom) &&
45 (( hinstance==0xffff )|| (hinstance == classPtr->wc.hInstance)))
47 if (ptr) *ptr = classPtr;
48 return class;
53 /* Then search global classes */
55 if ((atom = GlobalFindAtom( name )) != 0)
57 for (class = firstClass; (class); class = classPtr->hNext)
59 classPtr = (CLASS *) USER_HEAP_ADDR(class);
60 if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
61 if (classPtr->atomName == atom)
63 if (ptr) *ptr = classPtr;
64 return class;
69 return 0;
73 /***********************************************************************
74 * CLASS_FindClassPtr
76 * Return a pointer to the CLASS structure corresponding to a HCLASS.
78 CLASS * CLASS_FindClassPtr( HCLASS hclass )
80 CLASS * ptr;
82 if (!hclass) return NULL;
83 ptr = (CLASS *) USER_HEAP_ADDR( hclass );
84 if (ptr->wMagic != CLASS_MAGIC) return NULL;
85 return ptr;
89 /***********************************************************************
90 * RegisterClass (USER.57)
92 ATOM RegisterClass( LPWNDCLASS class )
94 CLASS * newClass, * prevClassPtr;
95 HCLASS handle, prevClass;
96 int classExtra;
98 dprintf_class(stddeb, "RegisterClass: wndproc=%p hinst=%d name='%s' background %x\n",
99 class->lpfnWndProc, class->hInstance, class->lpszClassName,
100 class->hbrBackground );
102 /* Check if a class with this name already exists */
104 prevClass = CLASS_FindClassByName( class->lpszClassName, class->hInstance,
105 &prevClassPtr );
106 if (prevClass)
108 /* Class can be created only if it is local and */
109 /* if the class with the same name is global. */
111 if (class->style & CS_GLOBALCLASS) return 0;
112 if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0;
115 /* Create class */
117 classExtra = (class->cbClsExtra < 0) ? 0 : class->cbClsExtra;
118 handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(CLASS) + classExtra );
119 if (!handle) return 0;
120 newClass = (CLASS *) USER_HEAP_ADDR( handle );
121 newClass->hNext = firstClass;
122 newClass->wMagic = CLASS_MAGIC;
123 newClass->cWindows = 0;
124 newClass->wc = *class;
125 newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
126 newClass->wc.cbClsExtra = classExtra;
128 /*if (newClass->wc.style & CS_GLOBALCLASS)*/
129 newClass->atomName = GlobalAddAtom( class->lpszClassName );
130 /*else newClass->atomName = AddAtom( class->lpszClassName );*/
131 newClass->wc.lpszClassName = NULL;
133 if (newClass->wc.style & CS_CLASSDC)
134 newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC );
135 else newClass->hdce = 0;
137 /* Make a copy of the menu name (only if it is a string) */
139 if ((int)class->lpszMenuName & 0xffff0000)
141 HANDLE hname;
142 hname = USER_HEAP_ALLOC( GMEM_MOVEABLE, strlen(class->lpszMenuName)+1);
143 if (hname)
145 newClass->wc.lpszMenuName = (char *)USER_HEAP_ADDR( hname );
146 strcpy( newClass->wc.lpszMenuName, class->lpszMenuName );
150 if (classExtra) memset( newClass->wExtra, 0, classExtra );
151 firstClass = handle;
152 return newClass->atomName;
156 /***********************************************************************
157 * UnregisterClass (USER.403)
159 BOOL UnregisterClass( LPSTR className, HANDLE instance )
161 HANDLE class, prevClass;
162 CLASS * classPtr, * prevClassPtr;
164 /* Check if we can remove this class */
165 class = CLASS_FindClassByName( className, instance, &classPtr );
166 if (!class) return FALSE;
167 if ((classPtr->wc.hInstance != instance) || (classPtr->cWindows > 0))
168 return FALSE;
170 /* Remove the class from the linked list */
171 if (firstClass == class) firstClass = classPtr->hNext;
172 else
174 for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
176 prevClassPtr = (CLASS *) USER_HEAP_ADDR(prevClass);
177 if (prevClassPtr->hNext == class) break;
179 if (!prevClass)
181 fprintf(stderr, "ERROR: Class list corrupted\n" );
182 return FALSE;
184 prevClassPtr->hNext = classPtr->hNext;
187 /* Delete the class */
188 if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
189 if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
190 /*if (classPtr->wc.style & CS_GLOBALCLASS)*/ GlobalDeleteAtom( classPtr->atomName );
191 /*else DeleteAtom( classPtr->atomName );*/
192 if ((int)classPtr->wc.lpszMenuName & 0xffff0000)
193 USER_HEAP_FREE( (int)classPtr->wc.lpszMenuName & 0xffff );
194 USER_HEAP_FREE( class );
195 return TRUE;
199 /***********************************************************************
200 * GetClassWord (USER.129)
202 WORD GetClassWord( HWND hwnd, short offset )
204 return (WORD)GetClassLong( hwnd, offset );
208 /***********************************************************************
209 * SetClassWord (USER.130)
211 WORD SetClassWord( HWND hwnd, short offset, WORD newval )
213 CLASS * classPtr;
214 WND * wndPtr;
215 WORD *ptr, retval = 0;
217 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
218 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
219 ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
220 retval = *ptr;
221 *ptr = newval;
222 return retval;
226 /***********************************************************************
227 * GetClassLong (USER.131)
229 LONG GetClassLong( HWND hwnd, short offset )
231 CLASS * classPtr;
232 WND * wndPtr;
234 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
235 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
236 return *(LONG *)(((char *)classPtr->wExtra) + offset);
240 /***********************************************************************
241 * SetClassLong (USER.132)
243 LONG SetClassLong( HWND hwnd, short offset, LONG newval )
245 CLASS * classPtr;
246 WND * wndPtr;
247 LONG *ptr, retval = 0;
249 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
250 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
251 ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
252 retval = *ptr;
253 *ptr = newval;
254 return retval;
258 /***********************************************************************
259 * GetClassName (USER.58)
261 int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount)
263 WND *wndPtr;
264 CLASS *classPtr;
266 /* FIXME: We have the find the correct hInstance */
267 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
268 if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0;
270 return (GetAtomName(classPtr->atomName, lpClassName, maxCount));
274 /***********************************************************************
275 * GetClassInfo (USER.404)
277 BOOL GetClassInfo(HANDLE hInstance, LPSTR lpClassName,
278 LPWNDCLASS lpWndClass)
280 CLASS *classPtr;
282 if (HIWORD(lpClassName))
284 dprintf_class(stddeb, "GetClassInfo hInstance=%04x lpClassName=%s\n",
285 hInstance, lpClassName);
287 else
288 dprintf_class(stddeb, "GetClassInfo hInstance=%04x lpClassName=#%d\n",
289 hInstance, (int)lpClassName);
292 /* if (!(CLASS_FindClassByName(lpClassName, &classPtr))) return FALSE; */
293 if (!(CLASS_FindClassByName(lpClassName, hInstance, &classPtr)))
295 if (!HIWORD(lpClassName))
297 char temp[10];
298 sprintf(temp, "#%d", (int)lpClassName);
299 if (!(CLASS_FindClassByName(temp, hInstance, &classPtr))) return FALSE;
302 else return FALSE;
305 if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE;
307 memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
308 return TRUE;