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

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

class lookup fix

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