Release 950901
[wine/multimedia.git] / windows / class.c
blob4ce07ed33c4797eb066be10ee0eeba362dae95fa
1 /*
2 * Window classes functions
4 * Copyright 1993 Alexandre Julliard
5 */
7 #include <stdlib.h>
8 #include <stdio.h>
9 #include <string.h>
10 #include "class.h"
11 #include "user.h"
12 #include "win.h"
13 #include "dce.h"
14 #include "atom.h"
15 #include "ldt.h"
16 #include "toolhelp.h"
17 #include "stddebug.h"
18 /* #define DEBUG_CLASS */
19 #include "debug.h"
22 static HCLASS firstClass = 0;
25 /***********************************************************************
26 * CLASS_FindClassByName
28 * Return a handle and a pointer to the class.
29 * 'ptr' can be NULL if the pointer is not needed.
31 HCLASS CLASS_FindClassByName( SEGPTR name, WORD hinstance, CLASS **ptr )
33 ATOM atom;
34 HCLASS class;
35 CLASS * classPtr;
37 if (!(atom = GlobalFindAtom( name ))) return 0;
39 /* First search task-specific classes */
41 for (class = firstClass; (class); class = classPtr->hNext)
43 classPtr = (CLASS *) USER_HEAP_LIN_ADDR(class);
44 if (classPtr->wc.style & CS_GLOBALCLASS) continue;
45 if ((classPtr->atomName == atom) &&
46 ((hinstance==0xffff )|| (hinstance == classPtr->wc.hInstance)))
48 if (ptr) *ptr = classPtr;
49 return class;
53 /* Then search global classes */
55 for (class = firstClass; (class); class = classPtr->hNext)
57 classPtr = (CLASS *) USER_HEAP_LIN_ADDR(class);
58 if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
59 if (classPtr->atomName == atom)
61 if (ptr) *ptr = classPtr;
62 return class;
66 return 0;
70 /***********************************************************************
71 * CLASS_FindClassPtr
73 * Return a pointer to the CLASS structure corresponding to a HCLASS.
75 CLASS * CLASS_FindClassPtr( HCLASS hclass )
77 CLASS * ptr;
79 if (!hclass) return NULL;
80 ptr = (CLASS *) USER_HEAP_LIN_ADDR( hclass );
81 if (ptr->wMagic != CLASS_MAGIC) return NULL;
82 return ptr;
86 /***********************************************************************
87 * RegisterClass (USER.57)
89 ATOM RegisterClass( LPWNDCLASS class )
91 CLASS * newClass, * prevClassPtr;
92 HCLASS handle, prevClass;
93 int classExtra;
95 dprintf_class( stddeb, "RegisterClass: wndproc=%08lx hinst=%04x name='%s' background %04x\n",
96 (DWORD)class->lpfnWndProc, class->hInstance,
97 HIWORD(class->lpszClassName) ?
98 (char *)PTR_SEG_TO_LIN(class->lpszClassName) : "(int)",
99 class->hbrBackground );
100 dprintf_class(stddeb," style=%04x clsExtra=%d winExtra=%d\n",
101 class->style, class->cbClsExtra, class->cbWndExtra );
103 /* Window classes are owned by modules, not instances */
104 class->hInstance = GetExePtr( class->hInstance );
106 /* Check if a class with this name already exists */
107 prevClass = CLASS_FindClassByName( class->lpszClassName,
108 class->hInstance, &prevClassPtr );
109 if (prevClass)
111 /* Class can be created only if it is local and */
112 /* if the class with the same name is global. */
114 if (class->style & CS_GLOBALCLASS) return 0;
115 if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0;
118 /* Create class */
120 classExtra = (class->cbClsExtra < 0) ? 0 : class->cbClsExtra;
121 handle = USER_HEAP_ALLOC( sizeof(CLASS) + classExtra );
122 if (!handle) return 0;
123 newClass = (CLASS *) USER_HEAP_LIN_ADDR( handle );
124 newClass->hNext = firstClass;
125 newClass->wMagic = CLASS_MAGIC;
126 newClass->cWindows = 0;
127 newClass->wc = *class;
128 newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
129 newClass->wc.cbClsExtra = classExtra;
131 newClass->atomName = GlobalAddAtom( class->lpszClassName );
132 newClass->wc.lpszClassName = 0;
134 if (newClass->wc.style & CS_CLASSDC)
135 newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC );
136 else newClass->hdce = 0;
138 /* Make a copy of the menu name (only if it is a string) */
140 if (HIWORD(class->lpszMenuName))
142 char *menuname = PTR_SEG_TO_LIN( class->lpszMenuName );
143 HANDLE hname = USER_HEAP_ALLOC( strlen(menuname)+1 );
144 if (hname)
146 newClass->wc.lpszMenuName = USER_HEAP_SEG_ADDR( hname );
147 strcpy( USER_HEAP_LIN_ADDR( hname ), menuname );
151 if (classExtra) memset( newClass->wExtra, 0, classExtra );
152 firstClass = handle;
153 return newClass->atomName;
157 /***********************************************************************
158 * UnregisterClass (USER.403)
160 BOOL UnregisterClass( SEGPTR className, HANDLE hinstance )
162 HANDLE class, prevClass;
163 CLASS * classPtr, * prevClassPtr;
165 hinstance = GetExePtr( hinstance );
166 /* Check if we can remove this class */
167 class = CLASS_FindClassByName( className, hinstance, &classPtr );
168 if (!class) return FALSE;
169 if ((classPtr->wc.hInstance != hinstance) || (classPtr->cWindows > 0))
170 return FALSE;
172 /* Remove the class from the linked list */
173 if (firstClass == class) firstClass = classPtr->hNext;
174 else
176 for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
178 prevClassPtr = (CLASS *) USER_HEAP_LIN_ADDR(prevClass);
179 if (prevClassPtr->hNext == class) break;
181 if (!prevClass)
183 fprintf(stderr, "ERROR: Class list corrupted\n" );
184 return FALSE;
186 prevClassPtr->hNext = classPtr->hNext;
189 /* Delete the class */
190 if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
191 if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
192 GlobalDeleteAtom( classPtr->atomName );
193 if (HIWORD(classPtr->wc.lpszMenuName))
194 USER_HEAP_FREE( LOWORD(classPtr->wc.lpszMenuName) );
195 USER_HEAP_FREE( class );
196 return TRUE;
200 /***********************************************************************
201 * GetClassWord (USER.129)
203 WORD GetClassWord( HWND hwnd, short offset )
205 return (WORD)GetClassLong( hwnd, offset );
209 /***********************************************************************
210 * SetClassWord (USER.130)
212 WORD SetClassWord( HWND hwnd, short offset, WORD newval )
214 CLASS * classPtr;
215 WND * wndPtr;
216 WORD *ptr, retval = 0;
218 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
219 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
220 ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
221 retval = *ptr;
222 *ptr = newval;
223 return retval;
227 /***********************************************************************
228 * GetClassLong (USER.131)
230 LONG GetClassLong( HWND hwnd, short offset )
232 CLASS * classPtr;
233 WND * wndPtr;
235 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
236 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
237 return *(LONG *)(((char *)classPtr->wExtra) + offset);
241 /***********************************************************************
242 * SetClassLong (USER.132)
244 LONG SetClassLong( HWND hwnd, short offset, LONG newval )
246 CLASS * classPtr;
247 WND * wndPtr;
248 LONG *ptr, retval = 0;
250 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
251 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
252 ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
253 retval = *ptr;
254 *ptr = newval;
255 return retval;
259 /***********************************************************************
260 * GetClassName (USER.58)
262 int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount)
264 WND *wndPtr;
265 CLASS *classPtr;
267 /* FIXME: We have the find the correct hInstance */
268 dprintf_class(stddeb,"GetClassName(%x,%p,%d)\n",hwnd,lpClassName,maxCount);
269 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
270 if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0;
272 return GlobalGetAtomName(classPtr->atomName, lpClassName, maxCount);
276 /***********************************************************************
277 * GetClassInfo (USER.404)
279 BOOL GetClassInfo( HANDLE hInstance, SEGPTR name, LPWNDCLASS lpWndClass )
281 CLASS *classPtr;
283 dprintf_class( stddeb, "GetClassInfo: hInstance=%04x className=%s\n",
284 hInstance,
285 HIWORD(name) ? (char *)PTR_SEG_TO_LIN(name) : "(int)" );
287 hInstance = GetExePtr( hInstance );
289 if (!(CLASS_FindClassByName( name, hInstance, &classPtr))) return FALSE;
290 if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE;
292 memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
293 return TRUE;
297 /***********************************************************************
298 * ClassFirst (TOOLHELP.69)
300 BOOL ClassFirst( CLASSENTRY *pClassEntry )
302 pClassEntry->wNext = firstClass;
303 return ClassNext( pClassEntry );
307 /***********************************************************************
308 * ClassNext (TOOLHELP.70)
310 BOOL ClassNext( CLASSENTRY *pClassEntry )
312 CLASS *classPtr = (CLASS *) USER_HEAP_LIN_ADDR( pClassEntry->wNext );
313 if (!classPtr) return FALSE;
315 pClassEntry->hInst = classPtr->wc.hInstance;
316 pClassEntry->wNext = classPtr->hNext;
317 GlobalGetAtomName( classPtr->atomName, pClassEntry->szClassName,
318 sizeof(pClassEntry->szClassName) );
319 return TRUE;