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

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

misc changes

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