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

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

DC changes + commented out shell position update

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