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

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

Message handler updates & bugfixes

File size: 11.7 KB
Line 
1/* $Id: wndproc.cpp,v 1.12 1999-06-27 16:23:24 sandervl 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)
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, DLGTEMPLATE *os2dlg)
84 : hwnd(0), next(NULL), os2dlg(NULL), win32class(0)
85{
86 //Insert it in front of the rest
87 next = windows;
88 windows = this;
89 threadid = (DWORD)GetCurrentThreadId();
90 this->os2dlg = os2dlg; //delete on destruction
91
92 pCallback = pUserCallback;
93 fIsWindow = FALSE;
94}
95//******************************************************************************
96//******************************************************************************
97Win32WindowProc::Win32WindowProc(HINSTANCE hinst, LPCSTR lpszClassName)
98 : hwnd(0), next(NULL), os2dlg(NULL)
99{
100 WNDCLASSA wc;
101 BOOL rc;
102
103 rc = GetClassInfoA(hinst, lpszClassName, &wc);
104 assert(rc == TRUE);
105
106// pCallback = Win32WindowClass::GetClassCallback(hinst, (LPSTR)wc.lpszClassName);
107 pCallback = Win32WindowClass::GetClassCallback((LPSTR)wc.lpszClassName);
108//test (8nov)
109 if(pCallback == NULL) {//system class
110 pCallback = (WNDPROC)wc.lpfnWndProc;
111 }
112// assert(pCallback != NULL);
113
114 //Insert it in front of the rest
115 next = windows;
116 windows = this;
117 threadid = (DWORD)GetCurrentThreadId();
118
119 fIsWindow = TRUE;
120
121 win32class = Win32WindowClass::FindClass((LPSTR)lpszClassName);
122
123}
124//******************************************************************************
125//******************************************************************************
126Win32WindowProc::~Win32WindowProc()
127{
128 Win32WindowProc *window = Win32WindowProc::windows;
129
130 /* @@@PH 98/07/13 what's this whole code good for ? */
131 if(window == this)
132 {
133 windows = next;
134 }
135 else
136 {
137 /* @@@PH 98/07/13 window can be NULL */
138 if (window != NULL)
139 while(window->next != NULL)
140 {
141 if(window->next == this)
142 {
143 window->next = next;
144 break;
145 }
146 window = window->next;
147 }
148 }
149
150 if(os2dlg)
151 {
152 DeleteWin32DlgTemplate(os2dlg);
153 os2dlg = NULL;
154 }
155}
156//******************************************************************************
157//******************************************************************************
158BOOL Win32WindowProc::FindWindowProc(Win32WindowProc *wndproc)
159{
160 Win32WindowProc *window = Win32WindowProc::windows;
161
162 while(window != NULL) {
163 if(window == wndproc) {
164 return(TRUE);
165 }
166 window = window->next;
167 }
168 return(FALSE);
169}
170//******************************************************************************
171//******************************************************************************
172WNDPROC_O32 Win32WindowProc::GetOS2Callback()
173{
174 return(WndCallback);
175}
176//******************************************************************************
177//******************************************************************************
178Win32WindowProc *Win32WindowProc::FindProc(HWND hwnd)
179{
180 Win32WindowProc *window = Win32WindowProc::windows;
181
182 while(window != NULL) {
183 if(window->hwnd == hwnd) {
184 return(window);
185 }
186 window = window->next;
187 }
188 dprintf(("Win32WindowProc::FindProc, can't find window %X!\n", hwnd));
189 return(NULL);
190}
191//******************************************************************************
192//Find newly created window
193//******************************************************************************
194Win32WindowProc *Win32WindowProc::FindProc(HWND hwnd, DWORD threadid)
195{
196 Win32WindowProc *window = Win32WindowProc::windows;
197
198 while(window != NULL) {
199 if(window->hwnd == 0 && window->threadid == threadid) {
200 return(window);
201 }
202 window = window->next;
203 }
204 dprintf(("Win32WindowProc::FindProc, can't find window %X %d!\n", hwnd, threadid));
205 return(NULL);
206}
207//******************************************************************************
208//******************************************************************************
209void Win32WindowProc::DeleteWindow(HWND hwnd)
210{
211 Win32WindowProc *window = FindProc(hwnd);
212
213#ifdef DEBUG
214 WriteLog("::DeleteWindow, destroy window/dialog %X!!\n", hwnd);
215#endif
216 if(window) {
217 delete(window);
218 return;
219 }
220#ifdef DEBUG
221 WriteLog("::DeleteWindow, can't find window %X!!\n", hwnd);
222#endif
223}
224//******************************************************************************
225//******************************************************************************
226LRESULT Win32WindowProc::SendMessageA(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
227{
228 PostSpyMessage(hwnd, Msg, wParam, lParam);
229 return pCallback(hwnd, Msg, wParam, lParam);
230}
231//******************************************************************************
232//******************************************************************************
233DWORD MapOEMToRealKey(DWORD wParam, DWORD lParam)
234{
235 switch(wParam) {
236 case VK_PRIOR: //page up
237 lParam &= 0xFF00FFFF;
238 lParam |= 0x00510000;
239 break;
240 case VK_NEXT: //page down
241 lParam &= 0xFF00FFFF;
242 lParam |= 0x00490000;
243 break;
244 case VK_END:
245 lParam &= 0xFF00FFFF;
246 lParam |= 0x004F0000;
247 break;
248 case VK_HOME:
249 lParam &= 0xFF00FFFF;
250 lParam |= 0x00470000;
251 break;
252 case VK_UP:
253 lParam &= 0xFF00FFFF;
254 lParam |= 0x00480000;
255 break;
256 case VK_LEFT:
257 lParam &= 0xFF00FFFF;
258 lParam |= 0x004B0000;
259 break;
260 case VK_DOWN:
261 lParam &= 0xFF00FFFF;
262 lParam |= 0x00500000;
263 break;
264 case VK_RIGHT:
265 lParam &= 0xFF00FFFF;
266 lParam |= 0x004D0000;
267 break;
268 case VK_DELETE:
269 lParam &= 0xFF00FFFF;
270 lParam |= 0x00530000;
271 break;
272 case VK_INSERT:
273 lParam &= 0xFF00FFFF;
274 lParam |= 0x00520000;
275 break;
276 }
277 return(lParam);
278}
279//******************************************************************************
280//#undef DEBUG
281//#define DEBUG1
282//******************************************************************************
283LRESULT EXPENTRY_O32 WndCallback(HWND hwnd, UINT Msg, WPARAM wParam, LPARAM lParam)
284{
285 Win32WindowProc *curwnd;
286 LRESULT rc;
287
288 //Restore our FS selector
289 SetWin32TIB();
290
291 if(Msg == WM_MOUSEACTIVATE)
292 {
293 //Open32 sends an OS/2 window message for a button click
294 if(HIWORD(lParam) == 0x71) //WM_BUTTONCLICKFIRST
295 {
296 lParam = (WM_LBUTTONDOWN << 16) | LOWORD(lParam);
297 }
298 }
299
300 if(PostSpyMessage(hwnd, Msg, wParam, lParam) == FALSE)
301 dprintf(("Message %s for %X %x %x\n", GetMsgText(Msg), hwnd, wParam, lParam));
302
303 if(HkCBT::OS2HkCBTProc(hwnd, Msg, wParam, lParam) == TRUE) {//hook swallowed msg
304 RestoreOS2TIB();
305 return(0);
306 }
307
308 curwnd = Win32WindowProc::FindProc(hwnd);
309 if(!curwnd) {
310 curwnd = Win32WindowProc::FindProc(0, GetCurrentThreadId());
311 if(curwnd) curwnd->SetWindowHandle(hwnd);
312 }
313 if(curwnd != NULL) {
314 switch(Msg)
315 {
316 case WM_KEYDOWN:
317 case WM_KEYUP:
318 case WM_CHAR:
319 //SvL: Correct Open32 key mapping bug
320 lParam = MapOEMToRealKey(wParam, lParam);
321 break;
322 case WM_CREATE: //Open32 isn't sending WM_NCCREATE messages!!
323 if(curwnd->SendMessageA(hwnd, WM_NCCREATE, 0, lParam) == 0) {
324 dprintf(("WM_NCCREATE returned FALSE\n"));
325 RestoreOS2TIB();
326 return(-1); //don't create window
327 }
328
329 NotifyParent(hwnd, WM_CREATE, wParam, lParam);
330//TODO
331#if 0
332 if(curwnd->SendMessageA(hwnd, WM_NCCALCSIZE, 0, lParam) == 0) {
333 RestoreOS2TIB();
334 return(-1); //don't create window
335 }
336#endif
337 break;
338
339 case WM_LBUTTONDOWN:
340 case WM_MBUTTONDOWN:
341 case WM_RBUTTONDOWN:
342 case WM_DESTROY: //nofity parent
343 NotifyParent(hwnd, Msg, wParam, lParam);
344 break;
345
346 case WM_ACTIVATE:
347 if(LOWORD(wParam) != WA_INACTIVE)
348 {//SvL: Bugfix, Open32 is NOT sending this to the window (messes up Solitaire)
349 HDC hdc = GetDC(hwnd);
350
351 curwnd->SendMessageA(hwnd, WM_ERASEBKGND, hdc, 0);
352 ReleaseDC(hwnd, hdc);
353 }
354 break;
355 }
356
357 rc = curwnd->pCallback(hwnd, Msg, wParam, lParam);
358 if(Msg == WM_NCDESTROY) {
359 dprintf(("WM_NCDESTROY received for window/dialog %X\n", curwnd->hwnd));
360 delete curwnd;
361 }
362 RestoreOS2TIB();
363 return rc;
364 }
365
366 //Could be a dialog control using a registered class, so check this:
367 char szClass[128];
368 Win32WindowClass *wclass;
369 Win32WindowProc *wnd;
370
371 if(GetClassNameA(hwnd, szClass, sizeof(szClass))) {
372 wclass = Win32WindowClass::FindClass(szClass);
373 if(wclass) {
374 wnd = new Win32WindowProc(wclass->GetClassCallback(szClass));
375 wnd->SetWindowHandle(hwnd);
376 rc = WndCallback(hwnd, Msg, wParam, lParam);
377 RestoreOS2TIB();
378 return rc;
379 }
380 }
381 dprintf(("wnd Callback, can't find window %X %d!!!!\n", hwnd, Msg));
382 RestoreOS2TIB();
383 return 0;
384}
385//******************************************************************************
386//******************************************************************************
387Win32WindowProc *Win32WindowProc::windows = NULL;
Note: See TracBrowser for help on using the repository browser.