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

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

Use shared memory for class & window objects

File size: 15.2 KB
Line 
1/* $Id: win32class.cpp,v 1.8 1999-08-28 14:09: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)_smalloc(len);
31 classNameW = (WCHAR *)_smalloc(len*sizeof(WCHAR));
32 }
33 else {
34 INT len = strlen(wndclass->lpszClassName)+1;
35
36 classNameA = (PCHAR)_smalloc(len);
37 classNameW = (WCHAR *)_smalloc(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 *)_smalloc(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//******************************************************************************
120BOOL Win32WndClass::hasClassName(LPSTR classname, BOOL fUnicode)
121{
122 if(HIWORD(classname) == 0) {
123 return classAtom == (DWORD)classname;
124 }
125 if(fUnicode) {
126 return (lstrcmpW(classNameW, (LPWSTR)classname) == 0);
127 }
128 else return (strcmp(classNameA, classname) == 0);
129}
130//******************************************************************************
131//******************************************************************************
132Win32WndClass *Win32WndClass::FindClass(HINSTANCE hInstance, LPSTR id)
133{
134 enterMutex(OBJTYPE_CLASS);
135
136 Win32WndClass *wndclass = (Win32WndClass *)wndclasses;
137
138 if(wndclass == NULL) {
139 leaveMutex(OBJTYPE_CLASS);
140 return(NULL);
141 }
142
143 if(HIWORD(id) != 0) {
144//CB: read comment below!
145 if(stricmp(wndclass->classNameA, id) == 0 && wndclass->hInstance == hInstance) {
146 leaveMutex(OBJTYPE_CLASS);
147 return(wndclass);
148 }
149 else {
150 wndclass = (Win32WndClass *)wndclass->GetNext();
151 while(wndclass != NULL) {
152 if(stricmp(wndclass->classNameA, id) == 0 && wndclass->hInstance == hInstance) {
153 leaveMutex(OBJTYPE_CLASS);
154 return(wndclass);
155 }
156 wndclass = (Win32WndClass *)wndclass->GetNext();
157 }
158 }
159 }
160 else {
161//CB: without HInstance check, test program finds class
162//CB: need more code to compare instance; convert 0 to exe module handle
163 if(wndclass->classAtom == (DWORD)id /*&& wndclass->hInstance == hInstance*/) {
164 leaveMutex(OBJTYPE_CLASS);
165 return(wndclass);
166 }
167 else {
168 wndclass = (Win32WndClass *)wndclass->GetNext();
169 while(wndclass != NULL) {
170 if(wndclass->classAtom == (DWORD)id/* && wndclass->hInstance == hInstance*/) {
171 leaveMutex(OBJTYPE_CLASS);
172 return(wndclass);
173 }
174 wndclass = (Win32WndClass *)wndclass->GetNext();
175 }
176 }
177 }
178 leaveMutex(OBJTYPE_CLASS);
179 dprintf(("Class %X (inst %X) not found!", id, hInstance));
180 return(NULL);
181}
182//******************************************************************************
183//******************************************************************************
184BOOL Win32WndClass::getClassInfo(WNDCLASSEXA *wndclass)
185{
186 wndclass->cbClsExtra = nrExtraClassWords;
187 wndclass->cbWndExtra = nrExtraWindowWords;
188 wndclass->hbrBackground = backgroundBrush;
189 wndclass->hCursor = hCursor;
190 wndclass->hIcon = hIcon;
191 wndclass->hInstance = hInstance;
192 wndclass->lpszMenuName = (LPCTSTR)menuNameA;
193 wndclass->lpszClassName = (classNameA) ? (LPCTSTR)classNameA : (LPCTSTR)classAtom;
194 wndclass->style = windowStyle;
195 wndclass->lpfnWndProc = windowProc;
196 wndclass->hIconSm = hIconSm;
197 return(TRUE);
198}
199//******************************************************************************
200//******************************************************************************
201BOOL Win32WndClass::getClassInfo(WNDCLASSEXW *wndclass)
202{
203 wndclass->cbClsExtra = nrExtraClassWords;
204 wndclass->cbWndExtra = nrExtraWindowWords;
205 wndclass->hbrBackground = backgroundBrush;
206 wndclass->hCursor = hCursor;
207 wndclass->hIcon = hIcon;
208 wndclass->hInstance = hInstance;
209 wndclass->lpszMenuName = (LPCWSTR)menuNameW;
210 wndclass->lpszClassName = (classNameW) ? (LPCWSTR)classNameW : (LPCWSTR)classAtom;
211 wndclass->style = windowStyle;
212 wndclass->lpfnWndProc = windowProc;
213 wndclass->hIconSm = hIconSm;
214 return(TRUE);
215}
216//******************************************************************************
217//******************************************************************************
218ULONG Win32WndClass::getClassName(LPSTR lpszClassName, ULONG cchClassName)
219{
220 if(HIWORD(classNameA)) {
221 strncpy(lpszClassName, classNameA, cchClassName-1);
222 return strlen(lpszClassName);
223 }
224 *(ULONG *)lpszClassName = classAtom;
225 return(sizeof(ULONG));
226}
227//******************************************************************************
228//******************************************************************************
229ULONG Win32WndClass::getClassName(LPWSTR lpszClassName, ULONG cchClassName)
230{
231 ULONG len;
232
233 if(HIWORD(classNameW)) {
234 lstrcpyW(lpszClassName, classNameW);
235 return lstrlenW(lpszClassName)*sizeof(WCHAR);
236 }
237 *(ULONG *)lpszClassName = classAtom;
238 return(sizeof(ULONG));
239}
240//******************************************************************************
241//******************************************************************************
242void Win32WndClass::setMenuName(LPSTR newMenuName)
243{
244 if(HIWORD(menuNameA)) {
245 free(menuNameA);
246 free(menuNameW);
247 menuNameA = 0;
248 menuNameW = 0;
249 }
250 if(HIWORD(newMenuName)) {
251 if(isUnicode) {
252 menuNameA = (PCHAR)_smalloc(lstrlenW((LPWSTR)newMenuName)+1);
253 menuNameW = (WCHAR *)_smalloc((lstrlenW((LPWSTR)newMenuName)+1)*sizeof(WCHAR));
254 }
255 else {
256 menuNameA = (PCHAR)_smalloc(strlen(newMenuName)+1);
257 menuNameW = (WCHAR *)_smalloc((strlen(newMenuName)+1)*sizeof(WCHAR));
258 }
259 if(menuNameA == NULL || menuNameW == NULL) {
260 dprintf(("Win32Class ctr; menuName/menuNameW == NULL"));
261 exit(1);
262 }
263 if(isUnicode) {
264 lstrcpyW(menuNameW, (LPWSTR)newMenuName);
265 UnicodeToAscii(menuNameW, menuNameA);
266 }
267 else {
268 strcpy((char *)menuNameA, newMenuName);
269 AsciiToUnicode(menuNameA, menuNameW);
270 }
271 }
272 else {//id
273 menuNameA = (PCHAR)newMenuName;
274 menuNameW = (WCHAR *)newMenuName;
275 }
276}
277//******************************************************************************
278//******************************************************************************
279ULONG Win32WndClass::getClassLongA(int index, BOOL isUnicode)
280{
281 switch(index) {
282 case GCL_CBCLSEXTRA:
283 return nrExtraClassWords;
284 case GCL_CBWNDEXTRA:
285 return nrExtraWindowWords;
286 case GCL_HBRBACKGROUND:
287 return backgroundBrush;
288 case GCL_HCURSOR:
289 return hCursor;
290 case GCL_HICON:
291 return hIcon;
292 case GCL_HMODULE:
293 return hInstance;
294 case GCL_MENUNAME:
295 return (isUnicode) ? (ULONG)menuNameW : (ULONG)menuNameA;
296 case GCL_STYLE:
297 return windowStyle;
298 case GCL_WNDPROC:
299 return (ULONG)windowProc;
300 case GCW_ATOM: //TODO: does this really happen in windows?
301 SetLastError(ERROR_INVALID_PARAMETER);
302 return 0;
303 default:
304 if(index > 0 && index < nrExtraClassWords - sizeof(ULONG)) {
305 return userClassLong[index];
306 }
307 SetLastError(ERROR_INVALID_PARAMETER);
308 return 0;
309 }
310}
311//******************************************************************************
312//******************************************************************************
313WORD Win32WndClass::getClassWord(int index)
314{
315 switch(index) {
316 case GCW_ATOM:
317 return (WORD)classAtom;
318 default:
319 if(index > 0 && index < nrExtraClassWords - sizeof(WORD)) {
320 return ((WORD *)userClassLong)[index];
321 }
322 SetLastError(ERROR_INVALID_PARAMETER);
323 return 0;
324 }
325}
326//******************************************************************************
327//TODO: What effects what immediately?
328//******************************************************************************
329ULONG Win32WndClass::setClassLongA(int index, LONG lNewVal, BOOL isUnicode)
330{
331 ULONG rc;
332
333 switch(index) {
334 case GCL_CBCLSEXTRA: //TODO (doesn't affect allocated classes, so what does it do?)
335 rc = nrExtraClassWords;
336// nrExtraClassWords = lNewVal;
337 break;
338 case GCL_CBWNDEXTRA:
339 rc = nrExtraWindowWords;
340 nrExtraWindowWords = lNewVal;
341 break;
342 case GCL_HBRBACKGROUND:
343 rc = backgroundBrush;
344 backgroundBrush = lNewVal;
345 break;
346 case GCL_HCURSOR:
347 rc = hCursor;
348 hCursor = lNewVal;
349 break;
350 case GCL_HICON:
351 rc = hIcon;
352 hIcon = lNewVal;
353 break;
354 case GCL_HMODULE:
355 rc = hInstance;
356 hInstance = lNewVal;
357 break;
358 case GCL_MENUNAME:
359 rc = 0; //old value is meaningless (according to Wine)
360 setMenuName((LPSTR)lNewVal);
361 break;
362 case GCL_STYLE:
363 rc = windowStyle;
364 windowStyle = lNewVal;
365 break;
366 case GCL_WNDPROC:
367 rc = (ULONG)windowProc;
368 windowProc = (WNDPROC)lNewVal;
369 break;
370 case GCW_ATOM: //TODO: does this really happen in windows?
371 SetLastError(ERROR_INVALID_PARAMETER);
372 return 0;
373 default:
374 if(index > 0 && index < nrExtraClassWords - sizeof(ULONG)) {
375 rc = userClassLong[index];
376 userClassLong[index] = lNewVal;
377 return(rc);
378 }
379 SetLastError(ERROR_INVALID_PARAMETER);
380 return 0;
381 }
382 return(rc);
383}
384//******************************************************************************
385//******************************************************************************
386WORD Win32WndClass::setClassWord(int index, WORD wNewVal)
387{
388 WORD rc;
389
390 switch(index) {
391 case GCW_ATOM:
392 rc = (WORD)classAtom;
393 classAtom = wNewVal;
394 return(rc);
395 default:
396 if(index > 0 && index < nrExtraClassWords - sizeof(WORD)) {
397 rc = ((WORD *)userClassLong)[index];
398 ((WORD *)userClassLong)[index] = wNewVal;
399 return(rc);
400 }
401 SetLastError(ERROR_INVALID_PARAMETER);
402 return 0;
403 }
404}
405//******************************************************************************
406//FIXME: Windows that still exists with this class
407//******************************************************************************
408void Win32WndClass::UnregisterClassA(HINSTANCE hinst, LPSTR id)
409{
410 Win32WndClass *wndclass;
411
412 dprintf(("::UnregisterClass, destroy class %X!!\n", id));
413 wndclass = FindClass(hinst, id);
414 if(wndclass) {
415 delete wndclass;
416 return;
417 }
418 dprintf(("::UnregisterClass, couldn't find class %X!!\n", id));
419}
420//******************************************************************************
421//******************************************************************************
422GenericObject *Win32WndClass::wndclasses = NULL;
423
Note: See TracBrowser for help on using the repository browser.