2 * Window classes functions
4 * Copyright 1993 Alexandre Julliard
7 static char Copyright
[] = "Copyright Alexandre Julliard, 1993";
15 static HCLASS firstClass
= 0;
18 /***********************************************************************
19 * CLASS_FindClassByName
21 * Return a handle and a pointer to the class.
22 * 'ptr' can be NULL if the pointer is not needed.
24 HCLASS
CLASS_FindClassByName( char * name
, CLASS
**ptr
)
30 /* First search task-specific classes */
32 if ((atom
= FindAtom( name
)) != 0)
34 for (class = firstClass
; (class); class = classPtr
->hNext
)
36 classPtr
= (CLASS
*) USER_HEAP_ADDR(class);
37 if (classPtr
->wc
.style
& CS_GLOBALCLASS
) continue;
38 if (classPtr
->atomName
== atom
)
40 if (ptr
) *ptr
= classPtr
;
46 /* Then search global classes */
48 if ((atom
= GlobalFindAtom( name
)) != 0)
50 for (class = firstClass
; (class); class = classPtr
->hNext
)
52 classPtr
= (CLASS
*) USER_HEAP_ADDR(class);
53 if (!(classPtr
->wc
.style
& CS_GLOBALCLASS
)) continue;
54 if (classPtr
->atomName
== atom
)
56 if (ptr
) *ptr
= classPtr
;
66 /***********************************************************************
69 * Return a pointer to the CLASS structure corresponding to a HCLASS.
71 CLASS
* CLASS_FindClassPtr( HCLASS hclass
)
75 if (!hclass
) return NULL
;
76 ptr
= (CLASS
*) USER_HEAP_ADDR( hclass
);
77 if (ptr
->wMagic
!= CLASS_MAGIC
) return NULL
;
82 /***********************************************************************
83 * RegisterClass (USER.57)
85 ATOM
RegisterClass( LPWNDCLASS
class )
87 CLASS
* newClass
, * prevClassPtr
;
88 HCLASS handle
, prevClass
;
91 printf( "RegisterClass: wndproc=%08x hinst=%d name='%s'\n",
92 class->lpfnWndProc
, class->hInstance
, class->lpszClassName
);
95 /* Check if a class with this name already exists */
97 prevClass
= CLASS_FindClassByName( class->lpszClassName
, &prevClassPtr
);
100 /* Class can be created only if it is local and */
101 /* if the class with the same name is global. */
103 if (class->style
& CS_GLOBALCLASS
) return 0;
104 if (!(prevClassPtr
->wc
.style
& CS_GLOBALCLASS
)) return 0;
109 handle
= USER_HEAP_ALLOC( GMEM_MOVEABLE
, sizeof(CLASS
)+class->cbClsExtra
);
110 if (!handle
) return 0;
111 newClass
= (CLASS
*) USER_HEAP_ADDR( handle
);
112 newClass
->hNext
= firstClass
;
113 newClass
->wMagic
= CLASS_MAGIC
;
114 newClass
->cWindows
= 0;
115 newClass
->wc
= *class;
117 if (newClass
->wc
.style
& CS_GLOBALCLASS
)
118 newClass
->atomName
= GlobalAddAtom( class->lpszClassName
);
119 else newClass
->atomName
= AddAtom( class->lpszClassName
);
121 if (newClass
->wc
.style
& CS_CLASSDC
)
122 newClass
->hdce
= DCE_AllocDCE( DCE_CLASS_DC
);
123 else newClass
->hdce
= 0;
125 /* Menu name should also be set to zero. */
126 newClass
->wc
.lpszClassName
= NULL
;
128 if (class->cbClsExtra
) memset( newClass
->wExtra
, 0, class->cbClsExtra
);
130 return newClass
->atomName
;
134 /***********************************************************************
135 * UnregisterClass (USER.403)
137 BOOL
UnregisterClass( LPSTR className
, HANDLE instance
)
139 HANDLE
class, next
, prevClass
;
140 CLASS
* classPtr
, * prevClassPtr
;
142 /* Check if we can remove this class */
143 class = CLASS_FindClassByName( className
, &classPtr
);
144 if (!class) return FALSE
;
145 if ((classPtr
->wc
.hInstance
!= instance
) || (classPtr
->cWindows
> 0))
148 /* Remove the class from the linked list */
149 if (firstClass
== class) firstClass
= classPtr
->hNext
;
152 for (prevClass
= firstClass
; prevClass
; prevClass
=prevClassPtr
->hNext
)
154 prevClassPtr
= (CLASS
*) USER_HEAP_ADDR(prevClass
);
155 if (prevClassPtr
->hNext
== class) break;
159 printf( "ERROR: Class list corrupted\n" );
162 prevClassPtr
->hNext
= classPtr
->hNext
;
165 /* Delete the class */
166 if (classPtr
->hdce
) DCE_FreeDCE( classPtr
->hdce
);
167 if (classPtr
->wc
.hbrBackground
) DeleteObject( classPtr
->wc
.hbrBackground
);
168 if (classPtr
->wc
.style
& CS_GLOBALCLASS
) GlobalDeleteAtom( classPtr
->atomName
);
169 else DeleteAtom( classPtr
->atomName
);
170 USER_HEAP_FREE( class );
175 /***********************************************************************
176 * GetClassWord (USER.129)
178 WORD
GetClassWord( HWND hwnd
, short offset
)
180 return (WORD
)GetClassLong( hwnd
, offset
);
184 /***********************************************************************
185 * SetClassWord (USER.130)
187 WORD
SetClassWord( HWND hwnd
, short offset
, WORD newval
)
191 WORD
*ptr
, retval
= 0;
193 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
194 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
195 ptr
= (WORD
*)(((char *)classPtr
->wExtra
) + offset
);
202 /***********************************************************************
203 * GetClassLong (USER.131)
205 LONG
GetClassLong( HWND hwnd
, short offset
)
210 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
211 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
212 return *(LONG
*)(((char *)classPtr
->wExtra
) + offset
);
216 /***********************************************************************
217 * SetClassLong (USER.132)
219 LONG
SetClassLong( HWND hwnd
, short offset
, LONG newval
)
223 LONG
*ptr
, retval
= 0;
225 if (!(wndPtr
= WIN_FindWndPtr( hwnd
))) return 0;
226 if (!(classPtr
= CLASS_FindClassPtr( wndPtr
->hClass
))) return 0;
227 ptr
= (LONG
*)(((char *)classPtr
->wExtra
) + offset
);
234 /***********************************************************************
235 * GetClassName (USER.58)
237 int GetClassName(HWND hwnd
, LPSTR lpClassName
, short maxCount
)
242 if (!(wndPtr
= WIN_FindWndPtr(hwnd
))) return 0;
243 if (!(classPtr
= CLASS_FindClassPtr(wndPtr
->hClass
))) return 0;
245 return (GetAtomName(classPtr
->atomName
, lpClassName
, maxCount
));
249 /***********************************************************************
250 * GetClassInfo (USER.404)
252 BOOL
GetClassInfo(HANDLE hInstance
, LPSTR lpClassName
,
253 LPWNDCLASS lpWndClass
)
257 if (!(CLASS_FindClassByName(lpClassName
, &classPtr
))) return FALSE
;
258 if (hInstance
&& (hInstance
!= classPtr
->wc
.hInstance
)) return FALSE
;
260 memcpy(lpWndClass
, &(classPtr
->wc
), sizeof(WNDCLASS
));