2 * Window classes functions
4 * Copyright 1993 Alexandre Julliard
6 static char Copyright[] = "Copyright Alexandre Julliard, 1993";
17 /* #define DEBUG_CLASS */
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
)
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
;
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
;
73 /***********************************************************************
76 * Return a pointer to the CLASS structure corresponding to a HCLASS.
78 CLASS
* CLASS_FindClassPtr( HCLASS hclass
)
82 if (!hclass
) return NULL
;
83 ptr
= (CLASS
*) USER_HEAP_ADDR( hclass
);
84 if (ptr
->wMagic
!= CLASS_MAGIC
) return NULL
;
89 /***********************************************************************
90 * RegisterClass (USER.57)
92 ATOM
RegisterClass( LPWNDCLASS
class )
94 CLASS
* newClass
, * prevClassPtr
;
95 HCLASS handle
, prevClass
;
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
,
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;
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)
142 hname
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, strlen(class->lpszMenuName
)+1);
145 newClass
->wc
.lpszMenuName
= (char *)USER_HEAP_ADDR( hname
);
146 strcpy( newClass
->wc
.lpszMenuName
, class->lpszMenuName
);
150 if (classExtra
) memset( newClass
->wExtra
, 0, classExtra
);
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))
170 /* Remove the class from the linked list */
171 if (firstClass
== class) firstClass
= classPtr
->hNext
;
174 for (prevClass
= firstClass
; prevClass
; prevClass
=prevClassPtr
->hNext
)
176 prevClassPtr
= (CLASS
*) USER_HEAP_ADDR(prevClass
);
177 if (prevClassPtr
->hNext
== class) break;
181 fprintf(stderr
, "ERROR: Class list corrupted\n" );
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 );
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
)
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
);
226 /***********************************************************************
227 * GetClassLong (USER.131)
229 LONG
GetClassLong( HWND hwnd
, short offset
)
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
)
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
);
258 /***********************************************************************
259 * GetClassName (USER.58)
261 int GetClassName(HWND hwnd
, LPSTR lpClassName
, short maxCount
)
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
)
282 if (HIWORD(lpClassName
))
284 dprintf_class(stddeb
, "GetClassInfo hInstance=%04x lpClassName=%s\n",
285 hInstance
, lpClassName
);
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
))
298 sprintf(temp
, "#%d", (int)lpClassName
);
299 if (!(CLASS_FindClassByName(temp
, hInstance
, &classPtr
))) return FALSE
;
305 if (hInstance
&& (hInstance
!= classPtr
->wc
.hInstance
)) return FALSE
;
307 memcpy(lpWndClass
, &(classPtr
->wc
), sizeof(WNDCLASS
));