source: trunk/src/user32/win32class.cpp@ 1540

Last change on this file since 1540 was 1540, checked in by sandervl, 26 years ago

Activate + group box fixes + cleanup changes

File size: 17.1 KB
Line 
1/* $Id: win32class.cpp,v 1.5 1999-11-01 19:11:42 sandervl Exp $ */
2/*
3 * Win32 Window Class Managment Code for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 *
7 *
8 * TODO: Right now all class atoms are global. This must be changed.
9 * TODO: Global atoms of classes with CS_GLOBALCLASS flag are not deleted
10 * Must all be changed if we want to support global app classes
11 * that can be used by other apps. (low priority)
12 *
13 * Project Odin Software License can be found in LICENSE.TXT
14 *
15 */
16#include <os2win.h>
17#include <stdio.h>
18#include <stdlib.h>
19#include <string.h>
20#include <stdarg.h>
21#include <assert.h>
22#include <misc.h>
23#include <win32class.h>
24#include <win32wnd.h>
25
26static fDestroyAll = FALSE;
27
28//******************************************************************************
29//Win32WndClass methods:
30//******************************************************************************
31Win32WndClass::Win32WndClass(WNDCLASSEXA *wndclass, BOOL isUnicode) : GenericObject(&wndclasses, OBJTYPE_CLASS)
32{
33 this->isUnicode = isUnicode;
34 processId = 0;
35
36 if(HIWORD(wndclass->lpszClassName)) {
37 if(isUnicode) {
38 INT len = lstrlenW((LPWSTR)wndclass->lpszClassName)+1;
39
40 classNameA = (PCHAR)_smalloc(len);
41 classNameW = (WCHAR *)_smalloc(len*sizeof(WCHAR));
42 }
43 else {
44 INT len = strlen(wndclass->lpszClassName)+1;
45
46 classNameA = (PCHAR)_smalloc(len);
47 classNameW = (WCHAR *)_smalloc(len*sizeof(WCHAR));
48 }
49 if(classNameA == NULL || classNameW == NULL) {
50 dprintf(("Win32Class ctr; classNameA/classNameW == NULL"));
51 exit(1);
52 }
53 if(isUnicode) {
54 lstrcpyW(classNameW, (LPWSTR)wndclass->lpszClassName);
55 UnicodeToAscii(classNameW, classNameA);
56 }
57 else {
58 strcpy((char *)classNameA, wndclass->lpszClassName);
59 AsciiToUnicode(classNameA, classNameW);
60 }
61 classAtom = 0;
62 //SvL: If a system control has already be registered, use that atom instead
63 // of creating a new one
64 if(wndclass->style & CS_GLOBALCLASS) {
65 classAtom = GlobalFindAtomA(classNameA);
66 }
67 if(!classAtom) classAtom = GlobalAddAtomA(classNameA);
68 }
69 else {
70 classNameA = NULL;
71 classNameW = NULL;
72 classAtom = (DWORD)wndclass->lpszClassName;
73 }
74 if(!(wndclass->style & CS_GLOBALCLASS)) {
75 processId = GetCurrentProcess();
76 }
77 menuNameA = 0;
78 menuNameW = 0;
79 setMenuName((LPSTR)wndclass->lpszMenuName);
80
81 dprintf(("USER32: Win32Class ctor\n"));
82 dprintf(("USER32: wndclass->style %X\n", wndclass->style));
83 dprintf(("USER32: wndclass->lpfnWndProc %X\n", wndclass->lpfnWndProc));
84 dprintf(("USER32: wndclass->cbClsExtra %X\n", wndclass->cbClsExtra));
85 dprintf(("USER32: wndclass->cbWndExtra %X\n", wndclass->cbWndExtra));
86 dprintf(("USER32: wndclass->hInstance %X\n", wndclass->hInstance));
87 dprintf(("USER32: wndclass->hIcon %X\n", wndclass->hIcon));
88 dprintf(("USER32: wndclass->hCursor %X\n", wndclass->hCursor));
89 dprintf(("USER32: wndclass->hbrBackground %X\n", wndclass->hbrBackground));
90 if(HIWORD(wndclass->lpszClassName))
91 dprintf(("USER32: wndclass->lpszClassName %s\n", classNameA));
92 else dprintf(("USER32: wndclass->lpszClassName %X\n", wndclass->lpszClassName));
93
94 if(HIWORD(wndclass->lpszMenuName)) {//convert string name identifier to numeric id
95 dprintf(("USER32: lpszMenuName %s\n", menuNameA));
96 }
97 else dprintf(("USER32: wndclass->lpszMenuName %X\n", menuNameA));
98
99 nrExtraClassWords = wndclass->cbClsExtra;
100 nrExtraWindowWords = wndclass->cbWndExtra;
101 backgroundBrush = wndclass->hbrBackground;
102 hCursor = wndclass->hCursor;
103 hIcon = wndclass->hIcon;
104 hInstance = wndclass->hInstance;
105
106 windowStyle = wndclass->style;
107 windowProc = wndclass->lpfnWndProc;
108
109 //User data class words/longs
110 if(nrExtraClassWords) {
111 userClassLong = (ULONG *)_smalloc(nrExtraClassWords);
112 if(userClassLong == NULL) {
113 dprintf(("Win32Class ctr: userClassLong == NULL!"));
114 exit(1);
115 }
116 memset(userClassLong, 0, nrExtraClassWords);
117 }
118 else userClassLong = NULL;
119
120 cWindows = 0;
121 hIconSm = wndclass->hIconSm;
122}
123//******************************************************************************
124//******************************************************************************
125Win32WndClass::~Win32WndClass()
126{
127 if(classNameA) {
128 dprintf(("Win32WndClass dtor, destroy class %s\n", classNameA));
129 }
130
131 //SvL: Don't delete global classes
132 if(classNameA && !(windowStyle & CS_GLOBALCLASS)) {
133 GlobalDeleteAtom(classAtom);
134 }
135
136 if(userClassLong) free(userClassLong);
137 if(classNameA) free(classNameA);
138 if(classNameW) free(classNameW);
139 if(menuNameA && HIWORD(menuNameA)) {
140 free(menuNameA);
141 assert(menuNameW);
142 free(menuNameW);
143 }
144}
145//******************************************************************************
146//******************************************************************************
147void Win32WndClass::DestroyAll()
148{
149 fDestroyAll = TRUE;
150 GenericObject::DestroyAll(wndclasses);
151}
152//******************************************************************************
153//******************************************************************************
154BOOL Win32WndClass::hasClassName(LPSTR classname, BOOL fUnicode)
155{
156 if(HIWORD(classname) == 0) {
157 return classAtom == (DWORD)classname;
158 }
159 if(fUnicode) {
160 return (lstrcmpW(classNameW, (LPWSTR)classname) == 0);
161 }
162 else return (strcmp(classNameA, classname) == 0);
163}
164//******************************************************************************
165//******************************************************************************
166Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPSTR id)
167{
168 enterMutex(OBJTYPE_CLASS);
169
170 Win32WndClass *wndclass = (Win32WndClass *)wndclasses;
171
172 if(wndclass == NULL) {
173 leaveMutex(OBJTYPE_CLASS);
174 return(NULL);
175 }
176
177 if(HIWORD(id) != 0) {
178//CB: read comment below!
179 if(stricmp(wndclass->classNameA, id) == 0 && wndclass->hInstance == hInstance) {
180 leaveMutex(OBJTYPE_CLASS);
181 return(wndclass);
182 }
183 else {
184 wndclass = (Win32WndClass *)wndclass->GetNext();
185 while(wndclass != NULL) {
186 if(stricmp(wndclass->classNameA, id) == 0)
187 {
188 //SvL: According to Wine, if the instance handle is the one of the main exe, everything is ok
189 if(hInstance == NULL || GetModuleHandleA(NULL) == hInstance ||
190 wndclass->hInstance == hInstance)
191 {
192 leaveMutex(OBJTYPE_CLASS);
193 return(wndclass);
194 }
195 }
196 wndclass = (Win32WndClass *)wndclass->GetNext();
197 }
198 }
199 }
200 else {
201//CB: without HInstance check, test program finds class
202//CB: need more code to compare instance; convert 0 to exe module handle
203 if(wndclass->classAtom == (DWORD)id /*&& wndclass->hInstance == hInstance*/) {
204 leaveMutex(OBJTYPE_CLASS);
205 return(wndclass);
206 }
207 else {
208 wndclass = (Win32WndClass *)wndclass->GetNext();
209 while(wndclass != NULL) {
210 if(wndclass->classAtom == (DWORD)id /* && wndclass->hInstance == hInstance*/) {
211 leaveMutex(OBJTYPE_CLASS);
212 return(wndclass);
213 }
214 wndclass = (Win32WndClass *)wndclass->GetNext();
215 }
216 }
217 }
218 leaveMutex(OBJTYPE_CLASS);
219 dprintf(("Class %X (inst %X) not found!", id, hInstance));
220 return(NULL);
221}
222//******************************************************************************
223//An app can only access another process' class if it's global
224//(all system classes are global)
225//NOTE: NOT USED NOW
226//******************************************************************************
227BOOL Win32WndClass::isAppClass(ULONG curProcessId)
228{
229 if(windowStyle & CS_GLOBALCLASS)
230 return TRUE;
231
232 return curProcessId = processId;
233}
234//******************************************************************************
235//******************************************************************************
236BOOL Win32WndClass::getClassInfo(WNDCLASSEXA *wndclass)
237{
238 wndclass->cbClsExtra = nrExtraClassWords;
239 wndclass->cbWndExtra = nrExtraWindowWords;
240 wndclass->hbrBackground = backgroundBrush;
241 wndclass->hCursor = hCursor;
242 wndclass->hIcon = hIcon;
243 wndclass->hInstance = hInstance;
244 wndclass->lpszMenuName = (LPCTSTR)menuNameA;
245 wndclass->lpszClassName = (classNameA) ? (LPCTSTR)classNameA : (LPCTSTR)classAtom;
246 wndclass->style = windowStyle;
247 wndclass->lpfnWndProc = windowProc;
248 wndclass->hIconSm = hIconSm;
249 return(TRUE);
250}
251//******************************************************************************
252//******************************************************************************
253BOOL Win32WndClass::getClassInfo(WNDCLASSEXW *wndclass)
254{
255 wndclass->cbClsExtra = nrExtraClassWords;
256 wndclass->cbWndExtra = nrExtraWindowWords;
257 wndclass->hbrBackground = backgroundBrush;
258 wndclass->hCursor = hCursor;
259 wndclass->hIcon = hIcon;
260 wndclass->hInstance = hInstance;
261 wndclass->lpszMenuName = (LPCWSTR)menuNameW;
262 wndclass->lpszClassName = (classNameW) ? (LPCWSTR)classNameW : (LPCWSTR)classAtom;
263 wndclass->style = windowStyle;
264 wndclass->lpfnWndProc = windowProc;
265 wndclass->hIconSm = hIconSm;
266 return(TRUE);
267}
268//******************************************************************************
269//******************************************************************************
270ULONG Win32WndClass::getClassName(LPSTR lpszClassName, ULONG cchClassName)
271{
272 if(HIWORD(classNameA)) {
273 strncpy(lpszClassName, classNameA, cchClassName-1);
274 return strlen(lpszClassName);
275 }
276 *(ULONG *)lpszClassName = classAtom;
277 return(sizeof(ULONG));
278}
279//******************************************************************************
280//******************************************************************************
281ULONG Win32WndClass::getClassName(LPWSTR lpszClassName, ULONG cchClassName)
282{
283 ULONG len;
284
285 if(HIWORD(classNameW)) {
286 lstrcpyW(lpszClassName, classNameW);
287 return lstrlenW(lpszClassName)*sizeof(WCHAR);
288 }
289 *(ULONG *)lpszClassName = classAtom;
290 return(sizeof(ULONG));
291}
292//******************************************************************************
293//******************************************************************************
294void Win32WndClass::setMenuName(LPSTR newMenuName)
295{
296 if(HIWORD(menuNameA)) {
297 free(menuNameA);
298 free(menuNameW);
299 menuNameA = 0;
300 menuNameW = 0;
301 }
302 if(HIWORD(newMenuName)) {
303 if(isUnicode) {
304 menuNameA = (PCHAR)_smalloc(lstrlenW((LPWSTR)newMenuName)+1);
305 menuNameW = (WCHAR *)_smalloc((lstrlenW((LPWSTR)newMenuName)+1)*sizeof(WCHAR));
306 }
307 else {
308 menuNameA = (PCHAR)_smalloc(strlen(newMenuName)+1);
309 menuNameW = (WCHAR *)_smalloc((strlen(newMenuName)+1)*sizeof(WCHAR));
310 }
311 if(menuNameA == NULL || menuNameW == NULL) {
312 dprintf(("Win32Class ctr; menuName/menuNameW == NULL"));
313 exit(1);
314 }
315 if(isUnicode) {
316 lstrcpyW(menuNameW, (LPWSTR)newMenuName);
317 UnicodeToAscii(menuNameW, menuNameA);
318 }
319 else {
320 strcpy((char *)menuNameA, newMenuName);
321 AsciiToUnicode(menuNameA, menuNameW);
322 }
323 }
324 else {//id
325 menuNameA = (PCHAR)newMenuName;
326 menuNameW = (WCHAR *)newMenuName;
327 }
328}
329//******************************************************************************
330//******************************************************************************
331ULONG Win32WndClass::getClassLongA(int index, BOOL isUnicode)
332{
333 switch(index) {
334 case GCL_CBCLSEXTRA:
335 return nrExtraClassWords;
336 case GCL_CBWNDEXTRA:
337 return nrExtraWindowWords;
338 case GCL_HBRBACKGROUND:
339 return backgroundBrush;
340 case GCL_HCURSOR:
341 return hCursor;
342 case GCL_HICON:
343 return hIcon;
344 case GCL_HMODULE:
345 return hInstance;
346 case GCL_MENUNAME:
347 return (isUnicode) ? (ULONG)menuNameW : (ULONG)menuNameA;
348 case GCL_STYLE:
349 return windowStyle;
350 case GCL_WNDPROC:
351 return (ULONG)windowProc;
352 case GCW_ATOM: //TODO: does this really happen in windows?
353 SetLastError(ERROR_INVALID_PARAMETER);
354 return 0;
355 default:
356 if(index > 0 && index < nrExtraClassWords - sizeof(ULONG)) {
357 return userClassLong[index];
358 }
359 SetLastError(ERROR_INVALID_PARAMETER);
360 return 0;
361 }
362}
363//******************************************************************************
364//******************************************************************************
365WORD Win32WndClass::getClassWord(int index)
366{
367 switch(index) {
368 case GCW_ATOM:
369 return (WORD)classAtom;
370 default:
371 if(index > 0 && index < nrExtraClassWords - sizeof(WORD)) {
372 return ((WORD *)userClassLong)[index];
373 }
374 SetLastError(ERROR_INVALID_PARAMETER);
375 return 0;
376 }
377}
378//******************************************************************************
379//TODO: What effects what immediately?
380//******************************************************************************
381ULONG Win32WndClass::setClassLongA(int index, LONG lNewVal, BOOL isUnicode)
382{
383 ULONG rc;
384
385 switch(index) {
386 case GCL_CBCLSEXTRA: //TODO (doesn't affect allocated classes, so what does it do?)
387 rc = nrExtraClassWords;
388// nrExtraClassWords = lNewVal;
389 break;
390 case GCL_CBWNDEXTRA:
391 rc = nrExtraWindowWords;
392 nrExtraWindowWords = lNewVal;
393 break;
394 case GCL_HBRBACKGROUND:
395 rc = backgroundBrush;
396 backgroundBrush = lNewVal;
397 break;
398 case GCL_HCURSOR:
399 rc = hCursor;
400 hCursor = lNewVal;
401 break;
402 case GCL_HICON:
403 rc = hIcon;
404 hIcon = lNewVal;
405 break;
406 case GCL_HMODULE:
407 rc = hInstance;
408 hInstance = lNewVal;
409 break;
410 case GCL_MENUNAME:
411 rc = 0; //old value is meaningless (according to Wine)
412 setMenuName((LPSTR)lNewVal);
413 break;
414 case GCL_STYLE:
415 rc = windowStyle;
416 windowStyle = lNewVal;
417 break;
418 case GCL_WNDPROC:
419 rc = (ULONG)windowProc;
420 windowProc = (WNDPROC)lNewVal;
421 break;
422 case GCW_ATOM: //TODO: does this really happen in windows?
423 SetLastError(ERROR_INVALID_PARAMETER);
424 return 0;
425 default:
426 if(index > 0 && index < nrExtraClassWords - sizeof(ULONG)) {
427 rc = userClassLong[index];
428 userClassLong[index] = lNewVal;
429 return(rc);
430 }
431 SetLastError(ERROR_INVALID_PARAMETER);
432 return 0;
433 }
434 return(rc);
435}
436//******************************************************************************
437//******************************************************************************
438WORD Win32WndClass::setClassWord(int index, WORD wNewVal)
439{
440 WORD rc;
441
442 switch(index) {
443 case GCW_ATOM:
444 rc = (WORD)classAtom;
445 classAtom = wNewVal;
446 return(rc);
447 default:
448 if(index > 0 && index < nrExtraClassWords - sizeof(WORD)) {
449 rc = ((WORD *)userClassLong)[index];
450 ((WORD *)userClassLong)[index] = wNewVal;
451 return(rc);
452 }
453 SetLastError(ERROR_INVALID_PARAMETER);
454 return 0;
455 }
456}
457//******************************************************************************
458//FIXME: Windows that still exists with this class
459//******************************************************************************
460void Win32WndClass::UnregisterClassA(HINSTANCE hinst, LPSTR id)
461{
462 Win32WndClass *wndclass;
463
464 wndclass = FindClass(hinst, id);
465 if(wndclass) {
466 delete wndclass;
467 return;
468 }
469 dprintf(("::UnregisterClass, couldn't find class %X!!\n", id));
470}
471//******************************************************************************
472//******************************************************************************
473GenericObject *Win32WndClass::wndclasses = NULL;
Note: See TracBrowser for help on using the repository browser.