source: trunk/src/user32/old/wndproc.cpp@ 3830

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

Compilation fixes

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