2 * Window classes functions
4 * Copyright 1993 Alexandre Julliard
18 /* #define DEBUG_CLASS */
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
)
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
;
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
;
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_LIN_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 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
);
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;
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 );
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
);
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))
173 /* Remove the class from the linked list */
174 if (firstClass
== class) firstClass
= classPtr
->hNext
;
177 for (prevClass
= firstClass
; prevClass
; prevClass
=prevClassPtr
->hNext
)
179 prevClassPtr
= (CLASS
*) USER_HEAP_LIN_ADDR(prevClass
);
180 if (prevClassPtr
->hNext
== class) break;
184 fprintf(stderr
, "ERROR: Class list corrupted\n" );
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
))
196 USER_HEAP_FREE( (HANDLE
)classPtr
->wc
.lpszMenuName
);
198 USER_HEAP_FREE( LOWORD(classPtr
->wc
.lpszMenuName
) );
200 USER_HEAP_FREE( class );
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
)
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
);
232 /***********************************************************************
233 * GetClassLong (USER.131)
235 LONG
GetClassLong( HWND hwnd
, short offset
)
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
)
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
);
264 /***********************************************************************
265 * GetClassName (USER.58)
267 int GetClassName(HWND hwnd
, LPSTR lpClassName
, short maxCount
)
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
)
288 dprintf_class( stddeb
, "GetClassInfo: hInstance="NPFMT
" className=%s\n",
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
));
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
) );