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

Last change on this file since 4945 was 4945, checked in by sandervl, 25 years ago

listbox, combobox and notifyframe fixes

File size: 40.1 KB
Line 
1/* $Id: pmwindow.cpp,v 1.112 2001-01-14 17:15:46 sandervl Exp $ */
2/*
3 * Win32 Window Managment Code for OS/2
4 *
5 * Copyright 1998-2000 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#define INCL_DEV /* Device Function definitions */
15#define INCL_GPICONTROL /* GPI control Functions */
16#define INCL_DOSPROCESS
17#define INCL_WINTRACKRECT
18
19#include <os2wrap.h>
20#include <stdlib.h>
21#include <string.h>
22#include <win32type.h>
23#include <winconst.h>
24#include <winuser32.h>
25#include <wprocess.h>
26#include <misc.h>
27#include <win32wbase.h>
28#include <win32dlg.h>
29#include "win32wdesktop.h"
30#include "pmwindow.h"
31#include "oslibwin.h"
32#include "oslibutil.h"
33#include "oslibgdi.h"
34#include "oslibmsg.h"
35#include "dc.h"
36#include <thread.h>
37#include <wprocess.h>
38#include "caret.h"
39#include "timer.h"
40#include <codepage.h>
41
42#define DBG_LOCALLOG DBG_pmwindow
43#include "dbglocal.h"
44
45HMQ hmq = 0; /* Message queue handle */
46HAB hab = 0;
47
48RECTL desktopRectl = {0};
49ULONG ScreenWidth = 0;
50ULONG ScreenHeight = 0;
51ULONG ScreenBitsPerPel = 0;
52
53static PFNWP pfnFrameWndProc = NULL;
54
55MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
56MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
57MRESULT ProcessPMMessage(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, Win32BaseWindow *win32wnd,
58 MSG *pWinMsg, TEB *teb, BOOL isFrame);
59
60//******************************************************************************
61//Initialize PM; create hab, message queue and register special Win32 window classes
62//******************************************************************************
63BOOL InitPM()
64{
65
66 hab = WinInitialize(0);
67 dprintf(("Winitialize returned %x", hab));
68 hmq = WinCreateMsgQueue(hab, 0);
69
70 if(!hab || !hmq)
71 {
72 UINT error;
73 //CB: only fail on real error
74 error = WinGetLastError(hab) & 0xFFFF; //error code
75 if (!hab || (error != PMERR_MSG_QUEUE_ALREADY_EXISTS))
76 {
77 dprintf(("WinInitialize or WinCreateMsgQueue failed %x %x", hab, hmq));
78 dprintf((" Error = %x",error));
79 return(FALSE);
80 }
81 else
82 {
83 if(!hab) {
84 hab = WinQueryAnchorBlock(HWND_DESKTOP);
85 dprintf(("WinQueryAnchorBlock returned %x", hab));
86 }
87 if(!hmq) {
88 hmq = HMQ_CURRENT;
89 }
90 }
91 }
92 SetThreadHAB(hab);
93 dprintf(("InitPM: hmq = %x", hmq));
94 SetThreadMessageQueue(hmq);
95
96 BOOL rc = WinSetCp(hmq, GetDisplayCodepage());
97 dprintf(("InitPM: WinSetCP was %sOK", rc ? "" : "not "));
98
99 if(!WinRegisterClass( /* Register window class */
100 hab, /* Anchor block handle */
101 (PSZ)WIN32_STDCLASS, /* Window class name */
102 (PFNWP)Win32WindowProc, /* Address of window procedure */
103 CS_HITTEST,
104 NROF_WIN32WNDBYTES))
105 {
106 dprintf(("WinRegisterClass Win32BaseWindow failed"));
107 return(FALSE);
108 }
109
110 CLASSINFO FrameClassInfo;
111 if(!WinQueryClassInfo (hab, WC_FRAME, &FrameClassInfo)) {
112 dprintf (("WinQueryClassInfo WC_FRAME failed"));
113 return (FALSE);
114 }
115 pfnFrameWndProc = FrameClassInfo.pfnWindowProc;
116
117 dprintf(("WC_FRAME style %x", FrameClassInfo.flClassStyle));
118
119 if(!WinRegisterClass( /* Register window class */
120 hab, /* Anchor block handle */
121 (PSZ)WIN32_STDFRAMECLASS, /* Window class name */
122 (PFNWP)Win32FrameWindowProc, /* Address of window procedure */
123 CS_HITTEST | CS_FRAME,
124 FrameClassInfo.cbWindowData+NROF_WIN32WNDBYTES))
125 {
126 dprintf(("WinRegisterClass Win32BaseWindow failed %x", WinGetLastError(hab)));
127 return(FALSE);
128 }
129
130 WinQueryWindowRect(HWND_DESKTOP, &desktopRectl);
131 ScreenWidth = desktopRectl.xRight;
132 ScreenHeight = desktopRectl.yTop;
133
134 HDC hdc; /* Device-context handle */
135 /* context data structure */
136 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
137 NULL, NULL, NULL};
138
139 /* create memory device context */
140 hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
141 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, (PLONG)&ScreenBitsPerPel);
142 DevCloseDC(hdc);
143
144 dprintf(("InitPM: Desktop (%d,%d)", ScreenWidth, ScreenHeight));
145 return TRUE;
146} /* End of main */
147//******************************************************************************
148//Win32 window message handler
149//******************************************************************************
150MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
151{
152 Win32BaseWindow *win32wnd;
153 TEB *teb;
154 MSG winMsg, *pWinMsg;
155 MRESULT rc = 0;
156
157 //Restore our FS selector
158 SetWin32TIB();
159
160 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- BEGIN
161 teb = GetThreadTEB();
162 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
163
164 if(!teb || (msg != WM_CREATE && win32wnd == NULL)) {
165 dprintf(("Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
166 goto RunDefWndProc;
167 }
168//// if(teb->o.odin.fIgnoreMsgs) {
169//// goto RunDefWndProc;
170//// }
171
172 if((teb->o.odin.msgstate & 1) == 0)
173 {//message that was sent directly to our window proc handler; translate it here
174 QMSG qmsg;
175
176 qmsg.msg = msg;
177 qmsg.hwnd = hwnd;
178 qmsg.mp1 = mp1;
179 qmsg.mp2 = mp2;
180 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
181 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
182 qmsg.reserved = 0;
183
184 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
185 {//message was not translated
186 memset(&winMsg, 0, sizeof(MSG));
187 }
188 pWinMsg = &winMsg;
189 }
190 else {
191 pWinMsg = &teb->o.odin.msg;
192 teb->o.odin.msgstate++;
193 }
194 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- END
195 rc = ProcessPMMessage(hwnd, msg, mp1, mp2, win32wnd, pWinMsg, teb, FALSE);
196 RestoreOS2TIB();
197 return rc;
198
199RunDefWndProc:
200 RestoreOS2TIB();
201 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
202}
203//******************************************************************************
204//******************************************************************************
205MRESULT ProcessPMMessage(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2, Win32BaseWindow *win32wnd, MSG *pWinMsg, TEB *teb, BOOL isFrame)
206{
207 POSTMSG_PACKET *postmsg;
208 OSLIBPOINT point, ClientPoint;
209 MRESULT rc = 0;
210
211 if(msg == WIN32APP_POSTMSG) {
212 //probably win32 app user message
213 if((ULONG)mp1 == WIN32MSG_MAGICA) {
214 return (MRESULT)win32wnd->DispatchMsgA(pWinMsg);
215 }
216 else
217 if((ULONG)mp1 == WIN32MSG_MAGICW) {
218 return (MRESULT)win32wnd->DispatchMsgW(pWinMsg);
219 }
220 }
221
222 switch( msg )
223 {
224 //OS/2 msgs
225 case WM_CREATE:
226 {
227 if(teb->o.odin.newWindow == 0)
228 goto createfail;
229
230 //Processing is done in after WinCreateWindow returns
231 dprintf(("OS2: WM_CREATE %x", hwnd));
232 win32wnd = (Win32BaseWindow *)teb->o.odin.newWindow;
233 teb->o.odin.newWindow = 0;
234 if(win32wnd->MsgCreate(hwnd) == FALSE)
235 {
236 return (MRESULT)TRUE; //discontinue window creation
237 }
238 createfail:
239 return (MRESULT)FALSE;
240 }
241
242 case WM_QUIT:
243 dprintf(("OS2: WM_QUIT %x", hwnd));
244 win32wnd->MsgQuit();
245 break;
246
247 case WM_CLOSE:
248 dprintf(("OS2: WM_CLOSE %x", hwnd));
249 win32wnd->MsgClose();
250 break;
251
252 case WM_DESTROY:
253 dprintf(("OS2: WM_DESTROY %x", hwnd));
254 win32wnd->MsgDestroy();
255 WinSetVisibleRegionNotify(hwnd, FALSE);
256 goto RunDefWndProc;
257
258 case WM_ENABLE:
259 dprintf(("OS2: WM_ENABLE %x", hwnd));
260 win32wnd->MsgEnable(SHORT1FROMMP(mp1));
261 break;
262
263 case WM_SHOW:
264 dprintf(("OS2: WM_SHOW %x %d", hwnd, mp1));
265 win32wnd->MsgShow((ULONG)mp1);
266 break;
267
268 case WM_ADJUSTWINDOWPOS:
269 {
270 PSWP pswp = (PSWP)mp1;
271 SWP swpOld;
272 WINDOWPOS wp,wpOld;
273 HWND hParent = NULLHANDLE, hwndAfter;
274
275 dprintf(("OS2: WM_ADJUSTWINDOWPOS %x %x %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
276
277 if(pswp->fl & SWP_NOADJUST) {
278 //ignore weird messages (TODO: why are they sent?)
279 break;
280 }
281 //CB: show dialog in front of owner
282 if (win32wnd->IsModalDialogOwner())
283 {
284 pswp->fl |= SWP_ZORDER;
285 pswp->hwndInsertBehind = win32wnd->getOS2HwndModalDialog();
286 if (pswp->fl & SWP_ACTIVATE)
287 {
288 pswp->fl &= ~SWP_ACTIVATE;
289 WinSetWindowPos(win32wnd->getOS2HwndModalDialog(),0,0,0,0,0,SWP_ACTIVATE);
290 }
291 }
292
293 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0)
294 goto RunDefWndProc;
295
296 if(!win32wnd->CanReceiveSizeMsgs())
297 break;
298
299 WinQueryWindowPos(hwnd, &swpOld);
300 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
301 if (win32wnd->isChild()) {
302 if(win32wnd->getParent()) {
303 hParent = win32wnd->getParent()->getOS2WindowHandle();
304 }
305 else goto RunDefWndProc;
306 }
307 }
308 hwndAfter = pswp->hwndInsertBehind;
309 if(win32wnd->getParent()) {
310 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getWindowHeight(),
311 win32wnd->getParent()->getClientRectPtr()->left,
312 win32wnd->getParent()->getClientRectPtr()->top,
313 hwnd);
314 }
315 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), 0, 0, hwnd);
316
317 wp.hwnd = win32wnd->getWindowHandle();
318 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
319 {
320 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
321 if(wndAfter) {
322 wp.hwndInsertAfter = wndAfter->getWindowHandle();
323 }
324 else wp.hwndInsertAfter = HWND_TOP_W;
325 }
326
327 wpOld = wp;
328 win32wnd->MsgPosChanging((LPARAM)&wp);
329
330 if ((wp.hwndInsertAfter != wpOld.hwndInsertAfter) ||
331 (wp.x != wpOld.x) || (wp.y != wpOld.y) || (wp.cx != wpOld.cx) || (wp.cy != wpOld.cy) || (wp.flags != wpOld.flags))
332 {
333 dprintf(("OS2: WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
334 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
335
336 if(win32wnd->getParent()) {
337 OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, win32wnd->getParent()->getWindowHeight(),
338 win32wnd->getParent()->getClientRectPtr()->left,
339 win32wnd->getParent()->getClientRectPtr()->top,
340 hwnd);
341 }
342 else OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, OSLibQueryScreenHeight(), 0, 0, hwnd);
343
344 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
345 pswp->fl |= SWP_NOADJUST;
346 pswp->hwndInsertBehind = hwndAfter;
347 pswp->hwnd = hwnd;
348
349 return (MRESULT)0xf;
350 }
351 return (MRESULT)0;
352 }
353
354 case WM_WINDOWPOSCHANGED:
355 {
356 PSWP pswp = (PSWP)mp1,pswpOld = pswp+1;
357 SWP swpOld = *(pswp + 1);
358 WINDOWPOS wp;
359 HWND hParent = NULLHANDLE;
360 RECTL rect;
361
362 dprintf(("OS2: WM_WINDOWPOSCHANGED (%x) %x %x (%d,%d) (%d,%d)", mp2, win32wnd->getWindowHandle(), pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
363
364 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0)
365 {
366 if(pswp->fl & SWP_ACTIVATE)
367 {
368 //Only send PM WM_ACTIVATE to top-level windows (frame windows)
369 if(!(WinQueryWindowUShort(hwnd,QWS_FLAGS) & FF_ACTIVE))
370 {
371 if(isFrame) {
372 WinSendMsg(hwnd, WM_ACTIVATE, (MPARAM)TRUE, (MPARAM)hwnd);
373 }
374 else
375 if(win32wnd->IsWindowCreated()) {
376 win32wnd->MsgActivate(1, 0, win32wnd->getWindowHandle(), hwnd);
377 }
378 }
379 }
380 goto RunDefWndProc;
381 }
382
383 if(pswp->fl & (SWP_MOVE | SWP_SIZE))
384 {
385 if(win32wnd->isChild())
386 {
387 if(win32wnd->getParent()) {
388 hParent = win32wnd->getParent()->getOS2WindowHandle();
389 }
390 else goto PosChangedEnd; //parent has just been destroyed
391 }
392 }
393
394
395 if(win32wnd->getParent()) {
396 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getWindowHeight(),
397 win32wnd->getParent()->getClientRectPtr()->left,
398 win32wnd->getParent()->getClientRectPtr()->top,
399 hwnd);
400 }
401 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), 0, 0, hwnd);
402
403 wp.hwnd = win32wnd->getWindowHandle();
404 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
405 {
406 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
407 if(wndAfter) {
408 wp.hwndInsertAfter = wndAfter->getWindowHandle();
409 }
410 else wp.hwndInsertAfter = HWND_TOP_W;
411 }
412
413 if((pswp->fl & (SWP_MOVE | SWP_SIZE)) && !(win32wnd->getStyle() & WS_MINIMIZE_W))
414 {
415 //CB: todo: use result for WM_CALCVALIDRECTS
416 //Get old client rectangle (for invalidation of frame window parts later on)
417 mapWin32ToOS2Rect(win32wnd->getWindowHeight(), win32wnd->getClientRectPtr(), (PRECTLOS2)&rect);
418
419 //Note: Also updates the new window rectangle
420 win32wnd->MsgFormatFrame(&wp);
421
422 if(win32wnd->CanReceiveSizeMsgs())
423 win32wnd->MsgPosChanged((LPARAM)&wp);
424
425 if((pswp->fl & SWP_SIZE) && ((pswp->cx != pswpOld->cx) || (pswp->cy != pswpOld->cy)))
426 {
427 //redraw the frame (to prevent unnecessary client updates)
428 BOOL redrawAll = FALSE;
429
430 if (win32wnd->getWindowClass())
431 {
432 DWORD dwStyle = win32wnd->getWindowClass()->getClassLongA(GCL_STYLE_W);
433
434 if ((dwStyle & CS_HREDRAW_W) && (pswp->cx != pswpOld->cx))
435 redrawAll = TRUE;
436 else if ((dwStyle & CS_VREDRAW_W) && (pswp->cy != pswpOld->cy))
437 redrawAll = TRUE;
438 } else redrawAll = TRUE;
439
440 if (redrawAll)
441 {
442 //CB: redraw all children for now
443 // -> problems with update region if we don't do it
444 // todo: rewrite whole handling
445 WinInvalidateRect(hwnd,NULL,TRUE);
446 }
447 else
448 {
449 HPS hps = WinGetPS(hwnd);
450 RECTL frame,client,arcl[4];
451
452 WinQueryWindowRect(hwnd,&frame);
453 //top
454 arcl[0].xLeft = 0;
455 arcl[0].xRight = frame.xRight;
456 arcl[0].yBottom = rect.yTop;
457 arcl[0].yTop = frame.yTop;
458 //right
459 arcl[1].xLeft = rect.xRight;
460 arcl[1].xRight = frame.xRight;
461 arcl[1].yBottom = 0;
462 arcl[1].yTop = frame.yTop;
463 //left
464 arcl[2].xLeft = 0;
465 arcl[2].xRight = rect.xLeft;
466 arcl[2].yBottom = 0;
467 arcl[2].yTop = frame.yTop;
468 //bottom
469 arcl[3].xLeft = 0;
470 arcl[3].xRight = frame.xRight;
471 arcl[3].yBottom = 0;
472 arcl[3].yTop = rect.yBottom;
473
474 HRGN hrgn = GpiCreateRegion(hps,4,(PRECTL)&arcl);
475
476 WinInvalidateRegion(hwnd,hrgn,FALSE);
477 GpiDestroyRegion(hps,hrgn);
478 WinReleasePS(hps);
479 }
480 }
481 }
482 else
483 {
484 if(win32wnd->CanReceiveSizeMsgs())
485 win32wnd->MsgPosChanged((LPARAM)&wp);
486 }
487
488 if(pswp->fl & SWP_ACTIVATE)
489 {
490 //Only send PM WM_ACTIVATE to top-level windows (frame windows)
491 if(!(WinQueryWindowUShort(hwnd,QWS_FLAGS) & FF_ACTIVE))
492 {
493 if(isFrame) {
494 WinSendMsg(hwnd, WM_ACTIVATE, (MPARAM)TRUE, (MPARAM)hwnd);
495 }
496 else
497 if(win32wnd->IsWindowCreated()) {
498 win32wnd->MsgActivate(1, 0, win32wnd->getWindowHandle(), hwnd);
499 }
500 }
501 }
502
503PosChangedEnd:
504 return (MRESULT)FALSE;
505 }
506
507 case WM_ACTIVATE:
508 {
509 USHORT flags = WinQueryWindowUShort(hwnd,QWS_FLAGS);
510
511 dprintf(("OS2: WM_ACTIVATE %x %x %x", hwnd, mp1, mp2));
512
513 WinSetWindowUShort(hwnd,QWS_FLAGS, SHORT1FROMMP(mp1) ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
514 if(win32wnd->IsWindowCreated())
515 {
516 win32wnd->MsgActivate((LOWORD(pWinMsg->wParam) == WA_ACTIVE_W) ? 1 : 0, HIWORD(pWinMsg->wParam), pWinMsg->lParam, (HWND)mp2);
517
518 //CB: show owner behind the dialog
519 if(win32wnd->IsModalDialog())
520 {
521 Win32BaseWindow *topOwner = win32wnd->getOwner()->GetTopParent();
522
523 if(topOwner) WinSetWindowPos(topOwner->getOS2WindowHandle(),hwnd,0,0,0,0,SWP_ZORDER);
524 }
525 }
526 return 0;
527 }
528
529 case WM_SIZE:
530 {
531 dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp2)));
532 goto RunDefWndProc;
533 }
534
535 case WM_CALCVALIDRECTS:
536#if 0
537 {
538 PRECTL oldRect = (PRECTL)mp1,newRect = oldRect+1;
539 UINT res = CVR_ALIGNLEFT | CVR_ALIGNTOP;
540
541//CB: todo: use WM_NCCALCSIZE result
542 if (win32wnd->getWindowClass())
543 {
544 DWORD dwStyle = win32wnd->getWindowClass()->getClassLongA(GCL_STYLE_W);
545
546 if ((dwStyle & CS_HREDRAW_W) && (newRect->xRight-newRect->xLeft != oldRect->xRight-oldRect->xLeft))
547 res |= CVR_REDRAW;
548 else
549 if ((dwStyle & CS_VREDRAW_W) && (newRect->yTop-newRect->yBottom != oldRect->yTop-oldRect->yBottom))
550 res |= CVR_REDRAW;
551 }
552 else res |= CVR_REDRAW;
553
554 return (MRESULT)res;
555 }
556#else
557 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
558 return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
559#endif
560
561 case WM_VRNENABLED:
562 dprintf(("OS2: WM_VRNENABLED %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
563 if(!win32wnd->isComingToTop() && ((win32wnd->getExStyle() & WS_EX_TOPMOST_W) == WS_EX_TOPMOST_W))
564 {
565 HWND hwndrelated;
566 Win32BaseWindow *topwindow;
567
568 win32wnd->setComingToTop(TRUE);
569
570 hwndrelated = WinQueryWindow(hwnd, QW_PREV);
571 dprintf(("WM_VRNENABLED hwndrelated = %x (hwnd=%x)", hwndrelated, hwnd));
572 topwindow = Win32BaseWindow::GetWindowFromOS2Handle(hwndrelated);
573 if(topwindow == NULL || ((win32wnd->getExStyle() & WS_EX_TOPMOST_W) == 0)) {
574 //put window at the top of z order
575 WinSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER );
576 }
577
578 win32wnd->setComingToTop(FALSE);
579 break;
580 }
581 goto RunDefWndProc;
582
583 case WM_SETFOCUS:
584 {
585 HWND hwndFocus = (HWND)mp1;
586
587 dprintf(("OS2: WM_SETFOCUS %x %x (%x) %d", win32wnd->getWindowHandle(), mp1, OS2ToWin32Handle(hwndFocus), mp2));
588 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC) {
589 //another (non-win32) application's window
590 //set to NULL (allowed according to win32 SDK) to avoid problems
591 hwndFocus = NULL;
592 }
593 if((ULONG)mp2 == TRUE) {
594 HWND hwndFocusWin32 = OS2ToWin32Handle(hwndFocus);
595 recreateCaret (hwndFocusWin32);
596 win32wnd->MsgSetFocus(hwndFocusWin32);
597 }
598 else win32wnd->MsgKillFocus(OS2ToWin32Handle(hwndFocus));
599 break;
600 }
601
602#if 0
603 //is sent to both windows gaining and loosing the focus
604 case WM_FOCUSCHANGE:
605 {
606 HWND hwndFocus = (HWND)mp1;
607 HWND hwndLoseFocus, hwndGainFocus;
608 USHORT usSetFocus = SHORT1FROMMP(mp2);
609 USHORT fsFocusChange = SHORT2FROMMP(mp2);
610
611 rc = 0;
612 dprintf(("OS2: WM_FOCUSCHANGE (start) %x %x %x %x", win32wnd->getWindowHandle(), hwndFocus, usSetFocus, fsFocusChange));
613 if(usSetFocus) {
614 hwndGainFocus = hwnd;
615 hwndLoseFocus = hwndFocus;
616 }
617 else {
618 hwndGainFocus = hwndFocus;
619 hwndLoseFocus = hwnd;
620 }
621
622 if(usSetFocus)
623 {
624 Win32BaseWindow *winfocus = Win32BaseWindow::GetWindowFromOS2Handle(hwndLoseFocus);
625 if(!(fsFocusChange & FC_NOSETACTIVE))
626 {
627 if(!winfocus || (winfocus->GetTopParent() != win32wnd->GetTopParent()))
628 {
629 if(winfocus)
630 WinSendMsg(winfocus->GetTopParent()->getOS2WindowHandle(), WM_ACTIVATE, (MPARAM)0, (MPARAM)hwndGainFocus);
631 else
632 WinSendMsg(hwndLoseFocus, WM_ACTIVATE, (MPARAM)0, (MPARAM)hwndGainFocus);
633 }
634 }
635 //SvL: Check if window is still valid
636 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
637 if(win32wnd == NULL)
638 return (MRESULT)rc;
639
640 if(!(fsFocusChange & FC_NOSETACTIVE))
641 {
642 Win32BaseWindow *topparent = win32wnd->GetTopParent();
643 if(!winfocus || (winfocus->GetTopParent() != topparent))
644 {
645 if(!(fsFocusChange & FC_NOBRINGTOTOP))
646 {
647 if(topparent) {
648 //put window at the top of z order
649 WinSetWindowPos(topparent->getOS2WindowHandle(), HWND_TOP, 0, 0, 0, 0, SWP_ZORDER);
650 }
651 }
652
653 // PH 2000/09/01 Netscape 4.7
654 // check if topparent is valid
655 if (topparent)
656 WinSendMsg(topparent->getOS2WindowHandle(), WM_ACTIVATE, (MPARAM)1, (MPARAM)hwndLoseFocus);
657 }
658 }
659 //SvL: Check if window is still valid
660 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
661 if(win32wnd == NULL)
662 return (MRESULT)rc;
663
664 //TODO: Don't send WM_SETSELECTION to child window if frame already has selection
665 if(!(fsFocusChange & FC_NOSETSELECTION)) {
666 WinSendMsg(hwndGainFocus, WM_SETSELECTION, (MPARAM)1, (MPARAM)0);
667 }
668
669 if(!(fsFocusChange & FC_NOSETFOCUS)) {
670 WinSendMsg(hwndGainFocus, WM_SETFOCUS, (MPARAM)hwndLoseFocus, (MPARAM)1);
671 }
672 }
673 else /* no usSetFocus */
674 {
675 if(!(fsFocusChange & FC_NOLOSEFOCUS)) {
676 WinSendMsg(hwndLoseFocus, WM_SETFOCUS, (MPARAM)hwndGainFocus, (MPARAM)0);
677 }
678 //TODO: Don't send WM_SETSELECTION to child window if frame already has selection
679 if(!(fsFocusChange & FC_NOLOSESELECTION)) {
680 WinSendMsg(hwndLoseFocus, WM_SETSELECTION, (MPARAM)0, (MPARAM)0);
681 }
682 //SvL: Check if window is still valid
683 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
684 if(win32wnd == NULL) {
685 return (MRESULT)rc;
686 }
687
688 Win32BaseWindow *winfocus = Win32BaseWindow::GetWindowFromOS2Handle(hwndGainFocus);
689 if(!(fsFocusChange & FC_NOLOSEACTIVE))
690 {
691 Win32BaseWindow *topparent = win32wnd->GetTopParent();
692
693 if(!winfocus || (winfocus->GetTopParent() != topparent))
694 {
695 // PH 2000/09/01 Netscape 4.7
696 // check if topparent is valid
697 if (topparent)
698 WinSendMsg(topparent->getOS2WindowHandle(), WM_ACTIVATE, (MPARAM)0, (MPARAM)hwndGainFocus);
699 }
700 }
701 //SvL: Check if window is still valid
702 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
703 if(win32wnd == NULL)
704 return (MRESULT)rc;
705
706 if(!(fsFocusChange & FC_NOSETACTIVE))
707 {
708 if(!winfocus || (winfocus->GetTopParent() != win32wnd->GetTopParent()))
709 {
710 if(winfocus)
711 {
712 // PH 2000/09/01 Netscape 4.7
713 // check if topparent is valid
714 Win32BaseWindow *topparent = winfocus->GetTopParent();
715 if (topparent)
716 WinSendMsg(topparent->getOS2WindowHandle(), WM_ACTIVATE, (MPARAM)1, (MPARAM)hwndLoseFocus);
717 }
718 else
719 WinSendMsg(hwndGainFocus, WM_ACTIVATE, (MPARAM)1, (MPARAM)hwndLoseFocus);
720 }
721 }
722 }
723
724
725#ifdef DEBUG
726 SetWin32TIB();
727 dprintf(("OS2: WM_FOCUSCHANGE (end) %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
728#endif
729 return (MRESULT)rc;
730 }
731#endif
732
733 //**************************************************************************
734 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
735 //**************************************************************************
736 case WM_HITTEST:
737 {
738 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
739 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
740 }
741 if(win32wnd && win32wnd->IsWindowCreated())
742 {
743 MRESULT rc;
744
745 rc = (MRESULT)win32wnd->MsgHitTest(pWinMsg);
746 return rc;
747 }
748 return (MRESULT)HT_NORMAL;
749 }
750
751 case WM_BUTTON1DOWN:
752 case WM_BUTTON1UP:
753 case WM_BUTTON1DBLCLK:
754 case WM_BUTTON2DOWN:
755 case WM_BUTTON2UP:
756 case WM_BUTTON2DBLCLK:
757 case WM_BUTTON3DOWN:
758 case WM_BUTTON3UP:
759 case WM_BUTTON3DBLCLK:
760 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
761 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
762 }
763 if(win32wnd)
764 win32wnd->MsgButton(pWinMsg);
765
766 rc = (MRESULT)TRUE;
767 break;
768
769 case WM_BUTTON2MOTIONSTART:
770 case WM_BUTTON2MOTIONEND:
771 case WM_BUTTON2CLICK:
772 case WM_BUTTON1MOTIONSTART:
773 case WM_BUTTON1MOTIONEND:
774 case WM_BUTTON1CLICK:
775 case WM_BUTTON3MOTIONSTART:
776 case WM_BUTTON3MOTIONEND:
777 case WM_BUTTON3CLICK:
778 rc = (MRESULT)TRUE;
779 break;
780
781 case WM_MOUSEMOVE:
782 {
783 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
784 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
785 }
786 if(win32wnd)
787 win32wnd->MsgMouseMove(pWinMsg);
788 break;
789 }
790
791 case WM_CONTROL:
792 goto RunDefWndProc;
793
794 case WM_COMMAND:
795 dprintf(("OS2: WM_COMMAND %x %x %x", hwnd, mp1, mp2));
796 win32wnd->DispatchMsgA(pWinMsg);
797 break;
798
799 case WM_SYSCOMMAND:
800 win32wnd->DispatchMsgA(pWinMsg);
801 break;
802
803 case WM_RENDERFMT:
804 case WM_RENDERALLFMTS:
805 case WM_DESTROYCLIPBOARD:
806 win32wnd->DispatchMsgA(pWinMsg);
807 break;
808
809 case WM_CHAR:
810 win32wnd->MsgChar(pWinMsg);
811 break;
812
813 case WM_TIMER:
814 win32wnd->DispatchMsgA(pWinMsg);
815 goto RunDefWndProc;
816
817 case WM_SETWINDOWPARAMS:
818 {
819 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
820
821 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
822 if(wndParams->fsStatus & WPM_TEXT) {
823 win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText);
824 }
825 goto RunDefWndProc;
826 }
827
828 case WM_QUERYWINDOWPARAMS:
829 {
830 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
831 ULONG textlen;
832 PSZ wintext;
833
834 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
835 {
836 if(wndpars->fsStatus & WPM_TEXT)
837 win32wnd->MsgGetText(wndpars->pszText, wndpars->cchText);
838 if(wndpars->fsStatus & WPM_CCHTEXT)
839 wndpars->cchText = win32wnd->MsgGetTextLength();
840
841 wndpars->fsStatus = 0;
842 wndpars->cbCtlData = 0;
843 wndpars->cbPresParams = 0;
844 return (MRESULT)TRUE;
845 }
846 goto RunDefWndProc;
847 }
848
849 case WM_PAINT:
850 {
851 RECTL rectl;
852 BOOL rc;
853
854 rc = WinQueryUpdateRect(hwnd, &rectl);
855 dprintf(("OS2: WM_PAINT %x (%d,%d) (%d,%d) rc=%d", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop, rc));
856
857 if(rc && win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
858 rectl.yBottom != rectl.yTop))
859 {
860 PRECT pClient = win32wnd->getClientRectPtr();
861 PRECT pWindow = win32wnd->getWindowRect();
862
863 if(!(pClient->left == 0 && pClient->top == 0 &&
864 win32wnd->getClientHeight() == win32wnd->getWindowHeight() &&
865 win32wnd->getClientWidth() == win32wnd->getWindowWidth()))
866 {
867 win32wnd->MsgNCPaint();
868 }
869 win32wnd->DispatchMsgA(pWinMsg);
870 }
871 else goto RunDefWndProc;
872
873 //SvL: Not calling the default window procedure causes all sorts of
874 // strange problems (redraw & hanging app)
875 // -> check what WinBeginPaint does what we're forgetting in BeginPaint
876// WinQueryUpdateRect(hwnd, &rectl);
877// if(rectl.xLeft == 0 && rectl.yTop == 0 && rectl.xRight == 0 && rectl.yBottom == 0) {
878// RestoreOS2TIB();
879// return (MRESULT)FALSE;
880// }
881// dprintf(("Update rectangle (%d,%d)(%d,%d) not empty, msg %x", rectl.xLeft, rectl.yTop, rectl.xRight, rectl.yBottom, pWinMsg->message));
882// goto RunDefWndProc;
883 break;
884 }
885
886 case WM_ERASEBACKGROUND:
887 {
888 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
889 return (MRESULT)FALSE;
890 }
891
892#if 0
893 case WM_CONTEXTMENU:
894 {
895 win32wnd->DispatchMsgA(pWinMsg);
896
897 return (MRESULT)TRUE;
898 }
899#endif
900
901 case WM_QUERYTRACKINFO:
902 {
903 PTRACKINFO trackInfo = (PTRACKINFO)mp2;
904
905 dprintf(("OS2: WM_QUERYTRACKINFO %x", win32wnd->getWindowHandle()));
906 trackInfo->cxBorder = 4;
907 trackInfo->cyBorder = 4;
908 win32wnd->AdjustTrackInfo((PPOINT)&trackInfo->ptlMinTrackSize,(PPOINT)&trackInfo->ptlMaxTrackSize);
909 return (MRESULT)TRUE;
910 }
911
912 case WM_QUERYBORDERSIZE:
913 {
914 PWPOINT size = (PWPOINT)mp1;
915
916 dprintf(("OS2: WM_QUERYBORDERSIZE %x", win32wnd->getWindowHandle()));
917
918 size->x = 0;
919 size->y = 0;
920 return (MRESULT)TRUE;
921 }
922
923 case WM_REALIZEPALETTE:
924 {
925 dprintf(("OS2: WM_REALIZEPALETTE"));
926 goto RunDefWndProc;
927 }
928
929 case WM_OWNERPOSCHANGE:
930 {
931 dprintf(("OS2: WM_OWNERPOSCHANGE"));
932 goto RunDefWndProc;
933 }
934
935 case WM_INITMENU:
936 case WM_MENUSELECT:
937 case WM_MENUEND:
938 case WM_NEXTMENU:
939 case WM_SYSCOLORCHANGE:
940 case WM_SYSVALUECHANGED:
941 case WM_SETSELECTION:
942 case WM_PPAINT:
943 case WM_PSETFOCUS:
944 case WM_PSYSCOLORCHANGE:
945 case WM_PSIZE:
946 case WM_PACTIVATE:
947 case WM_PCONTROL:
948 case WM_HELP:
949 case WM_APPTERMINATENOTIFY:
950 case WM_PRESPARAMCHANGED:
951 case WM_DRAWITEM:
952 case WM_MEASUREITEM:
953 case WM_CONTROLPOINTER:
954 case WM_QUERYDLGCODE:
955 case WM_SUBSTITUTESTRING:
956 case WM_MATCHMNEMONIC:
957 case WM_SAVEAPPLICATION:
958 case WM_SEMANTICEVENT:
959 default:
960 dprintf2(("OS2: RunDefWndProc hwnd %x msg %x mp1 %x mp2 %x", hwnd, msg, mp1, mp2));
961 RestoreOS2TIB();
962 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
963 }
964 return (MRESULT)rc;
965
966RunDefWndProc:
967// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
968 RestoreOS2TIB();
969 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
970} /* End of Win32WindowProc */
971//******************************************************************************
972//******************************************************************************
973MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
974{
975 POSTMSG_PACKET *postmsg;
976 OSLIBPOINT point, ClientPoint;
977 Win32BaseWindow *win32wnd;
978 TEB *teb;
979 MRESULT rc = 0;
980 MSG winMsg, *pWinMsg;
981
982 //Restore our FS selector
983 SetWin32TIB();
984
985 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- BEGIN
986 teb = GetThreadTEB();
987 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
988
989 if(!teb || (msg != WM_CREATE && win32wnd == NULL)) {
990 dprintf(("Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
991 goto RunDefFrameWndProc;
992 }
993//// if(teb->o.odin.fIgnoreMsgs) {
994//// goto RunDefWndProc;
995//// }
996
997 if((teb->o.odin.msgstate & 1) == 0)
998 {//message that was sent directly to our window proc handler; translate it here
999 QMSG qmsg;
1000
1001 qmsg.msg = msg;
1002 qmsg.hwnd = hwnd;
1003 qmsg.mp1 = mp1;
1004 qmsg.mp2 = mp2;
1005 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
1006 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
1007 qmsg.reserved = 0;
1008
1009 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
1010 {//message was not translated
1011 memset(&winMsg, 0, sizeof(MSG));
1012 }
1013 pWinMsg = &winMsg;
1014 }
1015 else {
1016 pWinMsg = &teb->o.odin.msg;
1017 teb->o.odin.msgstate++;
1018 }
1019 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- END
1020
1021 switch( msg )
1022 {
1023 case WM_CREATE:
1024 {
1025 RestoreOS2TIB();
1026 pfnFrameWndProc(hwnd, msg, mp1, mp2);
1027 SetWin32TIB();
1028 rc = ProcessPMMessage(hwnd, msg, mp1, mp2, win32wnd, pWinMsg, teb, TRUE);
1029 break;
1030 }
1031
1032 case WM_CALCFRAMERECT:
1033 dprintf(("OS2: WM_CALCFRAMERECT %x", win32wnd->getWindowHandle()));
1034 rc = (MRESULT)TRUE;
1035 break;
1036
1037 case WM_QUERYCTLTYPE:
1038 // This is a frame window
1039 dprintf(("OS2: WM_QUERYCTLTYPE %x", win32wnd->getWindowHandle()));
1040 rc = (MRESULT)CCT_FRAME;
1041 break;
1042
1043 case WM_QUERYFOCUSCHAIN:
1044 dprintf(("OS2: WM_QUERYFOCUSCHAIN %x", win32wnd->getWindowHandle()));
1045 goto RunDefFrameWndProc;
1046
1047 case WM_FOCUSCHANGE:
1048 {
1049 HWND hwndFocus = (HWND)mp1;
1050 HWND hwndLoseFocus, hwndGainFocus;
1051 USHORT usSetFocus = SHORT1FROMMP(mp2);
1052 USHORT fsFocusChange = SHORT2FROMMP(mp2);
1053
1054 dprintf(("OS2: WM_FOCUSCHANGE %x %x %x %x", win32wnd->getWindowHandle(), hwndFocus, usSetFocus, fsFocusChange));
1055 goto RunDefFrameWndProc;
1056 }
1057
1058 case WM_ACTIVATE:
1059 case WM_SETFOCUS:
1060 {
1061 rc = ProcessPMMessage(hwnd, msg, mp1, mp2, win32wnd, pWinMsg, teb, TRUE);
1062 goto RunDefFrameWndProc;
1063 }
1064
1065#if 0
1066//just a test
1067 case WM_ADJUSTWINDOWPOS:
1068 case WM_WINDOWPOSCHANGED:
1069 {
1070 rc = ProcessPMMessage(hwnd, msg, mp1, mp2, win32wnd, pWinMsg, teb, TRUE);
1071 goto RunDefFrameWndProc;
1072 }
1073#endif
1074
1075 case WM_QUERYFRAMEINFO:
1076 dprintf(("OS2: WM_QUERYFRAMEINFO %x", win32wnd->getWindowHandle()));
1077 goto RunDefFrameWndProc;
1078
1079 case WM_FORMATFRAME:
1080 dprintf(("OS2: WM_FORMATFRAME %x", win32wnd->getWindowHandle()));
1081 goto RunDefFrameWndProc;
1082
1083 case WM_ADJUSTFRAMEPOS:
1084 {
1085 PSWP pswp = (PSWP)mp1;
1086
1087 dprintf(("OS2: WM_ADJUSTFRAMEPOS %x %x %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
1088 goto RunDefFrameWndProc;
1089 }
1090
1091 case WM_MINMAXFRAME:
1092 {
1093 PSWP swp = (PSWP)mp1;
1094
1095 if (!win32wnd->IsWindowCreated()) goto RunDefWndProc;
1096
1097 dprintf(("OS2: WM_MINMAXFRAME %x",hwnd));
1098 if ((swp->fl & SWP_MAXIMIZE) == SWP_MAXIMIZE)
1099 {
1100 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MINIMIZE_W) | WS_MAXIMIZE_W);
1101
1102 RECT rect;
1103
1104 rect.left = rect.top = rect.right = rect.bottom = 0;
1105 win32wnd->AdjustMaximizedRect(&rect);
1106 swp->x += rect.left;
1107 swp->cx += rect.right-rect.left;
1108 swp->y -= rect.bottom;
1109 swp->cy += rect.bottom-rect.top;
1110 }
1111 else
1112 if ((swp->fl & SWP_MINIMIZE) == SWP_MINIMIZE)
1113 {
1114 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MAXIMIZE_W) | WS_MINIMIZE_W);
1115 }
1116 else
1117 if ((swp->fl & SWP_RESTORE) == SWP_RESTORE)
1118 {
1119 win32wnd->setStyle(win32wnd->getStyle() & ~(WS_MINIMIZE_W | WS_MAXIMIZE_W));
1120 }
1121 goto RunDefWndProc;
1122 }
1123
1124 case WM_UPDATEFRAME:
1125 dprintf(("OS2: WM_UPDATEFRAME %x", win32wnd->getWindowHandle()));
1126 goto RunDefFrameWndProc;
1127
1128 default:
1129 rc = ProcessPMMessage(hwnd, msg, mp1, mp2, win32wnd, pWinMsg, teb, TRUE);
1130 break;
1131 }
1132 RestoreOS2TIB();
1133 return (MRESULT)rc;
1134
1135RunDefFrameWndProc:
1136 RestoreOS2TIB();
1137 return pfnFrameWndProc(hwnd, msg, mp1, mp2);
1138
1139RunDefWndProc:
1140 RestoreOS2TIB();
1141 return Win32WindowProc(hwnd, msg, mp1, mp2);
1142}
1143//******************************************************************************
1144//TODO: Quickly moving a window two times doesn't force a repaint (1st time)
1145//******************************************************************************
1146VOID FrameTrackFrame(Win32BaseWindow *win32wnd,DWORD flags)
1147{
1148 TRACKINFO track;
1149 RECTL rcl;
1150 PRECT pWindowRect, pClientRect;
1151 HWND hwndTracking;
1152 HPS hpsTrack;
1153 LONG parentHeight, parentWidth;
1154
1155 dprintf(("FrameTrackFrame: %x %x", win32wnd->getWindowHandle(), flags));
1156 track.cxBorder = 4;
1157 track.cyBorder = 4; /* 4 pel wide lines used for rectangle */
1158 track.cxGrid = 1;
1159 track.cyGrid = 1; /* smooth tracking with mouse */
1160 track.cxKeyboard = 8;
1161 track.cyKeyboard = 8; /* faster tracking using cursor keys */
1162
1163 pWindowRect = win32wnd->getWindowRect();
1164 if(win32wnd->getParent()) {
1165 parentHeight = win32wnd->getParent()->getWindowHeight();
1166 parentWidth = win32wnd->getParent()->getWindowWidth();
1167 hwndTracking = win32wnd->getParent()->getOS2WindowHandle();
1168 hpsTrack = WinGetPS(hwndTracking);
1169 }
1170 else {
1171 parentHeight = OSLibQueryScreenHeight();
1172 parentWidth = OSLibQueryScreenWidth();
1173 hwndTracking = HWND_DESKTOP;
1174 hpsTrack = NULL;
1175 }
1176
1177 mapWin32ToOS2Rect(parentHeight, pWindowRect, (PRECTLOS2)&track.rclTrack);
1178 WinQueryWindowRect(hwndTracking, &track.rclBoundary);
1179
1180 track.ptlMinTrackSize.x = 10;
1181 track.ptlMinTrackSize.y = 10; /* set smallest allowed size of rectangle */
1182 track.ptlMaxTrackSize.x = parentWidth;
1183 track.ptlMaxTrackSize.y = parentHeight; /* set largest allowed size of rectangle */
1184
1185 win32wnd->AdjustTrackInfo((PPOINT)&track.ptlMinTrackSize, (PPOINT)&track.ptlMaxTrackSize);
1186
1187 track.fs = flags;
1188
1189 if(WinTrackRect(hwndTracking, NULL, &track) )
1190 {
1191 if(hpsTrack) WinReleasePS(hpsTrack);
1192
1193 /* if successful copy final position back */
1194 if(!WinEqualRect(0, &rcl, &track.rclTrack)) {
1195 dprintf(("FrameTrackFrame: new (os/2) window rect: (%d,%d)(%d,%d)", track.rclTrack.xLeft, track.rclTrack.yBottom, track.rclTrack.xRight - track.rclTrack.xLeft, track.rclTrack.yTop - track.rclTrack.yBottom));
1196 if(flags == TF_MOVE) {
1197 WinSetWindowPos(win32wnd->getOS2WindowHandle(),
1198 0, track.rclTrack.xLeft, track.rclTrack.yBottom,
1199 0, 0, SWP_MOVE);
1200 }
1201 else {
1202 WinSetWindowPos(win32wnd->getOS2WindowHandle(),
1203 0, track.rclTrack.xLeft, track.rclTrack.yBottom,
1204 track.rclTrack.xRight - track.rclTrack.xLeft,
1205 track.rclTrack.yTop - track.rclTrack.yBottom,
1206 SWP_SIZE|SWP_MOVE);
1207 }
1208 }
1209 return;
1210 }
1211 if(hpsTrack) WinReleasePS(hpsTrack);
1212 return;
1213}
1214//******************************************************************************
1215//******************************************************************************
Note: See TracBrowser for help on using the repository browser.