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

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

wm_adjustwindowpos & combobox fixes

File size: 31.3 KB
Line 
1/* $Id: pmwindow.cpp,v 1.39 1999-10-21 12:19:27 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 case WM_ADJUSTWINDOWPOS:
250 {
251 PSWP pswp = (PSWP)mp1;
252 SWP swpOld;
253 WINDOWPOS wp;
254 ULONG parentHeight = 0;
255 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE, hwndAfter;
256
257 dprintf(("OS2: WM_ADJUSTWINDOWPOS %x %x %x (%d,%d) (%d,%d)", hwnd, pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
258
259 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) goto RunDefWndProc;;
260
261 //SvL: TODO: Workaround. Why is this happening?
262 // When this flag is set the coordinates are 0, even though SWP_SIZE & SWP_MOVE are set.
263// if ((pswp->fl & SWP_NOADJUST)) goto RunDefWndProc;
264
265 if(!win32wnd->CanReceiveSizeMsgs()) goto RunDefWndProc;;
266
267 WinQueryWindowPos(hwnd, &swpOld);
268
269 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
270 if (win32wnd->isChild()) {
271 if(win32wnd->getParent()) {
272 hParent = win32wnd->getParent()->getOS2WindowHandle();
273 }
274 else goto RunDefWndProc;;
275 }
276 }
277 hwndAfter = pswp->hwndInsertBehind;
278 hFrame = win32wnd->getOS2FrameWindowHandle();
279 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, hParent, hFrame);
280
281 wp.hwnd = win32wnd->getWindowHandle();
282 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
283 {
284 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
285 if(wndAfter) wp.hwndInsertAfter = wndAfter->getWindowHandle();
286 }
287 if(win32wnd->MsgPosChanging((LPARAM)&wp) == 0)
288 {//app or default window handler changed wp
289 dprintf(("OS2: WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
290 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
291 OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, hParent, hFrame);
292 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
293 pswp->fl |= SWP_NOADJUST;
294 pswp->hwndInsertBehind = hwndAfter;
295 pswp->hwnd = hFrame;
296
297 WinSetMultWindowPos(GetThreadHAB(), pswp, 1);
298 return (MRESULT)0;
299 }
300 break;
301 }
302
303 case WM_WINDOWPOSCHANGED:
304 {
305 PSWP pswp = (PSWP)mp1;
306 SWP swpOld = *(pswp + 1);
307 WINDOWPOS wp;
308 ULONG parentHeight = 0;
309 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE;
310 LONG yDelta = pswp->cy - swpOld.cy;
311 LONG xDelta = pswp->cx - swpOld.cx;
312
313 dprintf(("OS2: WM_WINDOWPOSCHANGED (%x) %x %x (%d,%d) (%d,%d)", mp2, hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
314
315 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) break;
316 if(!win32wnd->CanReceiveSizeMsgs()) break;
317
318 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
319 if (win32wnd->isChild()) {
320 if(win32wnd->getParent()) {
321 hParent = win32wnd->getParent()->getOS2WindowHandle();
322 }
323 else goto RunDefWndProc; //parent has just been destroyed
324 }
325 }
326 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, hParent, hwnd);
327
328 win32wnd->setWindowRect(wp.x, wp.y, wp.x+wp.cx, wp.y+wp.cy);
329 win32wnd->setClientRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
330
331 wp.hwnd = win32wnd->getWindowHandle();
332 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
333 {
334 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
335 wp.hwndInsertAfter = wndAfter->getWindowHandle();
336 }
337
338 if (yDelta != 0 || xDelta != 0)
339 {
340 HENUM henum = WinBeginEnumWindows(pswp->hwnd);
341 SWP swp[10];
342 int i = 0;
343 HWND hwnd;
344
345 while ((hwnd = WinGetNextWindow(henum)) != NULLHANDLE)
346 {
347#if 0
348 if (mdiClient )
349 {
350 continue;
351 }
352#endif
353 WinQueryWindowPos(hwnd, &(swp[i]));
354
355#ifdef DEBUG
356 Win32BaseWindow *window = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
357 dprintf(("ENUMERATE %x delta %d (%d,%d) (%d,%d) %x", (window) ? window->getWindowHandle() : hwnd,
358 yDelta, swp[i].x, swp[i].y, swp[i].cx, swp[i].cy, swp[i].fl));
359#endif
360
361 if(swp[i].y != 0) {
362 //child window at offset <> 0 from client area -> offset now changes
363 swp[i].y += yDelta;
364 swp[i].fl &= ~(SWP_NOREDRAW);
365 }
366 //else child window with the same start coorindates as the client area
367 //The app should resize it.
368
369 if (i == 9)
370 {
371 WinSetMultWindowPos(GetThreadHAB(), swp, 10);
372 i = 0;
373 }
374 else
375 {
376 i++;
377 }
378 }
379
380 WinEndEnumWindows(henum);
381
382 if (i)
383 WinSetMultWindowPos(GetThreadHAB(), swp, i);
384 }
385 if (yDelta != 0)
386 {
387 POINT pt;
388 if(GetCaretPos (&pt) == TRUE)
389 {
390 pt.y -= yDelta;
391 SetCaretPos (pt.x, pt.y);
392 }
393 }
394 win32wnd->MsgPosChanged((LPARAM)&wp);
395
396 goto RunDefWndProc;
397 }
398
399 case WM_SIZE:
400 {
401 dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp2)));
402 break;
403 }
404
405 case WM_OWNERPOSCHANGE:
406 {
407 dprintf(("OS2: WM_OWNERPOSCHANGE"));
408 goto RunDefWndProc;
409 }
410
411 case WM_CALCVALIDRECTS:
412 {
413 dprintf(("OS2: WM_CALCVALIDRECTS"));
414 goto RunDefWndProc;
415 }
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 case WM_FOCUSCHANGE:
439 dprintf(("OS2: WM_FOCUSCHANGE %x", hwnd));
440 goto RunDefWndProc;
441
442 case WM_SETFOCUS:
443 {
444 HWND hwndFocus = (HWND)mp1;
445
446 dprintf(("OS2: WM_SETFOCUS %x %d", hwnd, mp2));
447 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
448 //another (non-win32) application's window
449 //set to NULL (allowed according to win32 SDK) to avoid problems
450 hwndFocus = NULL;
451 }
452 if((ULONG)mp2 == TRUE) {
453 HWND hwndFocusWin32 = Win32BaseWindow::OS2ToWin32Handle(hwndFocus);
454 recreateCaret (hwndFocusWin32);
455 rc = win32wnd->MsgSetFocus(hwndFocusWin32);
456 }
457 else rc = win32wnd->MsgKillFocus(Win32BaseWindow::OS2ToWin32Handle(hwndFocus));
458 if(rc) {
459 goto RunDefWndProc;
460 }
461 break;
462 }
463 //**************************************************************************
464 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
465 //**************************************************************************
466 case WM_BUTTON1DOWN:
467 dprintf(("OS2: WM_BUTTON1DOWN %x", hwnd));
468 point.x = (*(POINTS *)&mp1).x;
469 point.y = (*(POINTS *)&mp1).y;
470 ClientPoint.x = point.x;
471 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
472 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
473 if(win32wnd->MsgButton(BUTTON_LEFTDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
474 goto RunDefWndProc;
475 }
476 break;
477
478 case WM_BUTTON1UP:
479 dprintf(("OS2: WM_BUTTON1UP %x", hwnd));
480 point.x = (*(POINTS *)&mp1).x;
481 point.y = (*(POINTS *)&mp1).y;
482 ClientPoint.x = point.x;
483 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
484 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
485 if(win32wnd->MsgButton(BUTTON_LEFTUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
486 goto RunDefWndProc;
487 }
488 break;
489 case WM_BUTTON1DBLCLK:
490 point.x = (*(POINTS *)&mp1).x;
491 point.y = (*(POINTS *)&mp1).y;
492 ClientPoint.x = point.x;
493 ClientPoint.y = MapOS2ToWin32Y(hwnd, 1, point.y);
494 MapOS2ToWin32Point(OSLIB_HWND_DESKTOP, hwnd, &point);
495 if(win32wnd->MsgButton(BUTTON_LEFTDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
496 goto RunDefWndProc;
497 }
498 break;
499 case WM_BUTTON2DOWN:
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_RIGHTDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
506 goto RunDefWndProc;
507 }
508 break;
509 case WM_BUTTON2UP:
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_RIGHTUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
516 goto RunDefWndProc;
517 }
518 break;
519 case WM_BUTTON2DBLCLK:
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_RIGHTDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
526 goto RunDefWndProc;
527 }
528 break;
529 case WM_BUTTON3DOWN:
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_MIDDLEDOWN, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
536 goto RunDefWndProc;
537 }
538 break;
539 case WM_BUTTON3UP:
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_MIDDLEUP, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
546 goto RunDefWndProc;
547 }
548 break;
549 case WM_BUTTON3DBLCLK:
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_MIDDLEDBLCLICK, point.x, point.y, ClientPoint.x, ClientPoint.y)) {
556 goto RunDefWndProc;
557 }
558 break;
559
560 case WM_BUTTON2MOTIONSTART:
561 case WM_BUTTON2MOTIONEND:
562 case WM_BUTTON2CLICK:
563 case WM_BUTTON1MOTIONSTART:
564 case WM_BUTTON1MOTIONEND:
565 case WM_BUTTON1CLICK:
566 case WM_BUTTON3MOTIONSTART:
567 case WM_BUTTON3MOTIONEND:
568 case WM_BUTTON3CLICK:
569 goto RunDefWndProc;
570
571 case WM_MOUSEMOVE:
572 {
573 ULONG keystate = 0;
574 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON1))
575 keystate |= WMMOVE_LBUTTON;
576 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON2))
577 keystate |= WMMOVE_MBUTTON;
578 if(WinGetKeyState(HWND_DESKTOP, VK_BUTTON3))
579 keystate |= WMMOVE_RBUTTON;
580 if(WinGetKeyState(HWND_DESKTOP, VK_SHIFT))
581 keystate |= WMMOVE_SHIFT;
582 if(WinGetKeyState(HWND_DESKTOP, VK_CTRL))
583 keystate |= WMMOVE_CTRL;
584
585 //OS/2 Window coordinates -> Win32 Window coordinates
586 if(win32wnd->MsgMouseMove(keystate, SHORT1FROMMP(mp1), MapOS2ToWin32Y(win32wnd, SHORT2FROMMP(mp1))))
587 {
588 //Changes mouse cursor to default
589 goto RunDefWndProc;
590 }
591 break;
592 }
593
594 case WM_CONTROL:
595
596 case WM_COMMAND:
597 if(SHORT1FROMMP(mp2) == CMDSRC_MENU) {
598 win32wnd->MsgCommand(CMD_MENU, SHORT1FROMMP(mp1), 0);
599 }
600 if(SHORT1FROMMP(mp2) == CMDSRC_ACCELERATOR) {
601 win32wnd->MsgCommand(CMD_ACCELERATOR, SHORT1FROMMP(mp1), 0);
602 }
603 //todo controls + accelerators
604 break;
605
606 case WM_SYSCOMMAND:
607 {
608 ULONG x = 0, y = 0;
609 ULONG win32sc;
610
611 if(SHORT2FROMMP(mp2) == TRUE) {//syscommand caused by mouse action
612 POINTL pointl;
613 WinQueryPointerPos(HWND_DESKTOP, &pointl);
614 x = pointl.x;
615 y = ScreenHeight - y;
616 }
617 switch(SHORT1FROMMP(mp1)) {
618 case SC_MOVE:
619 win32sc = SC_MOVE_W;
620 break;
621 case SC_CLOSE:
622 win32sc = SC_CLOSE_W;
623 break;
624 case SC_MAXIMIZE:
625 win32sc = SC_MAXIMIZE_W;
626 break;
627 case SC_MINIMIZE:
628 win32sc = SC_MINIMIZE_W;
629 break;
630 case SC_NEXTFRAME:
631 case SC_NEXTWINDOW:
632 win32sc = SC_NEXTWINDOW_W;
633 break;
634 case SC_RESTORE:
635 win32sc = SC_RESTORE_W;
636 break;
637 case SC_TASKMANAGER:
638 win32sc = SC_TASKLIST_W;
639 break;
640 default:
641 goto RunDefWndProc;
642 }
643 dprintf(("WM_SYSCOMMAND %x %x (%d,%d)", hwnd, win32sc, x, y));
644 if(win32wnd->MsgSysCommand(win32sc, x, y)) {
645 goto RunDefWndProc;
646 }
647 break;
648 }
649 case WM_CHAR:
650 {
651 THDB *thdb;
652 ULONG repeatCount=0, virtualKey=0, keyFlags=0, scanCode=0;
653 ULONG flags = SHORT1FROMMP(mp1);
654 BOOL keyWasPressed, fTranslated = FALSE, fRunDefWndProc = FALSE;
655 char c;
656
657 repeatCount = CHAR3FROMMP(mp1);
658 scanCode = CHAR4FROMMP(mp1);
659 keyWasPressed = ((SHORT1FROMMP (mp1) & KC_PREVDOWN) == KC_PREVDOWN);
660
661 // both WM_KEYUP & WM_KEYDOWN want a virtual key, find the right Win32 virtual key
662 // given the OS/2 virtual key and OS/2 character
663
664 if (((SHORT1FROMMP (mp1) & KC_CHAR) == KC_CHAR) ||
665 ((SHORT1FROMMP (mp1) & KC_LONEKEY) == KC_LONEKEY))
666 {
667 c = SHORT1FROMMP (mp2);
668 if ((c >= 'A') && (c <= 'Z')) {
669 virtualKey = c;
670 goto VirtualKeyFound;
671 }
672 if ((c >='a') && (c <= 'z')) {
673 virtualKey = c - 32; // make it uppercase
674 goto VirtualKeyFound;
675 }
676 if ((c >= '0') && (c <= '9')) {
677 virtualKey = c;
678 goto VirtualKeyFound;
679 }
680 }
681
682 // convert OS/2 virtual keys to Win32 virtual key
683 if (SHORT2FROMMP (mp2) <= VK_BLK2)
684 virtualKey = virtualKeyTable [SHORT2FROMMP (mp2)];
685
686VirtualKeyFound:
687
688 if(!(SHORT1FROMMP(mp1) & KC_ALT))
689 {
690 //
691 // the Alt key is not pressed
692 //
693 if ((flags & KC_KEYUP) == KC_KEYUP) {
694 // send WM_KEYUP message
695
696 if(win32wnd->MsgKeyUp (repeatCount, scanCode, virtualKey)) {
697 fRunDefWndProc = TRUE;
698 }
699 }
700 else {
701 // send WM_KEYDOWN message
702 if (win32wnd->MsgKeyDown (repeatCount, scanCode, virtualKey, keyWasPressed))
703 fRunDefWndProc = TRUE;
704 }
705 }
706 else {
707 //
708 // the Alt key is pressed
709 //
710 if ((flags & KC_KEYUP) == KC_KEYUP) {
711 // send WM_SYSKEYUP message
712
713 if(win32wnd->MsgSysKeyUp (repeatCount, scanCode, virtualKey)) {
714 fRunDefWndProc = TRUE;
715 }
716 }
717 else {
718 // send WM_SYSKEYDOWN message
719 if (win32wnd->MsgSysKeyDown (repeatCount, scanCode, virtualKey, keyWasPressed))
720 fRunDefWndProc = TRUE;
721 }
722 }
723
724 thdb = GetThreadTHDB();
725 if(thdb) {
726 fTranslated = thdb->fMsgTranslated;
727 thdb->fMsgTranslated = FALSE; //reset flag
728 }
729 //NOTE: These actually need to be posted so that the next message retrieved by GetMessage contains
730 // the newly generated WM_CHAR message.
731 if(fTranslated && !((flags & KC_KEYUP) == KC_KEYUP)) {//TranslatedMessage was called before DispatchMessage, so send WM_CHAR messages
732 ULONG keyflags = 0, vkey = 0;
733 ULONG fl = SHORT1FROMMP(mp1);
734
735 if(!(fl & KC_CHAR)) {
736 goto RunDefWndProc;
737 }
738 if(fl & KC_VIRTUALKEY) {
739 vkey = SHORT2FROMMP(mp2);
740 }
741 if(fl & KC_KEYUP) {
742 keyflags |= KEY_UP;
743 }
744 if(fl & KC_ALT) {
745 keyflags |= KEY_ALTDOWN;
746 }
747 if(fl & KC_PREVDOWN) {
748 keyflags |= KEY_PREVDOWN;
749 }
750 if(fl & KC_DEADKEY) {
751 keyflags |= KEY_DEADKEY;
752 }
753 if(win32wnd->MsgChar(SHORT1FROMMP(mp2), CHAR3FROMMP(mp1), CHAR4FROMMP(mp1), virtualKey, keyflags)) {
754 goto RunDefWndProc;
755 }
756 }
757 if(fRunDefWndProc) goto RunDefWndProc;
758 break;
759 }
760
761 case WM_INITMENU:
762 case WM_MENUSELECT:
763 case WM_MENUEND:
764 case WM_NEXTMENU:
765 goto RunDefWndProc;
766
767 case WM_TIMER:
768 if (mp2) win32wnd->MsgTimer((ULONG)mp1);
769 goto RunDefWndProc;
770
771 case WM_SETWINDOWPARAMS:
772 {
773 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
774
775 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
776 if(wndParams->fsStatus & WPM_TEXT) {
777 if(win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText)) {
778 goto RunDefWndProc;
779 }
780 }
781 goto RunDefWndProc;
782 }
783
784 case WM_QUERYWINDOWPARAMS:
785 {
786 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
787 ULONG textlen;
788 PSZ wintext;
789
790 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
791 {
792 if(wndpars->fsStatus & WPM_CCHTEXT)
793 wndpars->cchText = win32wnd->MsgGetTextLength();
794 if(wndpars->fsStatus & WPM_TEXT)
795 wndpars->pszText = win32wnd->MsgGetText();
796
797 wndpars->fsStatus = 0;
798 wndpars->cbCtlData = 0;
799 wndpars->cbPresParams = 0;
800 RestoreOS2TIB();
801 return (MRESULT)TRUE;
802 }
803 goto RunDefWndProc;
804 }
805
806 case WM_ERASEBACKGROUND:
807 {
808 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
809 if (WinQueryUpdateRect (hwnd, NULL) && !win32wnd->isSupressErase()) {
810 BOOL erased = sendEraseBkgnd (win32wnd);
811 win32wnd->setEraseBkgnd (!erased, !erased);
812 }
813 break;
814 }
815
816 case WM_PAINT:
817 dprintf(("OS2: WM_PAINT %x", hwnd));
818
819 if (WinQueryUpdateRect (hwnd, NULL)) {
820 if (!win32wnd->isSupressErase()) {
821 BOOL erased = sendEraseBkgnd (win32wnd);
822 win32wnd->setEraseBkgnd (!erased, !erased);
823 }
824 }
825 win32wnd->setSupressErase (FALSE);
826
827 if(win32wnd->MsgPaint(0, 0)) {
828 goto RunDefWndProc;
829 }
830 break;
831
832 case WM_HITTEST:
833 // Only send this message if the window is enabled
834 if (WinIsWindowEnabled(hwnd))
835 {
836 if(win32wnd->MsgHitTest((*(POINTS *)&mp1).x, MapOS2ToWin32Y(OSLIB_HWND_DESKTOP, hwnd, (*(POINTS *)&mp1).y))) {
837 goto RunDefWndProc;
838 }
839 }
840 else goto RunDefWndProc;
841 break;
842
843 case WM_SYSCOLORCHANGE:
844 case WM_SYSVALUECHANGED:
845 case WM_SETSELECTION:
846 case WM_PPAINT:
847 case WM_PSETFOCUS:
848 case WM_PSYSCOLORCHANGE:
849 case WM_PSIZE:
850 case WM_PACTIVATE:
851 case WM_PCONTROL:
852 case WM_HELP:
853 case WM_APPTERMINATENOTIFY:
854 case WM_PRESPARAMCHANGED:
855 case WM_DRAWITEM:
856 case WM_MEASUREITEM:
857 case WM_CONTROLPOINTER:
858 case WM_QUERYDLGCODE:
859 case WM_SUBSTITUTESTRING:
860 case WM_MATCHMNEMONIC:
861 case WM_SAVEAPPLICATION:
862 case WM_SEMANTICEVENT:
863 default:
864// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
865 RestoreOS2TIB();
866 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
867 }
868 RestoreOS2TIB();
869 return (MRESULT)FALSE;
870
871RunDefWndProc:
872// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
873 RestoreOS2TIB();
874 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
875} /* End of Win32WindowProc */
876//******************************************************************************
877//******************************************************************************
878MRESULT EXPENTRY Win32SubclassWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
879{
880 Win32BaseWindow* win32wnd;
881
882 //Restore our FS selector
883 SetWin32TIB();
884
885 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
886
887 if (!win32wnd)
888 {
889 dprintf(("Invalid win32wnd pointer for subclassed window %x!!", hwnd));
890 goto RunDefWndProc;
891 }
892
893 switch (msg)
894 {
895 case WM_WINDOWPOSCHANGED:
896 {
897 PSWP pswp = (PSWP)mp1;
898 SWP swpOld = *(pswp + 1);
899 WINDOWPOS wp;
900 HWND hParent = NULLHANDLE, hFrame = NULLHANDLE;
901
902 dprintf(("OS2Subclass: WM_WINDOWPOSCHANGED %x %x (%d,%d) (%d,%d)", hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
903 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0) break;
904
905 hParent = hFrame = WinQueryWindow(hwnd, QW_PARENT);
906
907 OSLibMapSWPtoWINDOWPOS(pswp,&wp, &swpOld,hParent,hFrame);
908
909 win32wnd->setWindowRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
910 win32wnd->setClientRect(swpOld.x, swpOld.y, swpOld.x + swpOld.cx, swpOld.y + swpOld.cy);
911 wp.x = swpOld.x;
912 wp.y = swpOld.y;
913 wp.cx = swpOld.cx;
914 wp.cy = swpOld.cy;
915
916 wp.hwnd = win32wnd->getWindowHandle();
917
918 win32wnd->MsgPosChanged((LPARAM)&wp);
919
920 goto RunOldWndProc;
921 }
922
923 default:
924 goto RunDefHandler;
925 }
926
927RunDefWndProc:
928 RestoreOS2TIB();
929 return WinDefWindowProc(hwnd,msg,mp1,mp2);
930
931RunOldWndProc:
932 RestoreOS2TIB();
933 return ((PFNWP)win32wnd->getOldWndProc())(hwnd,msg,mp1,mp2);
934
935RunDefHandler:
936 RestoreOS2TIB();
937 return Win32WindowProc(hwnd,msg,mp1,mp2);
938}
939
940PVOID SubclassWithDefHandler(HWND hwnd)
941{
942 return WinSubclassWindow(hwnd,Win32SubclassWindowProc);
943}
Note: See TracBrowser for help on using the repository browser.