2 * Window classes functions
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
17 /* #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
, CLASS
**ptr
)
35 /* First search task-specific classes */
37 if ((atom
= FindAtom( name
)) != 0)
39 for (class = firstClass
; (class); class = classPtr
->hNext
)
41 classPtr
= (CLASS
*) USER_HEAP_ADDR(class);
42 if (classPtr
->wc
.style
& CS_GLOBALCLASS
) continue;
43 if (classPtr
->atomName
== atom
)
45 if (ptr
) *ptr
= classPtr
;
51 /* Then search global classes */
53 if ((atom
= GlobalFindAtom( name
)) != 0)
55 for (class = firstClass
; (class); class = classPtr
->hNext
)
57 classPtr
= (CLASS
*) USER_HEAP_ADDR(class);
58 if (!(classPtr
->wc
.style
& CS_GLOBALCLASS
)) continue;
59 if (classPtr
->atomName
== atom
)
61 if (ptr
) *ptr
= classPtr
;
71 /***********************************************************************
74 * Return a pointer to the CLASS structure corresponding to a HCLASS.
76 CLASS
* CLASS_FindClassPtr( HCLASS hclass
)
80 if (!hclass
) return NULL
;
81 ptr
= (CLASS
*) USER_HEAP_ADDR( hclass
);
82 if (ptr
->wMagic
!= CLASS_MAGIC
) return NULL
;
87 /***********************************************************************
88 * RegisterClass (USER.57)
90 ATOM
RegisterClass( LPWNDCLASS
class )
92 CLASS
* newClass
, * prevClassPtr
;
93 HCLASS handle
, prevClass
;
96 printf( "RegisterClass: wndproc=%08x hinst=%d name='%s' background %x\n",
97 class->lpfnWndProc
, class->hInstance
, class->lpszClassName
,
98 class->hbrBackground
);
101 /* Check if a class with this name already exists */
103 prevClass
= CLASS_FindClassByName( class->lpszClassName
, &prevClassPtr
);
106 /* Class can be created only if it is local and */
107 /* if the class with the same name is global. */
109 if (class->style
& CS_GLOBALCLASS
) return 0;
110 if (!(prevClassPtr
->wc
.style
& CS_GLOBALCLASS
)) return 0;
115 handle
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(CLASS
)+class->cbClsExtra
);
116 if (!handle
) return 0;
117 newClass
= (CLASS
*) USER_HEAP_ADDR( handle
);
118 newClass
->hNext
= firstClass
;
119 newClass
->wMagic
= CLASS_MAGIC
;
120 newClass
->cWindows
= 0;
121 newClass
->wc
= *class;
123 if (newClass
->wc
.style
& CS_GLOBALCLASS
)
124 newClass
->atomName
= GlobalAddAtom( class->lpszClassName
);
125 else newClass
->atomName
= AddAtom( class->lpszClassName
);
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)
137 hname
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, strlen(class->lpszMenuName
)+1);
140 newClass
->wc
.lpszMenuName
= (char *)USER_HEAP_ADDR( hname
);
141 strcpy( newClass
->wc
.lpszMenuName
, class->lpszMenuName
);
145 if (class->cbClsExtra
) memset( newClass
->wExtra
, 0, class->cbClsExtra
);
147 return newClass
->atomName
;
151 /***********************************************************************
152 * UnregisterClass (USER.403)
154 BOOL
UnregisterClass( LPSTR className
, HANDLE instance
)
156 HANDLE
class, prevClass
;
157 CLASS
* classPtr
, * prevClassPtr
;
159 /* Check if we can remove this class */
160 class = CLASS_FindClassByName( className
, &classPtr
);
161 if (!class) return FALSE
;
162 if ((classPtr
->wc
.hInstance
!= instance
) || (classPtr
->cWindows
> 0))
165 /* Remove the class from the linked list */
166 if (firstClass
== class) firstClass
= classPtr
->hNext
;
169 for (prevClass
= firstClass
; prevClass
; prevClass
=prevClassPtr
->hNext
)
171 prevClassPtr
= (CLASS
*) USER_HEAP_ADDR(prevClass
);
172 if (prevClassPtr
->hNext
== class) break;
176 printf( "ERROR: Class list corrupted\n" );
179 prevClassPtr
->hNext
= classPtr
->hNext
;
182 /* Delete the class */
183 if (classPtr
->hdce
) DCE_FreeDCE( classPtr
->hdce
);
184 if (classPtr
->wc
.hbrBackground
) DeleteObject( classPtr
->wc
.hbrBackground
);
185 if (classPtr
->wc
.style
& CS_GLOBALCLASS
) GlobalDeleteAtom( classPtr
->atomName
);
186 else DeleteAtom( classPtr
->atomName
);
187 if ((int)classPtr
->wc
.lpszMenuName
& 0xffff0000)
188 USER_HEAP_FREE( (int)classPtr
->wc
.lpszMenuName
& 0xffff );
189 USER_HEAP_FREE( class );
194 /***********************************************************************
195 * GetClassWord (USER.129)
197 WORD
GetClassWord( HWND hwnd
, short offset
)
199 return (WORD
)GetClassLong( hwnd
, offset
);
203 /***********************************************************************
204 * SetClassWord (USER.130)
206 WORD
SetClassWord( HWND hwnd
, short offset
, WORD newval
)
210 WORD
*ptr
, retval
= 0;
212 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
213 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
214 ptr
= (WORD
*)(((char *)classPtr
->wExtra
) + offset
);
221 /***********************************************************************
222 * GetClassLong (USER.131)
224 LONG
GetClassLong( HWND hwnd
, short offset
)
229 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
230 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
231 return *(LONG
*)(((char *)classPtr
->wExtra
) + offset
);
235 /***********************************************************************
236 * SetClassLong (USER.132)
238 LONG
SetClassLong( HWND hwnd
, short offset
, LONG newval
)
242 LONG
*ptr
, retval
= 0;
244 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
245 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
246 ptr
= (LONG
*)(((char *)classPtr
->wExtra
) + offset
);
253 /***********************************************************************
254 * GetClassName (USER.58)
256 int GetClassName(HWND hwnd
, LPSTR lpClassName
, short maxCount
)
261 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
262 if (!(classPtr
= CLASS_FindClassPtr(wndPtr
->hClass
))) return 0;
264 return (GetAtomName(classPtr
->atomName
, lpClassName
, maxCount
));
268 /***********************************************************************
269 * GetClassInfo (USER.404)
271 BOOL
GetClassInfo(HANDLE hInstance
, LPSTR lpClassName
,
272 LPWNDCLASS lpWndClass
)
276 if (!(CLASS_FindClassByName(lpClassName
, &classPtr
))) return FALSE
;
277 if (hInstance
&& (hInstance
!= classPtr
->wc
.hInstance
)) return FALSE
;
279 memcpy(lpWndClass
, &(classPtr
->wc
), sizeof(WNDCLASS
));