source: trunk/src/user32/wndproc.cpp@ 645

Last change on this file since 645 was 645, checked in by phaller, 26 years ago

Fix: GetClassInfoA fails on querying system classes. Win32Proc constructor crashed.

File size: 13.2 KB
Line 
1/* $Id: wndproc.cpp,v 1.15 1999-08-23 13:07:10 phaller Exp $ */
2
3/*
4 * Win32 window procedure class for OS/2
5 *
6 * Copyright 1998 Sander van Leeuwen
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#include <os2win.h>
13#include <dde.h>
14#include <stdio.h>
15#include <string.h>
16#include <stdarg.h>
17#include <stdlib.h>
18#include <assert.h>
19#include <misc.h>
20#include <wndproc.h>
21#include <wndclass.h>
22#include <spy.h>
23#include <wprocess.h>
24#include "dlgconvert.h"
25#include "hooks.h"
26#include "wndmsg.h"
27
28void NotifyParent(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
29{
30 DWORD dwStyle, dwExStyle;
31 HWND hwndParent = GetParent(hwnd);;
32
33 while(hwndParent) {
34 dwStyle = GetWindowLongA(hwnd, GWL_STYLE);
35 dwExStyle = GetWindowLongA(hwnd, GWL_EXSTYLE);
36 //SvL: Taken from Wine
37 if(dwStyle & WS_CHILD && !(dwExStyle & WS_EX_NOPARENTNOTIFY) )
38 {
39 //NOTE: Open32's SendMessage swallows a WM_PARENTNOTIFY, so call
40 // the win32 callback handler directly!
41 hwndParent = GetParent(hwnd);
42 if(hwnd == hwndParent) {
43 break;
44 }
45
46 dprintf(("%s Send WM_PARENTNOTIFY from child %x to parent %x", GetMsgText(Msg), hwnd, hwndParent));
47 /* Notify the parent window only */
48 Win32WindowProc *parentwnd = Win32WindowProc::FindProc(hwndParent);
49 if(parentwnd) {
50 if(Msg == WM_CREATE || Msg == WM_DESTROY) {
51 //Todo: Set IdChild!!
52 parentwnd->SendMessageA(hwndParent, WM_PARENTNOTIFY, MAKEWPARAM(Msg, 0), (LPARAM)hwnd );
53 }
54 else parentwnd->SendMessageA(hwndParent, WM_PARENTNOTIFY, MAKEWPARAM(Msg, 0), lParam );
55 }
56 }
57 else break;
58
59 hwnd = hwndParent;
60 }
61}
62//******************************************************************************
63//******************************************************************************
64Win32WindowProc *SYSTEM CreateWindowProc(WNDPROC pUserCallback)
65{
66 return new Win32WindowProc(pUserCallback);
67}
68//******************************************************************************
69//******************************************************************************
70Win32WindowProc::Win32WindowProc(WNDPROC pUserCallback)
71 : hwnd(0), next(NULL), os2dlg(NULL), win32class(0), pOS2Callback(NULL)
72{
73 //Insert it in front of the rest
74 next = windows;
75 windows = this;
76 threadid = (DWORD)GetCurrentThreadId();
77
78 pCallback = pUserCallback;
79 fIsWindow = TRUE;
80}
81//******************************************************************************
82//******************************************************************************
83Win32WindowProc::Win32WindowProc(WNDPROC pUserCallback, WNDPROC_O32 pOS2Callback)
84 : hwnd(0), next(NULL), os2dlg(NULL), win32class(0), pOS2Callback(NULL)
85{
86 //Insert it in front of the rest
87 next = windows;
88 windows = this;
89 threadid = (DWORD)GetCurrentThreadId();
90
91 pCallback = pUserCallback; //can be NULL (to be set in SetWindowLong call)
92 fIsWindow = TRUE;
93 if(pOS2Callback == NULL) {
94 dprintf(("Win32WindowProc ctor: pOS2Callback == NULL"));
95 DebugInt3();
96 }
97 this->pOS2Callback = pOS2Callback;
98}
99//******************************************************************************
100//******************************************************************************
101Win32WindowProc::Win32WindowProc(WNDPROC pUserCallback, DLGTEMPLATE *os2dlg)
102 : hwnd(0), next(NULL), os2dlg(NULL), win32class(0), pOS2Callback(NULL)
103{
104 //Insert it in front of the rest
105 next = windows;
106 windows = this;
107 threadid = (DWORD)GetCurrentThreadId();
108 this->os2dlg = os2dlg; //delete on destruction
109
110 pCallback = pUserCallback;
111 fIsWindow = FALSE;
112}
113//******************************************************************************
114//******************************************************************************
115Win32WindowProc::Win32WindowProc(HINSTANCE hinst, LPCSTR lpszClassName)
116 : hwnd(0), next(NULL), os2dlg(NULL), pOS2Callback(NULL)
117{
118 WNDCLASSA wc;
119 BOOL rc;
120
121 rc = GetClassInfoA(hinst, lpszClassName, &wc);
122 if (rc == FALSE)
123 {
124 dprintf (("USER32:WNDPROC: GetClassInfoA(%s) failed.",
125 lpszClassName));
126 }
127 else
128 {
129 // pCallback = Win32WindowClass::GetClassCallback(hinst, (LPSTR)wc.lpszClassName);
130 pCallback = Win32WindowClass::GetClassCallback((LPSTR)wc.lpszClassName);
131 if(pCallback == NULL) //system class
132 pCallback = (WNDPROC)wc.lpfnWndProc;
133 }
134
135 //Insert it in front of the rest
136 next = windows;
137 windows = this;
138 threadid = (DWORD)GetCurrentThreadId();
139
140 fIsWindow = TRUE;
141
142 win32class = Win32WindowClass::FindClass((LPSTR)lpszClassName);
143
144}
145//******************************************************************************
146//******************************************************************************
147Win32WindowProc::~Win32WindowProc()
148{
149 Win32WindowProc *window = Win32WindowProc::windows;
150
151 /* @@@PH 98/07/13 what's this whole code good for ? */
152 if(window == this)
153 {
154 windows = next;
155 }
156 else
157 {
158 /* @@@PH 98/07/13 window can be NULL */
159 if (window != NULL)
160 while(window->next != NULL)
161 {
162 if(window->next == this)
163 {
164 window->next = next;
165 break;
166 }
167 window = window->next;
168 }
169 }
170
171 if(os2dlg)
172 {
173 DeleteWin32DlgTemplate(os2dlg);
174 os2dlg = NULL;
175 }
176}
177//******************************************************************************
178//******************************************************************************
179BOOL Win32WindowProc::FindWindowProc(Win32WindowProc *wndproc)
180{
181 Win32WindowProc *window = Win32WindowProc::windows;
182
183 while(window != NULL) {
184 if(window == wndproc) {
185 return(TRUE);
186 }
187 window = window->next;
188 }
189 return(FALSE);
190}
191//******************************************************************************
192//******************************************************************************
193WNDPROC_O32 Win32WindowProc::GetOS2Callback()
194{
195 return(OS2ToWin32Callback);
196}
197//******************************************************************************
198//******************************************************************************
199WNDPROC Win32WindowProc::GetWin32ToOS2Callback()
200{
201 return(Win32ToOS2Callback);
202}
203//******************************************************************************
204//******************************************************************************
205Win32WindowProc *Win32WindowProc::FindProc(HWND hwnd)
206{
207 Win32WindowProc *window = Win32WindowProc::windows;
208
209 while(window != NULL) {
210 if(window->hwnd == hwnd) {
211 return(window);
212 }
213 window = window->next;
214 }
215 dprintf(("Win32WindowProc::FindProc, can't find window %X!\n", hwnd));
216 return(NULL);
217}
218//******************************************************************************
219//Find newly created window
220//******************************************************************************
221Win32WindowProc *Win32WindowProc::FindProc(HWND hwnd, DWORD threadid)
222{
223 Win32WindowProc *window = Win32WindowProc::windows;
224
225 while(window != NULL) {
226 if(window->hwnd == 0 && window->threadid == threadid) {
227 return(window);
228 }
229 window = window->next;
230 }
231 dprintf(("Win32WindowProc::FindProc, can't find window %X %d!\n", hwnd, threadid));
232 return(NULL);
233}
234//******************************************************************************
235//******************************************************************************
236void Win32WindowProc::DeleteWindow(HWND hwnd)
237{
238 Win32WindowProc *window = FindProc(hwnd);
239
240#ifdef DEBUG
241 WriteLog("::DeleteWindow, destroy window/dialog %X!!\n", hwnd);
242#endif
243 if(window) {
244 delete(window);
245 return;
246 }
247#ifdef DEBUG
248 WriteLog("::DeleteWindow, can't find window %X!!\n", hwnd);
249#endif
250}
251//******************************************************************************
252//******************************************************************************
253LRESULT Win32WindowProc::SendMessageA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
254{
255 PostSpyMessage(hwnd, Msg, wParam, lParam);
256 return pCallback(hwnd, Msg, wParam, lParam);
257}
258//******************************************************************************
259//******************************************************************************
260DWORD MapOEMToRealKey(DWORD wParam, DWORD lParam)
261{
262 switch((UCHAR)(lParam >> 16)) {
263 case 0x60: // VK_HOME
264 lParam &= 0xFF00FFFF;
265 lParam |= 0x00470000;
266 break;
267 case 0x61: // VK_UP
268 lParam &= 0xFF00FFFF;
269 lParam |= 0x00480000;
270 break;
271 case 0x62: // VK_PRIOR //page up
272 lParam &= 0xFF00FFFF;
273 lParam |= 0x00490000;
274 break;
275 case 0x63: // VK_LEFT
276 lParam &= 0xFF00FFFF;
277 lParam |= 0x004B0000;
278 break;
279 case 0x64: // VK_RIGHT
280 lParam &= 0xFF00FFFF;
281 lParam |= 0x004D0000;
282 break;
283 case 0x65: // VK_END
284 lParam &= 0xFF00FFFF;
285 lParam |= 0x004F0000;
286 break;
287 case 0x66: // VK_DOWN:
288 lParam &= 0xFF00FFFF;
289 lParam |= 0x00500000;
290 break;
291 case 0x67: // VK_NEXT //page down
292 lParam &= 0xFF00FFFF;
293 lParam |= 0x00510000;
294 break;
295 case 0x68: // VK_INSERT
296 lParam &= 0xFF00FFFF;
297 lParam |= 0x00520000;
298 break;
299 case 0x69: // VK_DELETE
300 lParam &= 0xFF00FFFF;
301 lParam |= 0x00530000;
302 break;
303 }
304 return(lParam);
305}
306//******************************************************************************
307//#undef DEBUG
308//#define DEBUG1
309//******************************************************************************
310LRESULT EXPENTRY_O32 OS2ToWin32Callback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
311{
312 Win32WindowProc *curwnd;
313 LRESULT rc;
314
315 //Restore our FS selector
316 SetWin32TIB();
317
318 if(Msg == WM_MOUSEACTIVATE)
319 {
320 //Open32 sends an OS/2 window message for a button click
321 if(HIWORD(lParam) == 0x71) //WM_BUTTONCLICKFIRST
322 {
323 lParam = (WM_LBUTTONDOWN << 16) | LOWORD(lParam);
324 }
325 }
326
327 if(PostSpyMessage(hwnd, Msg, wParam, lParam) == FALSE)
328 dprintf(("Message %s for %X %x %x\n", GetMsgText(Msg), hwnd, wParam, lParam));
329
330 if(HkCBT::OS2HkCBTProc(hwnd, Msg, wParam, lParam) == TRUE) {//hook swallowed msg
331 RestoreOS2TIB();
332 return(0);
333 }
334
335 curwnd = Win32WindowProc::FindProc(hwnd);
336 if(!curwnd) {
337 curwnd = Win32WindowProc::FindProc(0, GetCurrentThreadId());
338 if(curwnd) curwnd->SetWindowHandle(hwnd);
339 }
340 if(curwnd != NULL) {
341 switch(Msg)
342 {
343 case WM_KEYDOWN:
344 case WM_KEYUP:
345 case WM_CHAR:
346 //SvL: Correct Open32 key mapping bug
347 lParam = MapOEMToRealKey(wParam, lParam);
348 break;
349 case WM_CREATE: //Open32 isn't sending WM_NCCREATE messages!!
350 if(curwnd->SendMessageA(hwnd, WM_NCCREATE, 0, lParam) == 0) {
351 dprintf(("WM_NCCREATE returned FALSE\n"));
352 RestoreOS2TIB();
353 return(-1); //don't create window
354 }
355
356 NotifyParent(hwnd, WM_CREATE, wParam, lParam);
357//TODO
358#if 0
359 if(curwnd->SendMessageA(hwnd, WM_NCCALCSIZE, 0, lParam) == 0) {
360 RestoreOS2TIB();
361 return(-1); //don't create window
362 }
363#endif
364 break;
365
366 case WM_LBUTTONDOWN:
367 case WM_MBUTTONDOWN:
368 case WM_RBUTTONDOWN:
369 case WM_DESTROY: //nofity parent
370 NotifyParent(hwnd, Msg, wParam, lParam);
371 break;
372
373 case WM_ACTIVATE:
374 if(LOWORD(wParam) != WA_INACTIVE)
375 {//SvL: Bugfix, Open32 is NOT sending this to the window (messes up Solitaire)
376 HDC hdc = GetDC(hwnd);
377
378 curwnd->SendMessageA(hwnd, WM_ERASEBKGND, hdc, 0);
379 ReleaseDC(hwnd, hdc);
380 }
381 break;
382 }
383
384 rc = curwnd->pCallback(hwnd, Msg, wParam, lParam);
385 if(Msg == WM_NCDESTROY) {
386 dprintf(("WM_NCDESTROY received for window/dialog %X\n", curwnd->hwnd));
387 delete curwnd;
388 }
389 RestoreOS2TIB();
390 return rc;
391 }
392
393 //Could be a dialog control using a registered class, so check this:
394 char szClass[128];
395 Win32WindowClass *wclass;
396 Win32WindowProc *wnd;
397
398 if(GetClassNameA(hwnd, szClass, sizeof(szClass))) {
399 wclass = Win32WindowClass::FindClass(szClass);
400 if(wclass) {
401 wnd = new Win32WindowProc(wclass->GetClassCallback(szClass));
402 wnd->SetWindowHandle(hwnd);
403 rc = OS2ToWin32Callback(hwnd, Msg, wParam, lParam);
404 RestoreOS2TIB();
405 return rc;
406 }
407 }
408 dprintf(("wnd Callback, can't find window %X %d!!!!\n", hwnd, Msg));
409 RestoreOS2TIB();
410 return 0;
411}
412//******************************************************************************
413//******************************************************************************
414LRESULT EXPENTRY Win32ToOS2Callback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
415{
416 LRESULT rc;
417
418 Win32WindowProc *curwnd = Win32WindowProc::FindProc(hwnd);
419 if(curwnd && curwnd->pOS2Callback) {
420 RestoreOS2TIB();
421 rc = curwnd->pOS2Callback(hwnd, Msg, wParam, lParam);
422 SetWin32TIB();
423 return rc;
424 }
425 else DebugInt3();
426
427 return 0;
428}
429//******************************************************************************
430//******************************************************************************
431Win32WindowProc *Win32WindowProc::windows = NULL;
Note: See TracBrowser for help on using the repository browser.