source: trunk/src/user32/pmwindow.cpp@ 1408

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

Put back pos change messages in pmwindow.cpp, changed message logging

File size: 31.2 KB
Line 
1/* $Id: pmwindow.cpp,v 1.41 1999-10-23 10:21:43 sandervl Exp $ */
2/*
3 * Win32 Window Managment Code for OS/2
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 *
8 *
9 * Project Odin Software License can be found in LICENSE.TXT
10 *
11 */
12#define INCL_WIN
13#define INCL_GPI
14
15#include <os2.h> /* PM header file */
16#include <os2wrap.h>
17#include <stdlib.h>
18#include "win32type.h"
19#include <winconst.h>
20#include <wprocess.h>
21#include <misc.h>
22#include <win32wbase.h>
23#include <win32dlg.h>
24#include "win32wdesktop.h"
25#include "pmwindow.h"
26#include "oslibwin.h"
27#include "oslibutil.h"
28#include "oslibgdi.h"
29#include "oslibmsg.h"
30#include "dc.h"
31#include <thread.h>
32#include <wprocess.h>
33#include <caret.h>
34
35HMQ hmq = 0; /* Message queue handle */
36HAB hab = 0;
37
38RECTL desktopRectl = {0};
39ULONG ScreenWidth = 0;
40ULONG ScreenHeight = 0;
41
42//Used for key translation while processing WM_CHAR message
43USHORT virtualKeyTable [66] = {
44 0x00, // OS/2 VK Win32 VK, Entry 0 is not used
45 0x01, // VK_BUTTON1 VK_LBUTTON
46 0x02, // VK_BUTTON2 VK_RBUTTON
47 0x04, // VK_BUTTON3 VK_MBUTTON
48 0x03, // VK_BREAK VK_CANCEL
49 0x08, // VK_BACKSPACE VK_BACK
50 0x09, // VK_TAB VK_TAB
51 0x00, // VK_BACKTAB No equivalent!
52 0x0D, // VK_NEWLINE VK_RETURN
53 0x10, // VK_SHIFT VK_SHIFT
54 0x11, // VK_CTRL VK_CONTROL
55 0x12, // VK_ALT VK_MENU, best match I guess
56 0x12, // VK_ALTGRAF VK_MENU, best match I guess
57 0x13, // VK_PAUSE VK_PAUSE
58 0x14, // VK_CAPSLOCK VK_CAPITAL
59 0x1B, // VK_ESC VK_ESCAPE
60 0x20, // VK_SPACE VK_SPACE
61 0x21, // VK_PAGEUP VK_PRIOR
62 0x22, // VK_PAGEDOWN VK_NEXT
63 0x23, // VK_END VK_END
64 0x24, // VK_HOME VK_HOME
65 0x25, // VK_LEFT VK_LEFT
66 0x26, // VK_UP VK_UP
67 0x27, // VK_RIGHT VK_RIGHT
68 0x28, // VK_DOWN VK_DOWN
69 0x2C, // VK_PRINTSCRN VK_SNAPSHOT
70 0x2D, // VK_INSERT VK_INSERT
71 0x2E, // VK_DELETE VK_DELETE
72 0x91, // VK_SCRLLOCK VK_SCROLL
73 0x90, // VK_NUMLOCK VK_NUMLOCK
74 0x2B, // VK_ENTER VK_EXECUTE, best match I guess
75 0x00, // VK_SYSRQ No equivalent!
76 0x70, // VK_F1 VK_F1
77 0x71, // VK_F2 VK_F2
78 0x72, // VK_F3 VK_F3
79 0x73, // VK_F4 VK_F4
80 0x74, // VK_F5 VK_F5
81 0x75, // VK_F6 VK_F6
82 0x76, // VK_F7 VK_F7
83 0x77, // VK_F8 VK_F8
84 0x78, // VK_F9 VK_F9
85 0x79, // VK_F10 VK_F10
86 0x7A, // VK_F11 VK_F11
87 0x7B, // VK_F12 VK_F12
88 0x7C, // VK_F13 VK_F13
89 0x7D, // VK_F14 VK_F14
90 0x7E, // VK_F15 VK_F15
91 0x7F, // VK_F16 VK_F16
92 0x80, // VK_F17 VK_F17
93 0x81, // VK_F18 VK_F18
94 0x82, // VK_F19 VK_F19
95 0x83, // VK_F20 VK_F20
96 0x84, // VK_F21 VK_F21
97 0x85, // VK_F22 VK_F22
98 0x86, // VK_F23 VK_F23
99 0x87, // VK_F24 VK_F24
100 0x00, // VK_ENDDRAG No equivalent!
101 0x0C, // VK_CLEAR VK_CLEAR
102 0xF9, // VK_EREOF VK_EREOF
103 0xFD, // VK_PA1 VK_PA1
104 0xF6, // VK_ATTN VK_ATTN
105 0xF7, // VK_CRSEL VK_CRSEL
106 0xF8, // VK_EXSEL VK_EXSEL
107 0x00, // VK_COPY No equivalent!
108 0x00, // VK_BLK1 No equivalent!
109 0x00}; // VK_BLK2 No equivalent!
110
111MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
112
113//******************************************************************************
114//Initialize PM; create hab, message queue and register special Win32 window classes
115//******************************************************************************
116BOOL InitPM()
117{
118 hab = WinInitialize(0);
119 dprintf(("Winitialize returned %x", hab));
120 hmq = WinCreateMsgQueue(hab, 0);
121
122 if(!hab || !hmq)
123 {
124 UINT error;
125 //CB: only fail on real error
126 error = WinGetLastError(hab) & 0xFFFF; //error code
127 if (!hab || error != PMERR_MSG_QUEUE_ALREADY_EXISTS)
128 {
129 dprintf(("WinInitialize or WinCreateMsgQueue failed %x %x", hab, hmq));
130 dprintf((" Error = %x",error));
131 return(FALSE);
132 }
133 else
134 {
135 if(!hab) {
136 hab = WinQueryAnchorBlock(HWND_DESKTOP);
137 dprintf(("WinQueryAnchorBlock returned %x", hab));
138 }
139 if(!hmq) {
140 hmq = HMQ_CURRENT;
141 }
142 }
143 }
144 SetThreadHAB(hab);
145 dprintf(("InitPM: hmq = %x", hmq));
146 SetThreadMessageQueue(hmq);
147
148 if(!WinRegisterClass( /* Register window class */
149 hab, /* Anchor block handle */
150 (PSZ)WIN32_STDCLASS, /* Window class name */
151 (PFNWP)Win32WindowProc, /* Address of window procedure */
152// CS_SIZEREDRAW | CS_HITTEST | CS_MOVENOTIFY,
153 CS_SIZEREDRAW | CS_HITTEST,
154 NROF_WIN32WNDBYTES)) {
155 dprintf(("WinRegisterClass Win32BaseWindow failed"));
156 return(FALSE);
157 }
158
159 WinQueryWindowRect(HWND_DESKTOP, &desktopRectl);
160 ScreenWidth = desktopRectl.xRight;
161 ScreenHeight = desktopRectl.yTop;
162
163 dprintf(("InitPM: Desktop (%d,%d)", ScreenWidth, ScreenHeight));
164 return OSLibInitMsgQueue();
165} /* End of main */
166//******************************************************************************
167//Win32 window message handler
168//******************************************************************************
169MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
170{
171 POSTMSG_PACKET *postmsg;
172 OSLIBPOINT point, ClientPoint;
173 Win32BaseWindow *win32wnd;
174 APIRET rc;
175
176 //Restore our FS selector
177 SetWin32TIB();
178
179 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
180
181 if(msg != WM_CREATE && win32wnd == NULL) {
182 dprintf(("Invalid win32wnd pointer for window %x!!", hwnd));
183 goto RunDefWndProc;
184 }
185 if(msg > WIN32APP_USERMSGBASE) {
186 //win32 app user message
187 return (MRESULT)win32wnd->SendMessageA((ULONG)msg-WIN32APP_USERMSGBASE, (ULONG)mp1, (ULONG)mp2);
188 }
189 switch( msg )
190 {
191 //OS/2 msgs
192 case WM_CREATE:
193 {
194 THDB *thdb = GetThreadTHDB();
195
196 if(thdb == NULL || thdb->newWindow == 0)
197 goto createfail;
198
199 //Processing is done in after WinCreateWindow returns
200 dprintf(("OS2: WM_CREATE %x", hwnd));
201 win32wnd = (Win32BaseWindow *)thdb->newWindow;
202
203 if(win32wnd->MsgCreate(WinQueryWindow(hwnd, QW_PARENT), hwnd) == FALSE)
204 {
205 RestoreOS2TIB();
206 return (MRESULT)TRUE; //discontinue window creation
207 }
208 createfail:
209 RestoreOS2TIB();
210 return (MRESULT)FALSE;
211 }
212
213 case WM_QUIT:
214 dprintf(("OS2: WM_QUIT %x", hwnd));
215 if(win32wnd->MsgQuit()) {
216 goto RunDefWndProc;
217 }
218 break;
219
220 case WM_CLOSE:
221 dprintf(("OS2: WM_CLOSE %x", hwnd));
222// win32wnd->RemoveFakeOpen32();
223 if(win32wnd->MsgClose()) {
224 goto RunDefWndProc;
225 }
226 break;
227
228 case WM_DESTROY:
229 dprintf(("OS2: WM_DESTROY %x", hwnd));
230 if(win32wnd->MsgDestroy()) {
231 goto RunDefWndProc;
232 }
233 break;
234
235 case WM_ENABLE:
236 dprintf(("OS2: WM_ENABLE %x", hwnd));
237 if(win32wnd->MsgEnable(SHORT1FROMMP(mp1))) {
238 goto RunDefWndProc;
239 }
240 break;
241
242 case WM_SHOW:
243 dprintf(("OS2: WM_SHOW %x %d", hwnd, mp1));
244 if(win32wnd->MsgShow((ULONG)mp1)) {
245 goto RunDefWndProc;
246 }
247 break;
248
249#if 1
250 case WM_ADJUSTWINDOWPOS:
251 {
252 PSWP pswp = (PSWP)mp1;
253 SWP swpOld;
254 WINDOWPOS wp;
255 ULONG parentHeight = 0;
256 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE, hwndAfter;
257
258 dprintf(("OS2: WM_ADJUSTWINDOWPOS %x %x %x (%d,%d) (%d,%d)", hwnd, pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
259
260 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) goto RunDefWndProc;;
261
262 //SvL: TODO: Workaround. Why is this happening?
263 // When this flag is set the coordinates are 0, even though SWP_SIZE & SWP_MOVE are set.
264// if ((pswp->fl & SWP_NOADJUST)) goto RunDefWndProc;
265
266 if(!win32wnd->CanReceiveSizeMsgs()) goto RunDefWndProc;;
267
268 WinQueryWindowPos(hwnd, &swpOld);
269
270 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
271 if (win32wnd->isChild()) {
272 if(win32wnd->getParent()) {
273 hParent = win32wnd->getParent()->getOS2WindowHandle();
274 }
275 else goto RunDefWndProc;;
276 }
277 }
278 hwndAfter = pswp->hwndInsertBehind;
279 hFrame = win32wnd->getOS2FrameWindowHandle();
280 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, hParent, hFrame);
281
282 wp.hwnd = win32wnd->getWindowHandle();
283 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
284 {
285 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
286 if(wndAfter) wp.hwndInsertAfter = wndAfter->getWindowHandle();
287 }
288 if(win32wnd->MsgPosChanging((LPARAM)&wp) == 0)
289 {//app or default window handler changed wp
290 dprintf(("OS2: WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
291 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
292 OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, hParent, hFrame);
293 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
294 pswp->fl |= SWP_NOADJUST;
295 pswp->hwndInsertBehind = hwndAfter;
296 pswp->hwnd = hFrame;
297
298 WinSetMultWindowPos(GetThreadHAB(), pswp, 1);
299 return (MRESULT)0;
300 }
301 break;
302 }
303#endif
304
305 case WM_WINDOWPOSCHANGED:
306 {
307 PSWP pswp = (PSWP)mp1;
308 SWP swpOld = *(pswp + 1);
309 WINDOWPOS wp;
310 HWND hParent = NULLHANDLE;
311 LONG yDelta = pswp->cy - swpOld.cy;
312 LONG xDelta = pswp->cx - swpOld.cx;
313
314 dprintf(("OS2: WM_WINDOWPOSCHANGED %x %x (%d,%d) (%d,%d)", hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
315
316 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) break;
317 if (!win32wnd->CanReceiveSizeMsgs()) break;
318
319 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
320 if (win32wnd->isChild()) {
321 if(win32wnd->getParent()) {
322 hParent = win32wnd->getParent()->getOS2WindowHandle();
323 }
324 else goto RunDefWndProc; //parent has just been destroyed
325 }
326 }
327 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, hParent, hwnd);
328
329 win32wnd->setWindowRect(wp.x, wp.y, wp.x+wp.cx, wp.y+wp.cy);
330 win32wnd->setClientRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
331
332 wp.hwnd = win32wnd->getWindowHandle();
333 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
334 {
335 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
336 wp.hwndInsertAfter = wndAfter->getWindowHandle();
337 }
338
339 if (yDelta != 0 || xDelta != 0)
340 {
341 HENUM henum = WinBeginEnumWindows(pswp->hwnd);
342 SWP swp[10];
343 int i = 0;
344 HWND hwnd;
345
346 while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE)
347 {
348#if 0
349 if (mdiClient )
350 {
351 continue;
352 }
353#endif
354 WinQueryWindowPos(hwnd, &(swp[i]));
355
356#ifdef DEBUG
357 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
358 dprintf(("ENUMERATE %x delta %d (%d,%d) (%d,%d) %x", (window) ? window->getWindowHandle() : hwnd,
359 yDelta, swp[i].x, swp[i].y, swp[i].cx, swp[i].cy, swp[i].fl));
360#endif
361
362 if(swp[i].y != 0) {
363 //child window at offset <> 0 from client area -> offset now changes
364 swp[i].y += yDelta;
365 swp[i].fl &= ~(SWP_NOREDRAW);
366 }
367 //else child window with the same start coorindates as the client area
368 //The app should resize it.
369
370 if (i == 9)
371 {
372 WinSetMultWindowPos(GetThreadHAB(), swp, 10);
373 i = 0;
374 }
375 else
376 {
377 i++;
378 }
379 }
380
381 WinEndEnumWindows(henum);
382
383 if (i)
384 WinSetMultWindowPos(GetThreadHAB(), swp, i);
385 }
386 if (yDelta != 0)
387 {
388 POINT pt;
389 if(GetCaretPos (&pt) == TRUE)
390 {
391 pt.y -= yDelta;
392 SetCaretPos (pt.x, pt.y);
393 }
394 }
395 win32wnd->MsgPosChanged((LPARAM)&wp);
396
397 goto RunDefWndProc;
398 }
399
400 case WM_SIZE:
401 {
402 dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp2)));
403 break;
404 }
405
406 case WM_OWNERPOSCHANGE:
407 {
408 dprintf(("OS2: WM_OWNERPOSCHANGE"));
409 goto RunDefWndProc;
410 }
411
412 case WM_CALCVALIDRECTS:
413 {
414 dprintf(("OS2: WM_CALCVALIDRECTS"));
415 goto RunDefWndProc;
416 }
417
418 case WM_ACTIVATE:
419 {
420 HWND hwndActivate = (HWND)mp2;
421 BOOL fMinimized = FALSE;
422
423 dprintf(("OS2: WM_ACTIVATE %x %x", hwnd, hwndActivate));
424 if(WinQueryWindowULong(hwndActivate, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
425 //another (non-win32) application's window
426 //set to NULL (allowed according to win32 SDK) to avoid problems
427 hwndActivate = NULL;
428 }
429 if(WinQueryWindowULong(hwnd, QWL_STYLE) & WS_MINIMIZED)
430 {
431 fMinimized = TRUE;
432 }
433
434 if(win32wnd->MsgActivate(SHORT1FROMMP(mp1), fMinimized, Win32BaseWindow::OS2ToWin32Handle(hwndActivate))) {
435 goto RunDefWndProc;
436 }
437 break;
438 }
439 case WM_FOCUSCHANGE:
440 dprintf(("OS2: WM_FOCUSCHANGE %x", hwnd));
441 goto RunDefWndProc;
442
443 case WM_SETFOCUS:
444 {
445 HWND hwndFocus = (HWND)mp1;
446
447 dprintf(("OS2: WM_SETFOCUS %x %d", hwnd, mp2));
448 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
449 //another (non-win32) application's window
450 //set to NULL (allowed according to win32 SDK) to avoid problems
451 hwndFocus = NULL;
452 }
453 if((ULONG)mp2 == TRUE) {
454 HWND hwndFocusWin32 = Win32BaseWindow::OS2ToWin32Handle(hwndFocus);
455 recreateCaret (hwndFocusWin32);
456 rc = win32wnd->MsgSetFocus(hwndFocusWin32);
457 }
458 else rc = win32wnd->MsgKillFocus(Win32BaseWindow::OS2ToWin32Handle(hwndFocus));
459 if(rc) {
460 goto RunDefWndProc;
461 }
462 break;
463 }
464 //**************************************************************************
465 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
466 //**************************************************************************
467 case WM_BUTTON1DOWN:
468 dprintf(("OS2: WM_BUTTON1DOWN %x", hwnd));
469 point.x = (*(POINTS *)&mp1).x;
470 point.y = (*(POINTS *)&mp1).y;
471 ClientPoint.x = point.x;
472 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
473 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
474 if(win32wnd->MsgButton(BUTTON_LEFTDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
475 goto RunDefWndProc;
476 }
477 break;
478
479 case WM_BUTTON1UP:
480 dprintf(("OS2: WM_BUTTON1UP %x", hwnd));
481 point.x = (*(POINTS *)&mp1).x;
482 point.y = (*(POINTS *)&mp1).y;
483 ClientPoint.x = point.x;
484 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
485 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
486 if(win32wnd->MsgButton(BUTTON_LEFTUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
487 goto RunDefWndProc;
488 }
489 break;
490 case WM_BUTTON1DBLCLK:
491 point.x = (*(POINTS *)&mp1).x;
492 point.y = (*(POINTS *)&mp1).y;
493 ClientPoint.x = point.x;
494 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
495 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
496 if(win32wnd->MsgButton(BUTTON_LEFTDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
497 goto RunDefWndProc;
498 }
499 break;
500 case WM_BUTTON2DOWN:
501 point.x = (*(POINTS *)&mp1).x;
502 point.y = (*(POINTS *)&mp1).y;
503 ClientPoint.x = point.x;
504 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
505 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
506 if(win32wnd->MsgButton(BUTTON_RIGHTDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
507 goto RunDefWndProc;
508 }
509 break;
510 case WM_BUTTON2UP:
511 point.x = (*(POINTS *)&mp1).x;
512 point.y = (*(POINTS *)&mp1).y;
513 ClientPoint.x = point.x;
514 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
515 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
516 if(win32wnd->MsgButton(BUTTON_RIGHTUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
517 goto RunDefWndProc;
518 }
519 break;
520 case WM_BUTTON2DBLCLK:
521 point.x = (*(POINTS *)&mp1).x;
522 point.y = (*(POINTS *)&mp1).y;
523 ClientPoint.x = point.x;
524 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
525 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
526 if(win32wnd->MsgButton(BUTTON_RIGHTDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
527 goto RunDefWndProc;
528 }
529 break;
530 case WM_BUTTON3DOWN:
531 point.x = (*(POINTS *)&mp1).x;
532 point.y = (*(POINTS *)&mp1).y;
533 ClientPoint.x = point.x;
534 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
535 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
536 if(win32wnd->MsgButton(BUTTON_MIDDLEDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
537 goto RunDefWndProc;
538 }
539 break;
540 case WM_BUTTON3UP:
541 point.x = (*(POINTS *)&mp1).x;
542 point.y = (*(POINTS *)&mp1).y;
543 ClientPoint.x = point.x;
544 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
545 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
546 if(win32wnd->MsgButton(BUTTON_MIDDLEUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
547 goto RunDefWndProc;
548 }
549 break;
550 case WM_BUTTON3DBLCLK:
551 point.x = (*(POINTS *)&mp1).x;
552 point.y = (*(POINTS *)&mp1).y;
553 ClientPoint.x = point.x;
554 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
555 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
556 if(win32wnd->MsgButton(BUTTON_MIDDLEDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
557 goto RunDefWndProc;
558 }
559 break;
560
561 case WM_BUTTON2MOTIONSTART:
562 case WM_BUTTON2MOTIONEND:
563 case WM_BUTTON2CLICK:
564 case WM_BUTTON1MOTIONSTART:
565 case WM_BUTTON1MOTIONEND:
566 case WM_BUTTON1CLICK:
567 case WM_BUTTON3MOTIONSTART:
568 case WM_BUTTON3MOTIONEND:
569 case WM_BUTTON3CLICK:
570 goto RunDefWndProc;
571
572 case WM_MOUSEMOVE:
573 {
574 ULONG keystate = 0;
575 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON1))
576 keystate |= WMMOVE_LBUTTON;
577 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON2))
578 keystate |= WMMOVE_MBUTTON;
579 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON3))
580 keystate |= WMMOVE_RBUTTON;
581 if(WinGetKeyState(HWND_DESKTOP, VK_SHIFT))
582 keystate |= WMMOVE_SHIFT;
583 if(WinGetKeyState(HWND_DESKTOP, VK_CTRL))
584 keystate |= WMMOVE_CTRL;
585
586 //OS/2 Window coordinates -> Win32 Window coordinates
587 if(win32wnd->MsgMouseMove(keystate, SHORT1FROMMP(mp1), MapOS2ToWin32Y(win32wnd, SHORT2FROMMP(mp1))))
588 {
589 //Changes mouse cursor to default
590 goto RunDefWndProc;
591 }
592 break;
593 }
594
595 case WM_CONTROL:
596
597 case WM_COMMAND:
598 if(SHORT1FROMMP(mp2) == CMDSRC_MENU) {
599 win32wnd->MsgCommand(CMD_MENU, SHORT1FROMMP(mp1), 0);
600 }
601 if(SHORT1FROMMP(mp2) == CMDSRC_ACCELERATOR) {
602 win32wnd->MsgCommand(CMD_ACCELERATOR, SHORT1FROMMP(mp1), 0);
603 }
604 //todo controls + accelerators
605 break;
606
607 case WM_SYSCOMMAND:
608 {
609 ULONG x = 0, y = 0;
610 ULONG win32sc;
611
612 if(SHORT2FROMMP(mp2) == TRUE) {//syscommand caused by mouse action
613 POINTL pointl;
614 WinQueryPointerPos(HWND_DESKTOP, &pointl);
615 x = pointl.x;
616 y = ScreenHeight - y;
617 }
618 switch(SHORT1FROMMP(mp1)) {
619 case SC_MOVE:
620 win32sc = SC_MOVE_W;
621 break;
622 case SC_CLOSE:
623 win32sc = SC_CLOSE_W;
624 break;
625 case SC_MAXIMIZE:
626 win32sc = SC_MAXIMIZE_W;
627 break;
628 case SC_MINIMIZE:
629 win32sc = SC_MINIMIZE_W;
630 break;
631 case SC_NEXTFRAME:
632 case SC_NEXTWINDOW:
633 win32sc = SC_NEXTWINDOW_W;
634 break;
635 case SC_RESTORE:
636 win32sc = SC_RESTORE_W;
637 break;
638 case SC_TASKMANAGER:
639 win32sc = SC_TASKLIST_W;
640 break;
641 default:
642 goto RunDefWndProc;
643 }
644 dprintf(("WM_SYSCOMMAND %x %x (%d,%d)", hwnd, win32sc, x, y));
645 if(win32wnd->MsgSysCommand(win32sc, x, y)) {
646 goto RunDefWndProc;
647 }
648 break;
649 }
650 case WM_CHAR:
651 {
652 THDB *thdb;
653 ULONG repeatCount=0, virtualKey=0, keyFlags=0, scanCode=0;
654 ULONG flags = SHORT1FROMMP(mp1);
655 BOOL keyWasPressed, fTranslated = FALSE, fRunDefWndProc = FALSE;
656 char c;
657
658 repeatCount = CHAR3FROMMP(mp1);
659 scanCode = CHAR4FROMMP(mp1);
660 keyWasPressed = ((SHORT1FROMMP (mp1) & KC_PREVDOWN) == KC_PREVDOWN);
661
662 // both WM_KEYUP & WM_KEYDOWN want a virtual key, find the right Win32 virtual key
663 // given the OS/2 virtual key and OS/2 character
664
665 if (((SHORT1FROMMP (mp1) & KC_CHAR) == KC_CHAR) ||
666 ((SHORT1FROMMP (mp1) & KC_LONEKEY) == KC_LONEKEY))
667 {
668 c = SHORT1FROMMP (mp2);
669 if ((c >= 'A') && (c <= 'Z')) {
670 virtualKey = c;
671 goto VirtualKeyFound;
672 }
673 if ((c >='a') && (c <= 'z')) {
674 virtualKey = c - 32; // make it uppercase
675 goto VirtualKeyFound;
676 }
677 if ((c >= '0') && (c <= '9')) {
678 virtualKey = c;
679 goto VirtualKeyFound;
680 }
681 }
682
683 // convert OS/2 virtual keys to Win32 virtual key
684 if (SHORT2FROMMP (mp2) <= VK_BLK2)
685 virtualKey = virtualKeyTable [SHORT2FROMMP (mp2)];
686
687VirtualKeyFound:
688
689 if(!(SHORT1FROMMP(mp1) & KC_ALT))
690 {
691 //
692 // the Alt key is not pressed
693 //
694 if ((flags & KC_KEYUP) == KC_KEYUP) {
695 // send WM_KEYUP message
696
697 if(win32wnd->MsgKeyUp (repeatCount, scanCode, virtualKey)) {
698 fRunDefWndProc = TRUE;
699 }
700 }
701 else {
702 // send WM_KEYDOWN message
703 if (win32wnd->MsgKeyDown (repeatCount, scanCode, virtualKey, keyWasPressed))
704 fRunDefWndProc = TRUE;
705 }
706 }
707 else {
708 //
709 // the Alt key is pressed
710 //
711 if ((flags & KC_KEYUP) == KC_KEYUP) {
712 // send WM_SYSKEYUP message
713
714 if(win32wnd->MsgSysKeyUp (repeatCount, scanCode, virtualKey)) {
715 fRunDefWndProc = TRUE;
716 }
717 }
718 else {
719 // send WM_SYSKEYDOWN message
720 if (win32wnd->MsgSysKeyDown (repeatCount, scanCode, virtualKey, keyWasPressed))
721 fRunDefWndProc = TRUE;
722 }
723 }
724
725 thdb = GetThreadTHDB();
726 if(thdb) {
727 fTranslated = thdb->fMsgTranslated;
728 thdb->fMsgTranslated = FALSE; //reset flag
729 }
730 //NOTE: These actually need to be posted so that the next message retrieved by GetMessage contains
731 // the newly generated WM_CHAR message.
732 if(fTranslated && !((flags & KC_KEYUP) == KC_KEYUP)) {//TranslatedMessage was called before DispatchMessage, so send WM_CHAR messages
733 ULONG keyflags = 0, vkey = 0;
734 ULONG fl = SHORT1FROMMP(mp1);
735
736 if(!(fl & KC_CHAR)) {
737 goto RunDefWndProc;
738 }
739 if(fl & KC_VIRTUALKEY) {
740 vkey = SHORT2FROMMP(mp2);
741 }
742 if(fl & KC_KEYUP) {
743 keyflags |= KEY_UP;
744 }
745 if(fl & KC_ALT) {
746 keyflags |= KEY_ALTDOWN;
747 }
748 if(fl & KC_PREVDOWN) {
749 keyflags |= KEY_PREVDOWN;
750 }
751 if(fl & KC_DEADKEY) {
752 keyflags |= KEY_DEADKEY;
753 }
754 if(win32wnd->MsgChar(SHORT1FROMMP(mp2), CHAR3FROMMP(mp1), CHAR4FROMMP(mp1), virtualKey, keyflags)) {
755 goto RunDefWndProc;
756 }
757 }
758 if(fRunDefWndProc) goto RunDefWndProc;
759 break;
760 }
761
762 case WM_INITMENU:
763 case WM_MENUSELECT:
764 case WM_MENUEND:
765 case WM_NEXTMENU:
766 goto RunDefWndProc;
767
768 case WM_TIMER:
769 if (mp2) win32wnd->MsgTimer((ULONG)mp1);
770 goto RunDefWndProc;
771
772 case WM_SETWINDOWPARAMS:
773 {
774 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
775
776 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
777 if(wndParams->fsStatus & WPM_TEXT) {
778 if(win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText)) {
779 goto RunDefWndProc;
780 }
781 }
782 goto RunDefWndProc;
783 }
784
785 case WM_QUERYWINDOWPARAMS:
786 {
787 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
788 ULONG textlen;
789 PSZ wintext;
790
791 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
792 {
793 if(wndpars->fsStatus & WPM_CCHTEXT)
794 wndpars->cchText = win32wnd->MsgGetTextLength();
795 if(wndpars->fsStatus & WPM_TEXT)
796 wndpars->pszText = win32wnd->MsgGetText();
797
798 wndpars->fsStatus = 0;
799 wndpars->cbCtlData = 0;
800 wndpars->cbPresParams = 0;
801 RestoreOS2TIB();
802 return (MRESULT)TRUE;
803 }
804 goto RunDefWndProc;
805 }
806
807 case WM_ERASEBACKGROUND:
808 {
809 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
810 if (WinQueryUpdateRect (hwnd, NULL) && !win32wnd->isSupressErase()) {
811 BOOL erased = sendEraseBkgnd (win32wnd);
812 win32wnd->setEraseBkgnd (!erased, !erased);
813 }
814 break;
815 }
816
817 case WM_PAINT:
818 dprintf(("OS2: WM_PAINT %x", hwnd));
819
820 if (WinQueryUpdateRect (hwnd, NULL)) {
821 if (!win32wnd->isSupressErase()) {
822 BOOL erased = sendEraseBkgnd (win32wnd);
823 win32wnd->setEraseBkgnd (!erased, !erased);
824 }
825 }
826 win32wnd->setSupressErase (FALSE);
827
828 if(win32wnd->MsgPaint(0, 0)) {
829 goto RunDefWndProc;
830 }
831 break;
832
833 case WM_HITTEST:
834 // Only send this message if the window is enabled
835 if (WinIsWindowEnabled(hwnd))
836 {
837 if(win32wnd->MsgHitTest((*(POINTS *)&mp1).x, MapOS2ToWin32Y(OSLIB_HWND_DESKTOP, hwnd, (*(POINTS *)&mp1).y))) {
838 goto RunDefWndProc;
839 }
840 }
841 else goto RunDefWndProc;
842 break;
843
844 case WM_SYSCOLORCHANGE:
845 case WM_SYSVALUECHANGED:
846 case WM_SETSELECTION:
847 case WM_PPAINT:
848 case WM_PSETFOCUS:
849 case WM_PSYSCOLORCHANGE:
850 case WM_PSIZE:
851 case WM_PACTIVATE:
852 case WM_PCONTROL:
853 case WM_HELP:
854 case WM_APPTERMINATENOTIFY:
855 case WM_PRESPARAMCHANGED:
856 case WM_DRAWITEM:
857 case WM_MEASUREITEM:
858 case WM_CONTROLPOINTER:
859 case WM_QUERYDLGCODE:
860 case WM_SUBSTITUTESTRING:
861 case WM_MATCHMNEMONIC:
862 case WM_SAVEAPPLICATION:
863 case WM_SEMANTICEVENT:
864 default:
865// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
866 RestoreOS2TIB();
867 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
868 }
869 RestoreOS2TIB();
870 return (MRESULT)FALSE;
871
872RunDefWndProc:
873// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
874 RestoreOS2TIB();
875 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
876} /* End of Win32WindowProc */
877//******************************************************************************
878//******************************************************************************
879MRESULT EXPENTRY Win32SubclassWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
880{
881 Win32BaseWindow* win32wnd;
882
883 //Restore our FS selector
884 SetWin32TIB();
885
886 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
887
888 if (!win32wnd)
889 {
890 dprintf(("Invalid win32wnd pointer for subclassed window %x!!", hwnd));
891 goto RunDefWndProc;
892 }
893
894 switch (msg)
895 {
896 case WM_WINDOWPOSCHANGED:
897 {
898 PSWP pswp = (PSWP)mp1;
899 SWP swpOld = *(pswp + 1);
900 WINDOWPOS wp;
901 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE;
902
903 dprintf(("OS2Subclass: WM_WINDOWPOSCHANGED %x %x (%d,%d) (%d,%d)", hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
904 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) break;
905
906 hParent = hFrame = WinQueryWindow(hwnd, QW_PARENT);
907
908 OSLibMapSWPtoWINDOWPOS(pswp,&wp, &swpOld,hParent,hFrame);
909
910 win32wnd->setWindowRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
911 win32wnd->setClientRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
912 wp.x = swpOld.x;
913 wp.y = swpOld.y;
914 wp.cx = swpOld.cx;
915 wp.cy = swpOld.cy;
916
917 wp.hwnd = win32wnd->getWindowHandle();
918
919 win32wnd->MsgPosChanged((LPARAM)&wp);
920
921 goto RunOldWndProc;
922 }
923
924 default:
925 goto RunDefHandler;
926 }
927
928RunDefWndProc:
929 RestoreOS2TIB();
930 return WinDefWindowProc(hwnd,msg,mp1,mp2);
931
932RunOldWndProc:
933 RestoreOS2TIB();
934 return ((PFNWP)win32wnd->getOldWndProc())(hwnd,msg,mp1,mp2);
935
936RunDefHandler:
937 RestoreOS2TIB();
938 return Win32WindowProc(hwnd,msg,mp1,mp2);
939}
940
941PVOID SubclassWithDefHandler(HWND hwnd)
942{
943 return WinSubclassWindow(hwnd,Win32SubclassWindowProc);
944}
Note: See TracBrowser for help on using the repository browser.