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

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

EBs fixes

File size: 17.2 KB
Line 
1/* $Id: win32class.cpp,v 1.6 1999-11-05 09:16:22 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 if(classNameW)
161 return (lstrcmpW(classNameW, (LPWSTR)classname) == 0);
162 return FALSE;
163 }
164 else {
165 if(classNameA)
166 return (strcmp(classNameA, classname) == 0);
167 return FALSE;
168 }
169}
170//******************************************************************************
171//******************************************************************************
172Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPSTR id)
173{
174 enterMutex(OBJTYPE_CLASS);
175
176 Win32WndClass *wndclass = (Win32WndClass *)wndclasses;
177
178 if(wndclass == NULL) {
179 leaveMutex(OBJTYPE_CLASS);
180 return(NULL);
181 }
182
183 if(HIWORD(id) != 0) {
184//CB: read comment below!
185 if(lstrcmpiA(wndclass->classNameA, id) == 0 && wndclass->hInstance == hInstance) {
186 leaveMutex(OBJTYPE_CLASS);
187 return(wndclass);
188 }
189 else {
190 wndclass = (Win32WndClass *)wndclass->GetNext();
191 while(wndclass != NULL) {
192 if(lstrcmpiA(wndclass->classNameA, id) == 0)
193 {
194 //SvL: According to Wine, if the instance handle is the one of the main exe, everything is ok
195 if(hInstance == NULL || GetModuleHandleA(NULL) == hInstance ||
196 wndclass->hInstance == hInstance)
197 {
198 leaveMutex(OBJTYPE_CLASS);
199 return(wndclass);
200 }
201 }
202 wndclass = (Win32WndClass *)wndclass->GetNext();
203 }
204 }
205 }
206 else {
207//CB: without HInstance check, test program finds class
208//CB: need more code to compare instance; convert 0 to exe module handle
209 if(wndclass->classAtom == (DWORD)id /*&& wndclass->hInstance == hInstance*/) {
210 leaveMutex(OBJTYPE_CLASS);
211 return(wndclass);
212 }
213 else {
214 wndclass = (Win32WndClass *)wndclass->GetNext();
215 while(wndclass != NULL) {
216 if(wndclass->classAtom == (DWORD)id /* && wndclass->hInstance == hInstance*/) {
217 leaveMutex(OBJTYPE_CLASS);
218 return(wndclass);
219 }
220 wndclass = (Win32WndClass *)wndclass->GetNext();
221 }
222 }
223 }
224 leaveMutex(OBJTYPE_CLASS);
225 dprintf(("Class %X (inst %X) not found!", id, hInstance));
226 return(NULL);
227}
228//******************************************************************************
229//An app can only access another process' class if it's global
230//(all system classes are global)
231//NOTE: NOT USED NOW
232//******************************************************************************
233BOOL Win32WndClass::isAppClass(ULONG curProcessId)
234{
235 if(windowStyle & CS_GLOBALCLASS)
236 return TRUE;
237
238 return curProcessId = processId;
239}
240//******************************************************************************
241//******************************************************************************
242BOOL Win32WndClass::getClassInfo(WNDCLASSEXA *wndclass)
243{
244 wndclass->cbClsExtra = nrExtraClassWords;
245 wndclass->cbWndExtra = nrExtraWindowWords;
246 wndclass->hbrBackground = backgroundBrush;
247 wndclass->hCursor = hCursor;
248 wndclass->hIcon = hIcon;
249 wndclass->hInstance = hInstance;
250 wndclass->lpszMenuName = (LPCTSTR)menuNameA;
251 wndclass->lpszClassName = (classNameA) ? (LPCTSTR)classNameA : (LPCTSTR)classAtom;
252 wndclass->style = windowStyle;
253 wndclass->lpfnWndProc = windowProc;
254 wndclass->hIconSm = hIconSm;
255 return(TRUE);
256}
257//******************************************************************************
258//******************************************************************************
259BOOL Win32WndClass::getClassInfo(WNDCLASSEXW *wndclass)
260{
261 wndclass->cbClsExtra = nrExtraClassWords;
262 wndclass->cbWndExtra = nrExtraWindowWords;
263 wndclass->hbrBackground = backgroundBrush;
264 wndclass->hCursor = hCursor;
265 wndclass->hIcon = hIcon;
266 wndclass->hInstance = hInstance;
267 wndclass->lpszMenuName = (LPCWSTR)menuNameW;
268 wndclass->lpszClassName = (classNameW) ? (LPCWSTR)classNameW : (LPCWSTR)classAtom;
269 wndclass->style = windowStyle;
270 wndclass->lpfnWndProc = windowProc;
271 wndclass->hIconSm = hIconSm;
272 return(TRUE);
273}
274//******************************************************************************
275//******************************************************************************
276ULONG Win32WndClass::getClassName(LPSTR lpszClassName, ULONG cchClassName)
277{
278 if(HIWORD(classNameA)) {
279 strncpy(lpszClassName, classNameA, cchClassName-1);
280 return strlen(lpszClassName);
281 }
282 *(ULONG *)lpszClassName = classAtom;
283 return(sizeof(ULONG));
284}
285//******************************************************************************
286//******************************************************************************
287ULONG Win32WndClass::getClassName(LPWSTR lpszClassName, ULONG cchClassName)
288{
289 ULONG len;
290
291 if(HIWORD(classNameW)) {
292 lstrcpyW(lpszClassName, classNameW);
293 return lstrlenW(lpszClassName)*sizeof(WCHAR);
294 }
295 *(ULONG *)lpszClassName = classAtom;
296 return(sizeof(ULONG));
297}
298//******************************************************************************
299//******************************************************************************
300void Win32WndClass::setMenuName(LPSTR newMenuName)
301{
302 if(HIWORD(menuNameA)) {
303 free(menuNameA);
304 free(menuNameW);
305 menuNameA = 0;
306 menuNameW = 0;
307 }
308 if(HIWORD(newMenuName)) {
309 if(isUnicode) {
310 menuNameA = (PCHAR)_smalloc(lstrlenW((LPWSTR)newMenuName)+1);
311 menuNameW = (WCHAR *)_smalloc((lstrlenW((LPWSTR)newMenuName)+1)*sizeof(WCHAR));
312 }
313 else {
314 menuNameA = (PCHAR)_smalloc(strlen(newMenuName)+1);
315 menuNameW = (WCHAR *)_smalloc((strlen(newMenuName)+1)*sizeof(WCHAR));
316 }
317 if(menuNameA == NULL || menuNameW == NULL) {
318 dprintf(("Win32Class ctr; menuName/menuNameW == NULL"));
319 exit(1);
320 }
321 if(isUnicode) {
322 lstrcpyW(menuNameW, (LPWSTR)newMenuName);
323 UnicodeToAscii(menuNameW, menuNameA);
324 }
325 else {
326 strcpy((char *)menuNameA, newMenuName);
327 AsciiToUnicode(menuNameA, menuNameW);
328 }
329 }
330 else {//id
331 menuNameA = (PCHAR)newMenuName;
332 menuNameW = (WCHAR *)newMenuName;
333 }
334}
335//******************************************************************************
336//******************************************************************************
337ULONG Win32WndClass::getClassLongA(int index, BOOL isUnicode)
338{
339 switch(index) {
340 case GCL_CBCLSEXTRA:
341 return nrExtraClassWords;
342 case GCL_CBWNDEXTRA:
343 return nrExtraWindowWords;
344 case GCL_HBRBACKGROUND:
345 return backgroundBrush;
346 case GCL_HCURSOR:
347 return hCursor;
348 case GCL_HICON:
349 return hIcon;
350 case GCL_HMODULE:
351 return hInstance;
352 case GCL_MENUNAME:
353 return (isUnicode) ? (ULONG)menuNameW : (ULONG)menuNameA;
354 case GCL_STYLE:
355 return windowStyle;
356 case GCL_WNDPROC:
357 return (ULONG)windowProc;
358 case GCW_ATOM: //TODO: does this really happen in windows?
359 SetLastError(ERROR_INVALID_PARAMETER);
360 return 0;
361 default:
362 if(index > 0 && index < nrExtraClassWords - sizeof(ULONG)) {
363 return userClassLong[index];
364 }
365 SetLastError(ERROR_INVALID_PARAMETER);
366 return 0;
367 }
368}
369//******************************************************************************
370//******************************************************************************
371WORD Win32WndClass::getClassWord(int index)
372{
373 switch(index) {
374 case GCW_ATOM:
375 return (WORD)classAtom;
376 default:
377 if(index > 0 && index < nrExtraClassWords - sizeof(WORD)) {
378 return ((WORD *)userClassLong)[index];
379 }
380 SetLastError(ERROR_INVALID_PARAMETER);
381 return 0;
382 }
383}
384//******************************************************************************
385//TODO: What effects what immediately?
386//******************************************************************************
387ULONG Win32WndClass::setClassLongA(int index, LONG lNewVal, BOOL isUnicode)
388{
389 ULONG rc;
390
391 switch(index) {
392 case GCL_CBCLSEXTRA: //TODO (doesn't affect allocated classes, so what does it do?)
393 rc = nrExtraClassWords;
394// nrExtraClassWords = lNewVal;
395 break;
396 case GCL_CBWNDEXTRA:
397 rc = nrExtraWindowWords;
398 nrExtraWindowWords = lNewVal;
399 break;
400 case GCL_HBRBACKGROUND:
401 rc = backgroundBrush;
402 backgroundBrush = lNewVal;
403 break;
404 case GCL_HCURSOR:
405 rc = hCursor;
406 hCursor = lNewVal;
407 break;
408 case GCL_HICON:
409 rc = hIcon;
410 hIcon = lNewVal;
411 break;
412 case GCL_HMODULE:
413 rc = hInstance;
414 hInstance = lNewVal;
415 break;
416 case GCL_MENUNAME:
417 rc = 0; //old value is meaningless (according to Wine)
418 setMenuName((LPSTR)lNewVal);
419 break;
420 case GCL_STYLE:
421 rc = windowStyle;
422 windowStyle = lNewVal;
423 break;
424 case GCL_WNDPROC:
425 rc = (ULONG)windowProc;
426 windowProc = (WNDPROC)lNewVal;
427 break;
428 case GCW_ATOM: //TODO: does this really happen in windows?
429 SetLastError(ERROR_INVALID_PARAMETER);
430 return 0;
431 default:
432 if(index > 0 && index < nrExtraClassWords - sizeof(ULONG)) {
433 rc = userClassLong[index];
434 userClassLong[index] = lNewVal;
435 return(rc);
436 }
437 SetLastError(ERROR_INVALID_PARAMETER);
438 return 0;
439 }
440 return(rc);
441}
442//******************************************************************************
443//******************************************************************************
444WORD Win32WndClass::setClassWord(int index, WORD wNewVal)
445{
446 WORD rc;
447
448 switch(index) {
449 case GCW_ATOM:
450 rc = (WORD)classAtom;
451 classAtom = wNewVal;
452 return(rc);
453 default:
454 if(index > 0 && index < nrExtraClassWords - sizeof(WORD)) {
455 rc = ((WORD *)userClassLong)[index];
456 ((WORD *)userClassLong)[index] = wNewVal;
457 return(rc);
458 }
459 SetLastError(ERROR_INVALID_PARAMETER);
460 return 0;
461 }
462}
463//******************************************************************************
464//FIXME: Windows that still exists with this class
465//******************************************************************************
466void Win32WndClass::UnregisterClassA(HINSTANCE hinst, LPSTR id)
467{
468 Win32WndClass *wndclass;
469
470 wndclass = FindClass(hinst, id);
471 if(wndclass) {
472 delete wndclass;
473 return;
474 }
475 dprintf(("::UnregisterClass, couldn't find class %X!!\n", id));
476}
477//******************************************************************************
478//******************************************************************************
479GenericObject *Win32WndClass::wndclasses = NULL;
Note: See TracBrowser for help on using the repository browser.