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

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

EB's MapOEMToRealKey fix

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