Release 951226
[wine/gsoc-2012-control.git] / windows / class.c
blobf148b38a82d1238120eb1a37175c4615845a20cc
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, HINSTANCE 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==(HINSTANCE)0xffff) ||
47 (hinstance == classPtr->wc.hInstance) ) )
49 if (ptr) *ptr = classPtr;
50 return class;
54 /* Then search global classes */
56 for (class = firstClass; (class); class = classPtr->hNext)
58 classPtr = (CLASS *) USER_HEAP_LIN_ADDR(class);
59 if (!(classPtr->wc.style & CS_GLOBALCLASS)) continue;
60 if (classPtr->atomName == atom)
62 if (ptr) *ptr = classPtr;
63 return class;
67 return 0;
71 /***********************************************************************
72 * CLASS_FindClassPtr
74 * Return a pointer to the CLASS structure corresponding to a HCLASS.
76 CLASS * CLASS_FindClassPtr( HCLASS hclass )
78 CLASS * ptr;
80 if (!hclass) return NULL;
81 ptr = (CLASS *) USER_HEAP_LIN_ADDR( hclass );
82 if (ptr->wMagic != CLASS_MAGIC) return NULL;
83 return ptr;
87 /***********************************************************************
88 * RegisterClass (USER.57)
90 ATOM RegisterClass( LPWNDCLASS class )
92 CLASS * newClass, * prevClassPtr;
93 HCLASS handle, prevClass;
94 int classExtra;
96 dprintf_class( stddeb, "RegisterClass: wndproc=%08lx hinst="NPFMT" name='%s' background "NPFMT"\n",
97 (DWORD)class->lpfnWndProc, class->hInstance,
98 HIWORD(class->lpszClassName) ?
99 (char *)PTR_SEG_TO_LIN(class->lpszClassName) : "(int)",
100 class->hbrBackground );
101 dprintf_class(stddeb," style=%04x clsExtra=%d winExtra=%d\n",
102 class->style, class->cbClsExtra, class->cbWndExtra );
104 /* Window classes are owned by modules, not instances */
105 class->hInstance = GetExePtr( class->hInstance );
107 /* Check if a class with this name already exists */
108 prevClass = CLASS_FindClassByName( class->lpszClassName,
109 class->hInstance, &prevClassPtr );
110 if (prevClass)
112 /* Class can be created only if it is local and */
113 /* if the class with the same name is global. */
115 if (class->style & CS_GLOBALCLASS) return 0;
116 if (!(prevClassPtr->wc.style & CS_GLOBALCLASS)) return 0;
119 /* Create class */
121 classExtra = (class->cbClsExtra < 0) ? 0 : class->cbClsExtra;
122 handle = USER_HEAP_ALLOC( sizeof(CLASS) + classExtra );
123 if (!handle) return 0;
124 newClass = (CLASS *) USER_HEAP_LIN_ADDR( handle );
125 newClass->hNext = firstClass;
126 newClass->wMagic = CLASS_MAGIC;
127 newClass->cWindows = 0;
128 newClass->wc = *class;
129 newClass->wc.cbWndExtra = (class->cbWndExtra < 0) ? 0 : class->cbWndExtra;
130 newClass->wc.cbClsExtra = classExtra;
132 newClass->atomName = GlobalAddAtom( class->lpszClassName );
133 newClass->wc.lpszClassName = 0;
135 if (newClass->wc.style & CS_CLASSDC)
136 newClass->hdce = DCE_AllocDCE( DCE_CLASS_DC );
137 else newClass->hdce = 0;
139 /* Make a copy of the menu name (only if it is a string) */
141 if (HIWORD(class->lpszMenuName))
143 char *menuname = PTR_SEG_TO_LIN( class->lpszMenuName );
144 HANDLE hname = USER_HEAP_ALLOC( strlen(menuname)+1 );
145 if (hname)
147 newClass->wc.lpszMenuName = (SEGPTR)USER_HEAP_SEG_ADDR( hname );
148 strcpy( USER_HEAP_LIN_ADDR( hname ), menuname );
152 if (classExtra) memset( newClass->wExtra, 0, classExtra );
153 firstClass = handle;
154 return newClass->atomName;
158 /***********************************************************************
159 * UnregisterClass (USER.403)
161 BOOL UnregisterClass( SEGPTR className, HANDLE hinstance )
163 HANDLE class, prevClass;
164 CLASS * classPtr, * prevClassPtr;
166 hinstance = GetExePtr( hinstance );
167 /* Check if we can remove this class */
168 class = CLASS_FindClassByName( className, hinstance, &classPtr );
169 if (!class) return FALSE;
170 if ((classPtr->wc.hInstance != hinstance) || (classPtr->cWindows > 0))
171 return FALSE;
173 /* Remove the class from the linked list */
174 if (firstClass == class) firstClass = classPtr->hNext;
175 else
177 for (prevClass = firstClass; prevClass; prevClass=prevClassPtr->hNext)
179 prevClassPtr = (CLASS *) USER_HEAP_LIN_ADDR(prevClass);
180 if (prevClassPtr->hNext == class) break;
182 if (!prevClass)
184 fprintf(stderr, "ERROR: Class list corrupted\n" );
185 return FALSE;
187 prevClassPtr->hNext = classPtr->hNext;
190 /* Delete the class */
191 if (classPtr->hdce) DCE_FreeDCE( classPtr->hdce );
192 if (classPtr->wc.hbrBackground) DeleteObject( classPtr->wc.hbrBackground );
193 GlobalDeleteAtom( classPtr->atomName );
194 if (HIWORD(classPtr->wc.lpszMenuName))
195 #ifdef WINELIB32
196 USER_HEAP_FREE( (HANDLE)classPtr->wc.lpszMenuName );
197 #else
198 USER_HEAP_FREE( LOWORD(classPtr->wc.lpszMenuName) );
199 #endif
200 USER_HEAP_FREE( class );
201 return TRUE;
205 /***********************************************************************
206 * GetClassWord (USER.129)
208 WORD GetClassWord( HWND hwnd, short offset )
210 return (WORD)GetClassLong( hwnd, offset );
214 /***********************************************************************
215 * SetClassWord (USER.130)
217 WORD SetClassWord( HWND hwnd, short offset, WORD newval )
219 CLASS * classPtr;
220 WND * wndPtr;
221 WORD *ptr, retval = 0;
223 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
224 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
225 ptr = (WORD *)(((char *)classPtr->wExtra) + offset);
226 retval = *ptr;
227 *ptr = newval;
228 return retval;
232 /***********************************************************************
233 * GetClassLong (USER.131)
235 LONG GetClassLong( HWND hwnd, short offset )
237 CLASS * classPtr;
238 WND * wndPtr;
240 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
241 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
242 return *(LONG *)(((char *)classPtr->wExtra) + offset);
246 /***********************************************************************
247 * SetClassLong (USER.132)
249 LONG SetClassLong( HWND hwnd, short offset, LONG newval )
251 CLASS * classPtr;
252 WND * wndPtr;
253 LONG *ptr, retval = 0;
255 if (!(wndPtr = WIN_FindWndPtr( hwnd ))) return 0;
256 if (!(classPtr = CLASS_FindClassPtr( wndPtr->hClass ))) return 0;
257 ptr = (LONG *)(((char *)classPtr->wExtra) + offset);
258 retval = *ptr;
259 *ptr = newval;
260 return retval;
264 /***********************************************************************
265 * GetClassName (USER.58)
267 int GetClassName(HWND hwnd, LPSTR lpClassName, short maxCount)
269 WND *wndPtr;
270 CLASS *classPtr;
272 /* FIXME: We have the find the correct hInstance */
273 dprintf_class(stddeb,"GetClassName("NPFMT",%p,%d)\n",hwnd,lpClassName,maxCount);
274 if (!(wndPtr = WIN_FindWndPtr(hwnd))) return 0;
275 if (!(classPtr = CLASS_FindClassPtr(wndPtr->hClass))) return 0;
277 return GlobalGetAtomName(classPtr->atomName, lpClassName, maxCount);
281 /***********************************************************************
282 * GetClassInfo (USER.404)
284 BOOL GetClassInfo( HANDLE hInstance, SEGPTR name, LPWNDCLASS lpWndClass )
286 CLASS *classPtr;
288 dprintf_class( stddeb, "GetClassInfo: hInstance="NPFMT" className=%s\n",
289 hInstance,
290 HIWORD(name) ? (char *)PTR_SEG_TO_LIN(name) : "(int)" );
292 hInstance = GetExePtr( hInstance );
294 if (!(CLASS_FindClassByName( name, hInstance, &classPtr))) return FALSE;
295 if (hInstance && (hInstance != classPtr->wc.hInstance)) return FALSE;
297 memcpy(lpWndClass, &(classPtr->wc), sizeof(WNDCLASS));
298 return TRUE;
302 /***********************************************************************
303 * ClassFirst (TOOLHELP.69)
305 BOOL ClassFirst( CLASSENTRY *pClassEntry )
307 pClassEntry->wNext = firstClass;
308 return ClassNext( pClassEntry );
312 /***********************************************************************
313 * ClassNext (TOOLHELP.70)
315 BOOL ClassNext( CLASSENTRY *pClassEntry )
317 CLASS *classPtr = (CLASS *) USER_HEAP_LIN_ADDR( pClassEntry->wNext );
318 if (!classPtr) return FALSE;
320 pClassEntry->hInst = classPtr->wc.hInstance;
321 pClassEntry->wNext = classPtr->hNext;
322 GlobalGetAtomName( classPtr->atomName, pClassEntry->szClassName,
323 sizeof(pClassEntry->szClassName) );
324 return TRUE;