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

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

FS bugfixes

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