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

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

Dinput additions + PostThreadMessageA/W fix

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