source: trunk/src/user32/wndclass.cpp@ 223

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

FS changes for msg callbacks & OS2/Open32 apis

File size: 34.4 KB
Line 
1/* $Id: wndclass.cpp,v 1.13 1999-06-26 18:25:08 sandervl Exp $ */
2
3/*
4 * Win32 Window Class Managment Code for OS/2
5 *
6 * 18-07-1998 SvL: Merged all class code into this file + bug fixes
7 * Register all system classes at dll init
8 * Rewrote incorrect callback code
9 *
10 * Copyright 1998 Sander van Leeuwen (sandervl@xs4all.nl)
11 *
12 *
13 * Project Odin Software License can be found in LICENSE.TXT
14 *
15 */
16#include <os2win.h>
17#include <stdarg.h>
18#include <stdio.h>
19#include <string.h>
20#include <stdlib.h>
21#include <assert.h>
22#include <misc.h>
23#include <wndproc.h>
24#include <wndclass.h>
25#include <nameid.h>
26#include <spy.h>
27#include <wprocess.h>
28#include "hooks.h"
29
30//default window handlers that are registered by RegisterClass are called
31//in this callback handler
32LRESULT EXPENTRY_O32 OS2ToWinCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
33//default window handlers that are queried by GetClassInfo/GetClassLong is really
34//this callback handler
35LRESULT WIN32API WinToOS2Callback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam);
36
37#ifdef DEBUG
38char *GetMsgText(int Msg);
39#endif
40
41DWORD MapOEMToRealKey(DWORD wParam, DWORD lParam);
42
43WNDPROC_O32 ButtonHandler = 0;
44WNDPROC_O32 ListboxHandler = 0;
45WNDPROC_O32 ComboboxHandler = 0;
46WNDPROC_O32 EditHandler = 0;
47WNDPROC_O32 MdiClientHandler = 0;
48WNDPROC_O32 ScrollbarHandler = 0;
49WNDPROC_O32 StaticHandler = 0;
50
51HWND hwndButton = 0;
52HWND hwndListbox = 0;
53HWND hwndEdit = 0;
54HWND hwndCombobox = 0;
55HWND hwndScrollbar = 0;
56HWND hwndMdiClient = 0;
57HWND hwndStatic = 0;
58
59Win32WindowClass *ButtonClass = 0;
60Win32WindowClass *ListboxClass = 0;
61Win32WindowClass *EditClass = 0;
62Win32WindowClass *ComboboxClass = 0;
63Win32WindowClass *MdiClientClass = 0;
64Win32WindowClass *ScrollbarClass = 0;
65Win32WindowClass *StaticClass = 0;
66//******************************************************************************
67//******************************************************************************
68LRESULT WIN32API ButtonCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
69{
70 DWORD dwStyle, dwExStyle;
71 LRESULT rc;
72
73 //Restore our FS selector
74 SetWin32TIB();
75
76 PostSpyMessage(hwnd, Msg, wParam, lParam);
77 switch(Msg)
78 {
79 case WM_LBUTTONDOWN:
80 rc = ButtonHandler(hwnd, Msg, wParam, lParam);
81 //Restore our FS selector
82 SetWin32TIB();
83
84 NotifyParent(hwnd, Msg, wParam, lParam);
85 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
86 dwExStyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
87
88 if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
89 {
90 HWND hwndParent = GetParent(hwnd);
91
92 //TODO: Mouse shouldn't be captured
93 Win32WindowProc *parentwnd = Win32WindowProc::FindProc(hwndParent);
94 if(parentwnd) {
95 //TODO: HTCLIENT isn't always accurate
96 parentwnd->SendMessageA(hwndParent, WM_SETCURSOR, hwnd, HTCLIENT | (WM_LBUTTONDOWN << 16));
97 }
98 }
99 return rc;
100
101 case WM_CREATE:
102 case WM_MBUTTONDOWN:
103 case WM_RBUTTONDOWN:
104 rc = ButtonHandler(hwnd, Msg, wParam, lParam);
105 //Restore our FS selector
106 SetWin32TIB();
107 NotifyParent(hwnd, Msg, wParam, lParam);
108 RestoreOS2TIB();
109 return rc;
110
111 case WM_DESTROY:
112 NotifyParent(hwnd, Msg, wParam, lParam);
113 break;
114 }
115 rc = ButtonHandler(hwnd, Msg, wParam, lParam);
116 RestoreOS2TIB();
117 return rc;
118}
119//******************************************************************************
120//******************************************************************************
121LRESULT WIN32API ListboxCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
122{
123 PostSpyMessage(hwnd, Msg, wParam, lParam);
124 return ListboxHandler(hwnd, Msg, wParam, lParam);
125}
126//******************************************************************************
127//******************************************************************************
128LRESULT WIN32API ComboboxCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
129{
130 PostSpyMessage(hwnd, Msg, wParam, lParam);
131 return ComboboxHandler(hwnd, Msg, wParam, lParam);
132}
133//******************************************************************************
134//******************************************************************************
135LRESULT WIN32API MdiClientCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
136{
137 PostSpyMessage(hwnd, Msg, wParam, lParam);
138 return MdiClientHandler(hwnd, Msg, wParam, lParam);
139}
140//******************************************************************************
141//******************************************************************************
142LRESULT WIN32API EditCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
143{
144 PostSpyMessage(hwnd, Msg, wParam, lParam);
145 return EditHandler(hwnd, Msg, wParam, lParam);
146}
147//******************************************************************************
148//******************************************************************************
149LRESULT WIN32API ScrollbarCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
150{
151 PostSpyMessage(hwnd, Msg, wParam, lParam);
152 return ScrollbarHandler(hwnd, Msg, wParam, lParam);
153}
154//******************************************************************************
155//******************************************************************************
156LRESULT WIN32API StaticCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
157{
158 PostSpyMessage(hwnd, Msg, wParam, lParam);
159 return StaticHandler(hwnd, Msg, wParam, lParam);
160}
161//******************************************************************************
162//SvL: 18-7-'98, Registers system window classes (button, listbox etc etc)
163//******************************************************************************
164void RegisterSystemClasses(ULONG hModule)
165{
166 WNDCLASSA wndclass;
167 HWND hwnd;
168
169 if(O32_GetClassInfo(NULL, "BUTTON", &wndclass)) {
170 dprintf(("Create BUTTON System class"));
171 ButtonClass = new Win32WindowClass(ButtonCallback, "BUTTON", hModule);
172 ButtonHandler = (WNDPROC_O32)wndclass.lpfnWndProc;
173 hwndButton = O32_CreateWindow("BUTTON", "BUTTON", 0, 0, 0, 0, 0, 0, 0, 0, 0);
174 if(hwndButton == 0) {
175 dprintf(("RegisterSystemClasses failed!!"));
176 }
177 O32_SetClassLong(hwndButton, GCL_WNDPROC, (LONG)ButtonCallback);
178 }
179 if(O32_GetClassInfo(NULL, "LISTBOX", &wndclass)) {
180 dprintf(("Create LISTBOX System class"));
181 ListboxClass = new Win32WindowClass(ListboxCallback, "LISTBOX", hModule);
182 ListboxHandler = (WNDPROC_O32)wndclass.lpfnWndProc;
183 hwndListbox = O32_CreateWindow("LISTBOX", "LISTBOX", 0, 0, 0, 0, 0, 0, 0, 0, 0);
184 if(hwndListbox == 0) {
185 dprintf(("RegisterSystemClasses failed!!"));
186 }
187 O32_SetClassLong(hwndListbox, GCL_WNDPROC, (LONG)ListboxCallback);
188 }
189 if(O32_GetClassInfo(NULL, "COMBOBOX", &wndclass)) {
190 dprintf(("Create COMBOBOX System class"));
191 ComboboxClass = new Win32WindowClass(ComboboxCallback, "COMBOBOX", hModule);
192 ComboboxHandler = (WNDPROC_O32)wndclass.lpfnWndProc;
193 hwndCombobox = O32_CreateWindow("COMBOBOX", "COMBOBOX", 0, 0, 0, 0, 0, 0, 0, 0, 0);
194 if(hwndCombobox == 0) {
195 dprintf(("RegisterSystemClasses failed!!"));
196 }
197 O32_SetClassLong(hwndCombobox, GCL_WNDPROC, (LONG)ComboboxCallback);
198 }
199 if(O32_GetClassInfo(NULL, "EDIT", &wndclass)) {
200 dprintf(("Create EDIT System class"));
201 EditClass = new Win32WindowClass(EditCallback, "EDIT", hModule);
202 EditHandler = (WNDPROC_O32)wndclass.lpfnWndProc;
203 hwndEdit = O32_CreateWindow("EDIT", "EDIT", 0, 0, 0, 0, 0, 0, 0, 0, 0);
204 if(hwndEdit == 0) {
205 dprintf(("RegisterSystemClasses failed!!"));
206 }
207 O32_SetClassLong(hwndEdit, GCL_WNDPROC, (LONG)EditCallback);
208 }
209 //TODO: This doens't work yet!! (need to create a normal window as parent)
210 if(O32_GetClassInfo(NULL, "MDICLIENT", &wndclass)) {
211 dprintf(("Create MDICLIENT System class"));
212 MdiClientClass = new Win32WindowClass(MdiClientCallback, "MDICLIENT", hModule);
213 MdiClientHandler = (WNDPROC_O32)wndclass.lpfnWndProc;
214 hwndMdiClient = O32_CreateWindow("MDICLIENT", "MDICLIENT", WS_CHILD, 0, 0, 0, 0, hwndListbox, 0, 0, 0);
215 if(hwndMdiClient == 0) {
216 dprintf(("RegisterSystemClasses failed!!"));
217 }
218 O32_SetClassLong(hwndMdiClient, GCL_WNDPROC, (LONG)MdiClientCallback);
219 }
220 if(O32_GetClassInfo(NULL, "SCROLLBAR", &wndclass)) {
221 dprintf(("Create SCROLLBAR System class"));
222 ScrollbarClass = new Win32WindowClass(ScrollbarCallback, "SCROLLBAR", hModule);
223 ScrollbarHandler = (WNDPROC_O32)wndclass.lpfnWndProc;
224 hwndScrollbar = O32_CreateWindow("SCROLLBAR", "SCROLLBAR", 0, 0, 0, 0, 0, 0, 0, 0, 0);
225 if(hwndScrollbar == 0) {
226 dprintf(("RegisterSystemClasses failed!!"));
227 }
228 O32_SetClassLong(hwndScrollbar, GCL_WNDPROC, (LONG)ScrollbarCallback);
229 }
230 if(O32_GetClassInfo(NULL, "STATIC", &wndclass)) {
231 dprintf(("Create STATIC System class"));
232 StaticClass = new Win32WindowClass(StaticCallback, "STATIC", hModule);
233 StaticHandler = (WNDPROC_O32)wndclass.lpfnWndProc;
234 hwndStatic = O32_CreateWindow("STATIC", "STATIC", 0, 0, 0, 0, 0, 0, 0, 0, 0);
235 if(hwndStatic == 0) {
236 dprintf(("RegisterSystemClasses failed!!"));
237 }
238 O32_SetClassLong(hwndStatic, GCL_WNDPROC, (LONG)StaticCallback);
239 }
240//TODO: More standard classes in win95/NT4?
241}
242//******************************************************************************
243//******************************************************************************
244void UnregisterSystemClasses()
245{
246 dprintf(("KERNEL32: UnregisterSystemClasses"));
247 if(hwndButton) O32_DestroyWindow(hwndButton);
248 if(hwndListbox) O32_DestroyWindow(hwndListbox);
249 if(hwndCombobox) O32_DestroyWindow(hwndCombobox);
250 if(hwndMdiClient) O32_DestroyWindow(hwndMdiClient);
251 if(hwndEdit) O32_DestroyWindow(hwndEdit);
252 if(hwndScrollbar) O32_DestroyWindow(hwndScrollbar);
253 if(hwndStatic) O32_DestroyWindow(hwndStatic);
254 if(ButtonClass) delete ButtonClass;
255 if(ListboxClass) delete ListboxClass;
256 if(EditClass) delete EditClass;
257 if(ComboboxClass) delete ComboboxClass;
258 if(MdiClientClass) delete MdiClientClass;
259 if(ScrollbarClass) delete ScrollbarClass;
260 if(StaticClass) delete StaticClass;
261 ButtonClass = NULL;
262 EditClass = NULL;
263 ListboxClass = NULL;
264 ComboboxClass = NULL;
265 MdiClientClass = NULL;
266 ScrollbarClass = NULL;
267 StaticClass = NULL;
268}
269//******************************************************************************
270//SvL: 18-7-'98: Moved here from user32.cpp
271//******************************************************************************
272ATOM WIN32API RegisterClassA(const WNDCLASSA *lpWndClass)
273{
274 ATOM rc;
275 WNDCLASSA wc;
276
277#ifdef DEBUG
278 WriteLog("USER32: RegisterClassA\n");
279 WriteLog("USER32: lpWndClass->style %X\n", lpWndClass->style);
280 WriteLog("USER32: lpWndClass->lpfnWndProc %X\n", lpWndClass->lpfnWndProc);
281 WriteLog("USER32: lpWndClass->cbClsExtra %X\n", lpWndClass->cbClsExtra);
282 WriteLog("USER32: lpWndClass->cbWndExtra %X\n", lpWndClass->cbWndExtra);
283 WriteLog("USER32: lpWndClass->hInstance %X\n", lpWndClass->hInstance);
284 WriteLog("USER32: lpWndClass->hIcon %X\n", lpWndClass->hIcon);
285 WriteLog("USER32: lpWndClass->hCursor %X\n", lpWndClass->hCursor);
286 WriteLog("USER32: lpWndClass->hbrBackground %X\n", lpWndClass->hbrBackground);
287 WriteLog("USER32: lpWndClass->lpszMenuName %X\n", lpWndClass->lpszMenuName);
288 if((int)lpWndClass->lpszClassName >> 16 == 0)
289 WriteLog("USER32: lpWndClass->lpszClassName %X\n", lpWndClass->lpszClassName);
290 else WriteLog("USER32: lpWndClass->lpszClassName %s\n", lpWndClass->lpszClassName);
291#endif
292 memcpy(&wc, lpWndClass, sizeof(WNDCLASSA));
293
294 if((int)wc.lpszMenuName >> 16 != 0) {//convert string name identifier to numeric id
295 dprintf(("USER32: lpszMenuName %s\n", wc.lpszMenuName));
296 *(int *)&wc.lpszMenuName = ConvertNameId(0, (char *)wc.lpszMenuName);
297 dprintf(("USER32: Menu id = %d\n", (int)wc.lpszMenuName));
298 }
299#ifdef DEBUG
300 if(wc.style & (CS_PARENTDC | CS_CLASSDC)) {
301 dprintf(("USER32: Class uses an unsupported style!!!\n"));
302 }
303#endif
304 //These are not supported by Open32
305 wc.style &= ~(CS_PARENTDC | CS_CLASSDC);
306
307 wc.lpfnWndProc = (WNDPROC)Win32WindowClass::GetOS2ClassCallback();
308 rc = O32_RegisterClass(&wc);
309 if(rc) {
310 Win32WindowClass *wndclass = new Win32WindowClass((WNDPROC)lpWndClass->lpfnWndProc, (LPSTR)wc.lpszClassName, wc.hInstance);
311 }
312 dprintf(("USER32: RegisterClass returned %d (%d)\n", rc, GetLastError()));
313 return(rc);
314}
315//******************************************************************************
316//SvL: 18-7-'98: Moved here from user32.cpp
317//******************************************************************************
318ATOM WIN32API RegisterClassExA(const WNDCLASSEXA *lpWndClass)
319{
320 ATOM rc;
321 WNDCLASSEXA wc;
322
323#ifdef DEBUG
324 WriteLog("USER32: lpWndClass->cbSize %X\n", lpWndClass->cbSize);
325 WriteLog("USER32: lpWndClass->style %X\n", lpWndClass->style);
326 WriteLog("USER32: lpWndClass->lpfnWndProc %X\n", lpWndClass->lpfnWndProc);
327 WriteLog("USER32: lpWndClass->cbClsExtra %X\n", lpWndClass->cbClsExtra);
328 WriteLog("USER32: lpWndClass->cbWndExtra %X\n", lpWndClass->cbWndExtra);
329 WriteLog("USER32: lpWndClass->hInstance %X\n", lpWndClass->hInstance);
330 WriteLog("USER32: lpWndClass->hIcon %X\n", lpWndClass->hIcon);
331 WriteLog("USER32: lpWndClass->hCursor %X\n", lpWndClass->hCursor);
332 WriteLog("USER32: lpWndClass->hbrBackground %X\n", lpWndClass->hbrBackground);
333 WriteLog("USER32: lpWndClass->lpszMenuName %X\n", lpWndClass->lpszMenuName);
334 if((int)lpWndClass->lpszClassName >> 16 == 0)
335 WriteLog("USER32: lpWndClass->lpszClassName %X\n", lpWndClass->lpszClassName);
336 else WriteLog("USER32: lpWndClass->lpszClassName %s\n", lpWndClass->lpszClassName);
337#endif
338 memcpy(&wc, lpWndClass, sizeof(WNDCLASSEXA));
339
340 if((int)wc.lpszMenuName >> 16 != 0) {//convert string name identifier to numeric id
341 dprintf(("USER32: lpszMenuName %s\n", wc.lpszMenuName));
342 *(int *)&wc.lpszMenuName = ConvertNameId(0, (char *)wc.lpszMenuName);
343 dprintf(("USER32: Menu id = %d\n", (int)wc.lpszMenuName));
344 }
345 if(wc.cbSize != sizeof(WNDCLASSEXA))
346 return(0);
347
348#ifdef DEBUG
349 if(wc.style & (CS_PARENTDC | CS_CLASSDC)) {
350 dprintf(("USER32: Class uses an unsupported style!!!\n"));
351 }
352#endif
353 //These are not supported by Open32
354 wc.style &= ~(CS_PARENTDC | CS_CLASSDC);
355
356 wc.lpfnWndProc = (WNDPROC)Win32WindowClass::GetOS2ClassCallback();
357
358 rc = O32_RegisterClass((WNDCLASSA *)&wc.style);
359 if(rc) {
360 Win32WindowClass *wndclass = new Win32WindowClass((WNDPROC)lpWndClass->lpfnWndProc, (LPSTR)wc.lpszClassName, wc.hInstance);
361 }
362#ifdef DEBUG
363 WriteLog("USER32: RegisterClassExA, not completely supported, returned %d\n", rc);
364 if(rc == 0)
365 WriteLog("USER32: GetLastError returned %X\n", GetLastError());
366
367#endif
368 return(rc);
369}
370//******************************************************************************
371//******************************************************************************
372WORD WIN32API RegisterClassW(const WNDCLASSW *lpwc)
373{
374 ATOM rc;
375 WNDCLASSA wclass;
376
377 dprintf(("RegisterClassW\n"));
378 memcpy(&wclass, lpwc, sizeof(WNDCLASSA));
379 if(wclass.lpszMenuName && ((int)wclass.lpszMenuName >> 16 != 0)) {
380 wclass.lpszMenuName = UnicodeToAsciiString((LPWSTR)lpwc->lpszMenuName);
381 }
382 if(wclass.lpszClassName && ((int)wclass.lpszClassName >> 16 != 0)) {
383 wclass.lpszClassName = UnicodeToAsciiString((LPWSTR)lpwc->lpszClassName);
384 }
385
386 rc = RegisterClassA(&wclass);
387
388 //TODO: Assuming RegisterClass doesn't mess up our structure
389 if(lpwc->lpszMenuName && ((int)lpwc->lpszMenuName >> 16 != 0)) {
390 FreeAsciiString((char *)wclass.lpszMenuName);
391 }
392 if(lpwc->lpszClassName && ((int)lpwc->lpszClassName >> 16 != 0)) {
393 FreeAsciiString((char *)wclass.lpszClassName);
394 }
395 return(rc);
396}
397//******************************************************************************
398//******************************************************************************
399ATOM WIN32API RegisterClassExW(CONST WNDCLASSEXW *lpwc)
400{
401 ATOM rc;
402 WNDCLASSEXA wclass;
403
404 dprintf(("RegisterClassExW\n"));
405 memcpy(&wclass, lpwc, sizeof(WNDCLASSEXA));
406 if(wclass.lpszMenuName && ((int)wclass.lpszMenuName >> 16 != 0)) {
407 wclass.lpszMenuName = UnicodeToAsciiString((LPWSTR)lpwc->lpszMenuName);
408 }
409 if(wclass.lpszClassName && ((int)wclass.lpszClassName >> 16 != 0)) {
410 wclass.lpszClassName = UnicodeToAsciiString((LPWSTR)lpwc->lpszClassName);
411 }
412
413 rc = RegisterClassExA(&wclass);
414
415 //TODO: Assuming RegisterClassEx doesn't mess up our structure
416 if(lpwc->lpszMenuName && ((int)lpwc->lpszMenuName >> 16 != 0)) {
417 FreeAsciiString((char *)wclass.lpszMenuName);
418 }
419 if(lpwc->lpszClassName && ((int)lpwc->lpszClassName >> 16 != 0)) {
420 FreeAsciiString((char *)wclass.lpszClassName);
421 }
422 return(rc);
423}
424//******************************************************************************
425//******************************************************************************
426BOOL WIN32API UnregisterClassA(LPCSTR lpszClassName, HINSTANCE hinst)
427{
428 BOOL rc;
429
430 Win32WindowClass::UnregisterClass(hinst, (LPSTR)lpszClassName);
431 rc = O32_UnregisterClass(lpszClassName, hinst);
432 dprintf(("USER32: OS2UnregisterClassA returned %d\n", rc));
433
434 //Spintest returns FALSE in dll termination, so pretend it succeeded
435 return(TRUE);
436}
437//******************************************************************************
438//******************************************************************************
439BOOL WIN32API UnregisterClassW(LPCWSTR lpszClassName, HINSTANCE hinst)
440{
441 char *astring = NULL;
442 BOOL rc;
443
444 dprintf(("USER32: OS2UnregisterClassW\n"));
445 if((int)lpszClassName >> 16 != 0) {
446 astring = UnicodeToAsciiString((LPWSTR)lpszClassName);
447 }
448 else astring = (char *)lpszClassName;
449
450 Win32WindowClass::UnregisterClass(hinst, (LPSTR)astring);
451 rc = O32_UnregisterClass(astring, hinst);
452 if((int)astring >> 16 != 0) {
453 FreeAsciiString(astring);
454 }
455 //Spintest returns FALSE in dll termination, so pretend it succeeded
456 return(TRUE);
457}
458//******************************************************************************
459//******************************************************************************
460BOOL WIN32API GetClassInfoA(HINSTANCE arg1, LPCSTR arg2, WNDCLASSA * arg3)
461{
462 BOOL rc;
463
464 dprintf(("USER32: OS2GetClassInfoA\n"));
465 rc = O32_GetClassInfo(arg1, arg2, (WNDCLASSA *)arg3);
466 if(rc == TRUE) {
467 arg3->lpfnWndProc = (WNDPROC)Win32WindowClass::GetClassCallback((LPSTR)arg2);
468 }
469 return(rc);
470}
471//******************************************************************************
472//******************************************************************************
473BOOL WIN32API GetClassInfoW(HINSTANCE hinst,
474 LPCWSTR lpszClass,
475 WNDCLASSW *lpwc)
476{
477 WNDCLASSA wclass;
478 BOOL rc;
479 char *szClass = NULL;
480
481 dprintf(("USER32: OS2GetClassInfoW\n"));
482 if((int)lpszClass >> 16 != 0) {
483 szClass = UnicodeToAsciiString((LPWSTR)lpszClass);
484 dprintf(("USER32: OS2GetClassInfoW %s\n", szClass));
485 }
486 else szClass = (char *)lpszClass;
487
488 rc = GetClassInfoA(hinst, szClass, &wclass);
489 if(rc == TRUE) {
490 memcpy(lpwc, &wclass, sizeof(WNDCLASSA));
491 //TODO: Memory leak (create class object at RegisterClass and delete it at UnregisterClass)
492 if(lpwc->lpszMenuName && ((int)lpwc->lpszMenuName >> 16 != 0)) {
493 lpwc->lpszMenuName = (LPCWSTR)malloc(strlen(wclass.lpszMenuName)*sizeof(WCHAR)+2);
494 AsciiToUnicode((char *)wclass.lpszMenuName, (LPWSTR)lpwc->lpszMenuName);
495 }
496 if(lpwc->lpszClassName && ((int)lpwc->lpszClassName >> 16 != 0)) {
497 lpwc->lpszClassName = (LPCWSTR)malloc(strlen(wclass.lpszClassName)*sizeof(WCHAR)+2);
498 AsciiToUnicode((char *)wclass.lpszClassName, (LPWSTR)lpwc->lpszClassName);
499 }
500 }
501 dprintf(("USER32: OS2GetClassInfoW returned %d\n", rc));
502 return(rc);
503}
504/****************************************************************************
505 * Name : BOOL WIN32API GetClassInfoExA
506 * Purpose : The GetClassInfoEx function retrieves information about a window
507 * class, including the handle of the small icon associated with the
508 * window class. GetClassInfo does not retrieve the handle of the small icon.
509 * Parameters: HINSTANCE hinst handle of application instance
510 * LPCTSTR lpszClass address of class name string
511 * LPWNDCLASSEX lpwcx address of structure for class data
512 * Variables :
513 * Result : If the function finds a matching class and successfully copies
514 * the data, the return value is TRUE;
515 * otherwise, it is FALSE.
516 * To get extended error information, call GetLastError.
517 * Remark : PH: does not obtain handle of the small icon
518 * Status : UNTESTED STUB
519 *
520 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
521 *****************************************************************************/
522BOOL WIN32API GetClassInfoExA(HINSTANCE hInstance,
523 LPCTSTR lpszClass,
524 LPWNDCLASSEXA lpwcx)
525{
526 WNDCLASSA WndClass; /* structure for data transformation */
527 BOOL bResult; /* result of subsequent function calls */
528
529 dprintf(("USER32:GetClassInfoExA (%08xh,%s,%08x).\n",
530 hInstance,
531 lpszClass,
532 lpwcx));
533
534 /* convert the structures */
535 memcpy((PVOID)&WndClass,
536 (PVOID)&lpwcx->style,
537 sizeof(WndClass) );
538
539 bResult = GetClassInfoA(hInstance,
540 lpszClass,
541 (WNDCLASSA *)&WndClass);
542 if (bResult == TRUE)
543 {
544 /* convert data back to original structure */
545 memcpy((PVOID)&lpwcx->style,
546 (PVOID)&WndClass,
547 sizeof(WndClass) );
548 lpwcx->cbSize = sizeof(WNDCLASSEXA);
549 lpwcx->hIconSm = 0;
550 }
551
552 return (bResult);
553}
554/*****************************************************************************
555 * Name : BOOL WIN32API GetClassInfoExW
556 * Purpose : The GetClassInfoEx function retrieves information about a window
557 * class, including the handle of the small icon associated with the
558 * window class. GetClassInfo does not retrieve the handle of the small icon.
559 * Parameters: HINSTANCE hinst handle of application instance
560 * LPCWSTR lpszClass address of class name string
561 * LPWNDCLASSEX lpwcx address of structure for class data
562 * Variables :
563 * Result : If the function finds a matching class and successfully copies
564 * the data, the return value is TRUE;
565 * otherwise, it is FALSE.
566 * To get extended error information, call GetLastError.
567 * Remark : does not obtain handle of the small icon
568 * Status : UNTESTED STUB
569 *
570 * Author : Patrick Haller [Thu, 1998/02/26 11:55]
571 *****************************************************************************/
572BOOL WIN32API GetClassInfoExW(HINSTANCE hInstance,
573 LPCWSTR lpszClass,
574 LPWNDCLASSEXW lpwcx)
575{
576 WNDCLASSW WndClass; /* structure for data transformation */
577 BOOL bResult; /* result of subsequent function calls */
578
579 dprintf(("USER32:GetClassInfoExW (%08xh,%s,%08x).\n",
580 hInstance,
581 lpszClass,
582 lpwcx));
583
584 /* convert the structures */
585 memcpy((PVOID)&WndClass,
586 (PVOID)&lpwcx->style,
587 sizeof(WndClass) );
588
589 bResult = GetClassInfoW(hInstance,
590 (LPWSTR)lpszClass,
591 (WNDCLASSW *)&WndClass);
592 if (bResult == TRUE)
593 {
594 /* convert data back to original structure */
595 memcpy((PVOID)&lpwcx->style,
596 (PVOID)&WndClass,
597 sizeof(WndClass) );
598 lpwcx->cbSize = sizeof(WNDCLASSEXW);
599 lpwcx->hIconSm = 0;
600 }
601
602 return (bResult);
603}
604//******************************************************************************
605//TODO: Not complete (unsupported extension in WNDCLASSEXA/W, unsupported styles etc)
606//******************************************************************************
607LONG WIN32API GetClassLongA(HWND hwnd, int nIndex)
608{
609 DWORD rc;
610
611 dprintf(("USER32: OS2GetClassLongA\n"));
612 rc = O32_GetClassLong(hwnd, nIndex);
613 if(nIndex == GCL_WNDPROC) {
614 char szClass[128];
615 Win32WindowClass *wclass;
616
617 if(GetClassNameA(hwnd, szClass, sizeof(szClass))) {
618 wclass = Win32WindowClass::FindClass(szClass);
619 if(wclass) {
620 return (LONG)wclass->GetWinCallback();
621 }
622 }
623 dprintf(("GetClassLongA, class of window %X not found\n", hwnd));
624 return 0; //TODO: set last error
625 }
626 return rc;
627}
628//******************************************************************************
629//******************************************************************************
630LONG WIN32API GetClassLongW(HWND hwnd, int nIndex)
631{
632 dprintf(("USER32: OS2GetClassLongW\n"));
633 if(nIndex == GCL_MENUNAME) { //TODO
634 dprintf(("USER32: Class Menu name not implemented yet\n"));
635 }
636 // NOTE: This will not work as is (needs UNICODE support)
637 return GetClassLongA(hwnd, nIndex);
638}
639//******************************************************************************
640//******************************************************************************
641int WIN32API GetClassNameA( HWND arg1, LPSTR arg2, int arg3)
642{
643 dprintf(("USER32: OS2GetClassNameA\n"));
644 return O32_GetClassName(arg1, arg2, arg3);
645}
646//******************************************************************************
647//******************************************************************************
648int WIN32API GetClassNameW(HWND hwnd, LPWSTR lpClassName, int nMaxCount)
649{
650 char *astring = (char *)malloc(nMaxCount);
651 int rc;
652
653 dprintf(("USER32: OS2GetClassNameW\n"));
654 rc = GetClassNameA(hwnd, astring, nMaxCount);
655 AsciiToUnicode(astring, lpClassName);
656 free(astring);
657 return(rc);
658}
659//******************************************************************************
660//******************************************************************************
661WORD WIN32API GetClassWord( HWND arg1, int arg2)
662{
663 dprintf(("USER32: OS2GetClassWord\n"));
664 return O32_GetClassWord(arg1, arg2);
665}
666//******************************************************************************
667//******************************************************************************
668LONG WIN32API SetClassLongA(HWND hwnd, int nIndex, LONG lNewVal)
669{
670 DWORD rc;
671
672 dprintf(("USER32: OS2SetClassLongA\n"));
673 if(nIndex == GCL_WNDPROC) {
674 char szClass[128];
675 Win32WindowClass *wclass;
676
677 if(GetClassNameA(hwnd, szClass, sizeof(szClass))) {
678 wclass = Win32WindowClass::FindClass(szClass);
679 if(wclass) {
680 rc = (DWORD)wclass->GetWinCallback();
681 wclass->SetWinCallback((WNDPROC)lNewVal);
682 return rc;
683 }
684 }
685 dprintf(("SetClassLongA, class of window %X not found\n", hwnd));
686 return 0; //TODO: set last error
687 }
688 return O32_SetClassLong(hwnd, nIndex, lNewVal);
689}
690//******************************************************************************
691//******************************************************************************
692LONG WIN32API SetClassLongW( HWND arg1, int arg2, LONG arg3)
693{
694 dprintf(("USER32: OS2SetClassLongW\n"));
695 // NOTE: This will not work as is (needs UNICODE support)
696 return O32_SetClassLong(arg1, arg2, arg3);
697}
698//******************************************************************************
699//******************************************************************************
700WORD WIN32API SetClassWord( HWND arg1, int arg2, WORD arg3)
701{
702 dprintf(("USER32: OS2SetClassWord\n"));
703 return O32_SetClassWord(arg1, arg2, arg3);
704}
705//******************************************************************************
706//Win32WindowClass methods:
707//******************************************************************************
708Win32WindowClass::Win32WindowClass(WNDPROC pUserCallback, LPSTR id, HINSTANCE hinst)
709{
710 //Insert it in front of the rest
711 next = wndclasses;
712 wndclasses = this;
713 if((int)id >> 16 != 0) {
714 strcpy(className, id);
715 classAtom = 0;
716 }
717 else {
718 className[0] = 0;
719 classAtom = (DWORD)id;
720 }
721 this->hinst = hinst;
722
723 pWinCallback = pUserCallback;
724 dprintf(("Win32WindowClass::Win32WindowClass %d\n", id));
725}
726//******************************************************************************
727//******************************************************************************
728Win32WindowClass::~Win32WindowClass()
729{
730 Win32WindowClass *wndclass = Win32WindowClass::wndclasses;
731
732 if(wndclass == this) {
733 wndclasses = next;
734 }
735 else {
736 while(wndclass->next != NULL) {
737 if(wndclass->next == this) {
738 wndclass->next = next;
739 break;
740 }
741 wndclass = wndclass->next;
742 }
743 }
744}
745//******************************************************************************
746//******************************************************************************
747Win32WindowClass *Win32WindowClass::FindClass(LPSTR id)
748{
749 Win32WindowClass *wndclass = wndclasses;
750
751 if(wndclass == NULL) return(NULL);
752
753 if((int)id >> 16 != 0) {
754 if(stricmp(wndclass->className, id) == 0) {
755 return(wndclass);
756 }
757 else {
758 wndclass = wndclass->next;
759 while(wndclass != NULL) {
760 if(stricmp(wndclass->className, id) == 0) {
761 return(wndclass);
762 }
763 wndclass = wndclass->next;
764 }
765 }
766 }
767 else {
768 if(wndclass->classAtom == (DWORD)id) {
769 return(wndclass);
770 }
771 else {
772 wndclass = wndclass->next;
773 while(wndclass != NULL) {
774 if(wndclass->classAtom == (DWORD)id) {
775 return(wndclass);
776 }
777 wndclass = wndclass->next;
778 }
779 }
780 }
781 return(NULL);
782}
783//******************************************************************************
784//******************************************************************************
785void Win32WindowClass::UnregisterClass(HINSTANCE hinst, LPSTR id)
786{
787 Win32WindowClass *wndclass;
788
789 dprintf(("::UnregisterClass, destroy class %X!!\n", id));
790 wndclass = FindClass(id);
791 if(wndclass && wndclass->hinst == hinst) {
792 delete wndclass;
793 return;
794 }
795 dprintf(("::UnregisterClass, couldn't find class %X!!\n", id));
796}
797//******************************************************************************
798//******************************************************************************
799WNDPROC Win32WindowClass::GetClassCallback(HINSTANCE hinst, LPSTR id)
800{
801 Win32WindowClass *wndclass;
802
803 wndclass = FindClass(id);
804 if(wndclass && wndclass->hinst == hinst) {
805 return wndclass->pWinCallback;
806 }
807 dprintf(("::GetClassCallback, couldn't find class %X!!\n", id));
808 return(NULL);
809}
810//******************************************************************************
811//******************************************************************************
812WNDPROC Win32WindowClass::GetClassCallback(LPSTR id)
813{
814 Win32WindowClass *wndclass;
815
816 wndclass = FindClass(id);
817 if(wndclass) {
818 return wndclass->pWinCallback;
819 }
820 dprintf(("::GetClassCallback2, couldn't find class %X!!\n", id));
821 return(NULL);
822}
823//******************************************************************************
824//******************************************************************************
825WNDPROC_O32 Win32WindowClass::GetOS2ClassCallback()
826{
827 return OS2ToWinCallback;
828}
829//******************************************************************************
830//******************************************************************************
831LRESULT EXPENTRY_O32 OS2ToWinCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
832{
833 char szClass[128];
834 Win32WindowClass *wclass;
835 LRESULT rc;
836 DWORD dwStyle, dwExStyle;
837 HWND parentHwnd;
838 Win32WindowProc *window;
839
840 //Restore our FS selector
841 SetWin32TIB();
842
843 if(Msg == WM_MOUSEACTIVATE)
844 {
845 //Open32 sends an OS/2 window message for a button click
846 if(HIWORD(lParam) == 0x71) //WM_BUTTONCLICKFIRST
847 {
848 lParam = (WM_LBUTTONDOWN << 16) | LOWORD(lParam);
849 }
850 }
851 if(PostSpyMessage(hwnd, Msg, wParam, lParam) == FALSE)
852 dprintf(("OS2ToWinCallback %s for %x %x %x", GetMsgText(Msg), hwnd, wParam, lParam));
853
854 if(HkCBT::OS2HkCBTProc(hwnd, Msg, wParam, lParam) == TRUE) {//hook swallowed msg
855 RestoreOS2TIB();
856 return(0);
857 }
858
859 if(O32_GetClassName(hwnd, szClass, sizeof(szClass))) {
860 wclass = Win32WindowClass::FindClass(szClass);
861 if(wclass) {
862 switch(Msg)
863 {
864 case WM_CREATE://Open32 isn't sending WM_NCCREATE messages!!
865 window = Win32WindowProc::FindProc(hwnd, GetCurrentThreadId());
866 if(window) {
867 dprintf(("OS2ToWinCallback (class): New window object!"));
868 window->SetWindowHandle(hwnd);
869 }
870
871 if(wclass->GetWinCallback()(hwnd, WM_NCCREATE, 0, lParam) == 0) {
872 dprintf(("WM_NCCREATE returned FALSE\n"));
873 return(-1); //don't create window
874 }
875 //Send WM_CREATE message before notifying parent
876 rc = wclass->GetWinCallback()(hwnd, Msg, wParam, lParam);
877
878 NotifyParent(hwnd, WM_CREATE, wParam, lParam);
879 RestoreOS2TIB();
880 return(rc);
881
882 case WM_DESTROY: //nofity parent
883 case WM_LBUTTONDOWN:
884 case WM_MBUTTONDOWN:
885 case WM_RBUTTONDOWN:
886 NotifyParent(hwnd, Msg, wParam, lParam);
887 break;
888
889 case WM_KEYDOWN:
890 case WM_KEYUP:
891 case WM_CHAR: //SvL: Correct Open32 key mapping bug
892 //TODO: Not good enough, look at Wine
893 lParam = MapOEMToRealKey(wParam, lParam);
894 break;
895
896 case WM_ACTIVATE:
897 if(LOWORD(wParam) != WA_INACTIVE)
898 {
899 //EB: I think the problem is not a missing wm_erasebkgnd.
900 //Maybe some wrong flags in open32 during async repainting.
901 RECT rect;
902 HRGN hrgn;
903 HDC hdc = GetDC(hwnd);
904
905 // erase the dirty rect
906 GetUpdateRect(hwnd, &rect, TRUE);
907 hrgn = CreateRectRgnIndirect(&rect);
908 SelectClipRgn (hdc, hrgn);
909 DeleteObject (hrgn);
910 wclass->GetWinCallback()(hwnd, WM_ERASEBKGND, hdc, (LPARAM)&rect);
911 SelectClipRgn (hdc, NULL);
912 ReleaseDC(hwnd, hdc);
913 }
914 break;
915 }
916 rc = wclass->GetWinCallback()(hwnd, Msg, wParam, lParam);
917 RestoreOS2TIB();
918 return rc;
919 }
920 }
921 dprintf(("OS2ToWinCallback: couldn't find class procedure of window %X\n", hwnd));
922 RestoreOS2TIB();
923 return(0);
924}
925//******************************************************************************
926//******************************************************************************
927LRESULT WIN32API WinToOS2Callback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
928{
929 WNDPROC_O32 os2callback;
930
931 os2callback = (WNDPROC_O32)GetClassLongA(hwnd, GCL_WNDPROC);
932 if(os2callback) {
933 return os2callback(hwnd, Msg, wParam, lParam);
934 }
935 dprintf(("OS2ToWinCallback: window procedure == NULL!!\n"));
936 return(0);
937}
938//******************************************************************************
939//******************************************************************************
940Win32WindowClass *Win32WindowClass::wndclasses = NULL;
Note: See TracBrowser for help on using the repository browser.