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

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

class changes

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