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

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

Msg handler bugfix

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