source: trunk/src/user32/new/win32class.cpp@ 655

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

One mutex per object type + mutex protection in win32 class

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