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

Last change on this file since 7266 was 7266, checked in by achimha, 24 years ago

poll CDROM less often, causes HDD activity on some systems

File size: 61.6 KB
Line 
1/* $Id: pmwindow.cpp,v 1.163 2001-10-29 13:54:39 achimha 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_DOSMODULEMGR
18#define INCL_DOSDEVICES
19#define INCL_DOSDEVIOCTL
20#define INCL_WINTRACKRECT
21
22#include <os2wrap.h>
23#include <stdlib.h>
24#include <string.h>
25#include <win32type.h>
26#include <win32api.h>
27#include <winconst.h>
28#include <winuser32.h>
29#include <wprocess.h>
30#include <misc.h>
31#include <win32wbase.h>
32#include <win32dlg.h>
33#include "win32wdesktop.h"
34#include "pmwindow.h"
35#include "oslibwin.h"
36#include "oslibutil.h"
37#include "oslibgdi.h"
38#include "oslibmsg.h"
39#define INCLUDED_BY_DC
40#include "dc.h"
41#include <thread.h>
42#include <wprocess.h>
43#include "caret.h"
44#include "timer.h"
45#include <codepage.h>
46#include "syscolor.h"
47#include "options.h"
48#include "menu.h"
49#include <pmkbdhk.h>
50#include <pmscan.h>
51#include <winscan.h>
52#include <win\dbt.h>
53
54#define DBG_LOCALLOG DBG_pmwindow
55#include "dbglocal.h"
56
57//define this to use the new code for WM_CALCVALIDRECT handling
58//#define USE_CALCVALIDRECT
59
60HMQ hmq = 0; /* Message queue handle */
61HAB hab = 0;
62RECTL desktopRectl = {0};
63ULONG ScreenWidth = 0;
64ULONG ScreenHeight = 0;
65ULONG ScreenBitsPerPel = 0;
66BOOL fOS2Look = FALSE;
67HBITMAP hbmFrameMenu[3] = {0};
68
69static PFNWP pfnFrameWndProc = NULL;
70static HWND hwndFocusChange = 0;
71static HWND hwndCD = 0;
72
73// Note:
74// For a "lonekey"-press of AltGr, we only receive WM_KEYUP
75// messages. If the key is pressed longer and starts to repeat,
76// WM_KEYDOWN messages come in properly.
77static BOOL fKeyAltGrDown = FALSE;
78
79
80
81MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
82MRESULT EXPENTRY Win32CDWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
83MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
84void FrameReplaceMenuItem(HWND hwndMenu, ULONG nIndex, ULONG idOld, ULONG idNew,
85 HBITMAP hbmNew);
86void FrameSetFocus(HWND hwnd);
87
88VOID APIENTRY DspInitSystemDriverName(PSZ pszDriverName, ULONG lenDriverName);
89
90//******************************************************************************
91//Initialize PM; create hab, message queue and register special Win32 window classes
92//******************************************************************************
93BOOL InitPM()
94{
95 hab = WinInitialize(0);
96 dprintf(("Winitialize returned %x", hab));
97 hmq = WinCreateMsgQueue(hab, 0);
98
99 if(!hab || !hmq)
100 {
101 UINT error;
102 //CB: only fail on real error
103 error = WinGetLastError(hab) & 0xFFFF; //error code
104 if (!hab || (error != PMERR_MSG_QUEUE_ALREADY_EXISTS))
105 {
106 dprintf(("WinInitialize or WinCreateMsgQueue failed %x %x", hab, hmq));
107 dprintf((" Error = %x",error));
108 return(FALSE);
109 }
110 else
111 {
112 if(!hab) {
113 hab = WinQueryAnchorBlock(HWND_DESKTOP);
114 dprintf(("WinQueryAnchorBlock returned %x", hab));
115 }
116 if(!hmq) {
117 PTIB ptib;
118 PPIB ppib;
119
120 DosGetInfoBlocks(&ptib, &ppib);
121
122 hmq = WinQueueFromID(hab, ppib->pib_ulpid, ptib->tib_ptib2->tib2_ultid);
123 }
124 }
125 }
126 SetThreadHAB(hab);
127 dprintf(("InitPM: hmq = %x", hmq));
128 SetThreadMessageQueue(hmq);
129
130 BOOL rc = WinSetCp(hmq, GetDisplayCodepage());
131 dprintf(("InitPM: WinSetCP was %sOK", rc ? "" : "not "));
132
133 //CD polling window class
134 if(!WinRegisterClass( /* Register window class */
135 hab, /* Anchor block handle */
136 (PSZ)WIN32_CDCLASS, /* Window class name */
137 (PFNWP)Win32CDWindowProc, /* Address of window procedure */
138 0,
139 0))
140 {
141 dprintf(("WinRegisterClass Win32BaseWindow failed"));
142 return(FALSE);
143 }
144
145 //Standard Odin window class
146 if(!WinRegisterClass( /* Register window class */
147 hab, /* Anchor block handle */
148 (PSZ)WIN32_STDCLASS, /* Window class name */
149 (PFNWP)Win32WindowProc, /* Address of window procedure */
150 0,
151 NROF_WIN32WNDBYTES))
152 {
153 dprintf(("WinRegisterClass Win32BaseWindow failed"));
154 return(FALSE);
155 }
156
157 CLASSINFO FrameClassInfo;
158 if(!WinQueryClassInfo (hab, WC_FRAME, &FrameClassInfo)) {
159 dprintf (("WinQueryClassInfo WC_FRAME failed"));
160 return (FALSE);
161 }
162 pfnFrameWndProc = FrameClassInfo.pfnWindowProc;
163
164 dprintf(("WC_FRAME style %x", FrameClassInfo.flClassStyle));
165
166 if(!WinRegisterClass( /* Register window class */
167 hab, /* Anchor block handle */
168 (PSZ)WIN32_STDFRAMECLASS, /* Window class name */
169 (PFNWP)Win32FrameWindowProc, /* Address of window procedure */
170 CS_FRAME,
171 FrameClassInfo.cbWindowData))
172 {
173 dprintf(("WinRegisterClass Win32BaseWindow failed %x", WinGetLastError(hab)));
174 return(FALSE);
175 }
176
177 WinQueryWindowRect(HWND_DESKTOP, &desktopRectl);
178 ScreenWidth = desktopRectl.xRight;
179 ScreenHeight = desktopRectl.yTop;
180
181 HDC hdc; /* Device-context handle */
182 /* context data structure */
183 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
184 NULL, NULL, NULL};
185
186 /* create memory device context */
187 hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
188
189 fOS2Look = PROFILE_GetOdinIniBool(ODINSYSTEM_SECTION, "OS2Look", FALSE);
190 if(fOS2Look)
191 {
192 CHAR szDisplay[30];
193 HMODULE hModDisplay;
194
195 SYSCOLOR_Init(FALSE); //use OS/2 colors
196
197 DspInitSystemDriverName(szDisplay, sizeof(szDisplay));
198 DosQueryModuleHandle(szDisplay, &hModDisplay);
199
200 hbmFrameMenu[0] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MINBUTTON, 0, 0);
201 hbmFrameMenu[1] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MAXBUTTON, 0, 0);
202 hbmFrameMenu[2] = GpiLoadBitmap(hdc, hModDisplay, SBMP_RESTOREBUTTON, 0, 0);
203 }
204
205 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, (PLONG)&ScreenBitsPerPel);
206 DevCloseDC(hdc);
207
208 dprintf(("InitPM: Desktop (%d,%d) bpp %d", ScreenWidth, ScreenHeight, ScreenBitsPerPel));
209 return TRUE;
210} /* End of main */
211//******************************************************************************
212//menu.cpp
213BOOL MENU_Init();
214//******************************************************************************
215void WIN32API SetWindowAppearance(int fLooks)
216{
217 if(fLooks == OS2_APPEARANCE || fLooks == OS2_APPEARANCE_SYSMENU)
218 {
219 CHAR szDisplay[30];
220 HMODULE hModDisplay;
221
222 SYSCOLOR_Init(FALSE); //use OS/2 colors
223
224 if(hbmFrameMenu[0] == 0)
225 {
226 CHAR szDisplay[30];
227 HMODULE hModDisplay;
228 HDC hdc; /* Device-context handle */
229 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
230 NULL, NULL, NULL};
231
232 /* create memory device context */
233 hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
234
235 DspInitSystemDriverName(szDisplay, sizeof(szDisplay));
236 DosQueryModuleHandle(szDisplay, &hModDisplay);
237
238 hbmFrameMenu[0] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MINBUTTON, 0, 0);
239 hbmFrameMenu[1] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MAXBUTTON, 0, 0);
240 hbmFrameMenu[2] = GpiLoadBitmap(hdc, hModDisplay, SBMP_RESTOREBUTTON, 0, 0);
241 DevCloseDC(hdc);
242 }
243 }
244 fOS2Look = fLooks;
245 MENU_Init();
246}
247//******************************************************************************
248//CD notification window class
249//******************************************************************************
250MRESULT EXPENTRY Win32CDWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
251{
252#pragma pack(1)
253 typedef struct
254 {
255 BYTE ucCommandInfo;
256 WORD usDriveUnit;
257 } ParameterBlock;
258#pragma pack()
259
260 MRESULT rc = 0;
261 static ULONG drives[26] = {0};
262 static int drivestatus[26] = {0};
263
264 switch( msg )
265 {
266 //OS/2 msgs
267 case WM_CREATE:
268 {
269 char drive[2];
270
271 //skip floppy drives
272 drive[0] = 'C';
273 drive[1] = 0;
274
275 for(int i=2;i<26;i++) {
276 drives[i] = GetDriveTypeA(drive);
277 if(drives[i] == DRIVE_CDROM_W)
278 {
279 DWORD parsize = sizeof(ParameterBlock);
280 DWORD datasize = 2;
281 WORD status = 0;
282 DWORD rc;
283 ParameterBlock parm;
284
285 parm.ucCommandInfo = 0;
286 parm.usDriveUnit = i;
287 rc = DosDevIOCtl(-1, IOCTL_DISK, DSK_GETLOCKSTATUS, &parm, sizeof(parm), &parsize,
288 &status, sizeof(status), &datasize);
289 if(rc != NO_ERROR) {
290 dprintf(("DosDevIOCtl failed with rc %d", rc));
291 drives[i] = 0;
292 continue;
293 }
294 //if no disk present, return FALSE
295 if(status & 4) {
296 drivestatus[i] = status & 4;
297 }
298 }
299 drive[0]++;
300 }
301 WinStartTimer(hab, hwnd, 17, 32*60);
302//// WinStartTimer(hab, hwnd, 17, 32*3);
303//// WinStartTimer(hab, hwnd, 17, 5000);
304 rc = (MRESULT)FALSE;
305 break;
306 }
307 case WM_TIMER:
308 {
309 for(int i=0;i<26;i++)
310 {
311 //for now only cdrom/dvd drives
312 if(drives[i] == DRIVE_CDROM_W)
313 {
314 DWORD parsize = sizeof(ParameterBlock);
315 DWORD datasize = 2;
316 WORD status = 0;
317 DWORD rc;
318 ParameterBlock parm;
319
320 parm.ucCommandInfo = 0;
321 parm.usDriveUnit = i;
322 rc = DosDevIOCtl(-1, IOCTL_DISK, DSK_GETLOCKSTATUS, &parm, sizeof(parm), &parsize,
323 &status, sizeof(status), &datasize);
324 if(rc != NO_ERROR) {
325 dprintf(("DosDevIOCtl failed with rc %d", rc));
326 return FALSE;
327 }
328 //Send WM_DEVICECHANGE message when CD status changes
329 if((status & 4) != drivestatus[i])
330 {
331 PID pidThis, pidTemp;
332 HENUM henum;
333 HWND hwndEnum;
334 DEV_BROADCAST_VOLUME volchange;
335
336 dprintf(("Disk status 0x%x", status));
337
338 volchange.dbcv_size = sizeof(volchange);
339 volchange.dbcv_devicetype = DBT_DEVTYP_VOLUME;
340 volchange.dbcv_reserved = 0;
341 volchange.dbcv_unitmask = (1 << i);
342 volchange.dbcv_flags = DBTF_MEDIA;
343
344 WinQueryWindowProcess(hwnd, &pidThis, NULL);
345
346 //Iterate over all child windows of the desktop
347 henum = WinBeginEnumWindows(HWND_DESKTOP);
348
349 SetWin32TIB();
350 while(hwndEnum = WinGetNextWindow(henum))
351 {
352 WinQueryWindowProcess(hwndEnum, &pidTemp, NULL);
353 if(pidTemp == pidThis)
354 {
355 HWND hwndWin32 = OS2ToWin32Handle(hwndEnum);
356 if(hwndWin32) {
357 SendMessageA(hwndWin32,
358 WM_DEVICECHANGE_W,
359 (status & 4) ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE,
360 (LPARAM)&volchange);
361 }
362 }
363 }
364 RestoreOS2TIB();
365 WinEndEnumWindows(henum);
366
367 drivestatus[i] = (status & 4);
368 }
369 }
370 }
371 break;
372 }
373
374 case WM_DESTROY:
375 WinStopTimer(hab, hwnd, 17);
376 break;
377
378 default:
379 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
380 }
381 return (MRESULT)rc;
382}
383//******************************************************************************
384//Win32 window message handler
385//******************************************************************************
386MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
387{
388 Win32BaseWindow *win32wnd;
389 TEB *teb;
390 MSG winMsg, *pWinMsg;
391 MRESULT rc = 0;
392 POSTMSG_PACKET *postmsg;
393 OSLIBPOINT point, ClientPoint;
394
395 //Restore our FS selector
396 SetWin32TIB();
397
398 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- BEGIN
399 teb = GetThreadTEB();
400 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
401
402//// dprintf(("window %x msg %x", (win32wnd) ? win32wnd->getWindowHandle() : 0, msg));
403
404 if(!teb || (msg != WM_CREATE && win32wnd == NULL)) {
405 dprintf(("OS2: Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
406 goto RunDefWndProc;
407 }
408//// if(teb->o.odin.fIgnoreMsgs) {
409//// goto RunDefWndProc;
410//// }
411
412 if((teb->o.odin.msgstate & 1) == 0)
413 {//message that was sent directly to our window proc handler; translate it here
414 QMSG qmsg;
415
416 qmsg.msg = msg;
417 qmsg.hwnd = hwnd;
418 qmsg.mp1 = mp1;
419 qmsg.mp2 = mp2;
420 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
421 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
422 qmsg.reserved = 0;
423
424 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
425 {//message was not translated
426 memset(&winMsg, 0, sizeof(MSG));
427 }
428 pWinMsg = &winMsg;
429 }
430 else {
431 pWinMsg = &teb->o.odin.msg;
432 teb->o.odin.msgstate++;
433 }
434 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- END
435
436 if(msg >= WIN32APP_POSTMSG) {
437 //probably win32 app user message
438 dprintf2(("Posted message %x->%x", msg, msg-WIN32APP_POSTMSG));
439 if((ULONG)mp1 == WIN32MSG_MAGICA) {
440 rc = (MRESULT)win32wnd->DispatchMsgA(pWinMsg);
441 }
442 else
443 if((ULONG)mp1 == WIN32MSG_MAGICW) {
444 rc = (MRESULT)win32wnd->DispatchMsgW(pWinMsg);
445 }
446 else {//broadcasted message
447 rc = (MRESULT)win32wnd->DispatchMsgA(pWinMsg);
448 }
449 RELEASE_WNDOBJ(win32wnd);
450 RestoreOS2TIB();
451 return rc;
452 }
453
454 switch( msg )
455 {
456 //OS/2 msgs
457 case WM_CREATE:
458 {
459 if(teb->o.odin.newWindow == 0)
460 goto createfail;
461
462 //Processing is done in after WinCreateWindow returns
463 dprintf(("OS2: WM_CREATE %x", hwnd));
464 win32wnd = (Win32BaseWindow *)teb->o.odin.newWindow;
465 win32wnd->addRef();
466 teb->o.odin.newWindow = 0;
467 if(win32wnd->MsgCreate(hwnd) == FALSE)
468 {
469 rc = (MRESULT)TRUE; //discontinue window creation
470 break;
471 }
472
473 //Create CD notification window
474 if(hwndCD == 0) {
475 hwndCD = WinCreateWindow(HWND_DESKTOP, WIN32_CDCLASS,
476 NULL, 0, 0, 0, 0, 0,
477 HWND_DESKTOP, HWND_TOP, 0, NULL, NULL);
478 }
479
480 createfail:
481 rc = (MRESULT)FALSE;
482 break;
483 }
484
485 case WM_QUIT:
486 dprintf(("OS2: WM_QUIT %x", hwnd));
487 win32wnd->MsgQuit();
488 break;
489
490 case WM_CLOSE:
491 dprintf(("OS2: WM_CLOSE %x", hwnd));
492 win32wnd->MsgClose();
493 break;
494
495 case WM_DESTROY:
496 dprintf(("OS2: WM_DESTROY %x", hwnd));
497 win32wnd->MsgDestroy();
498 WinSetVisibleRegionNotify(hwnd, FALSE);
499 goto RunDefWndProc;
500
501 case WM_ENABLE:
502 dprintf(("OS2: WM_ENABLE %x", hwnd));
503 break;
504
505 case WM_SHOW:
506 dprintf(("OS2: WM_SHOW %x %d", hwnd, mp1));
507 win32wnd->MsgShow((ULONG)mp1);
508 break;
509
510 case WM_ACTIVATE:
511 {
512 ULONG flags = WinQueryWindowULong(hwnd, OFFSET_WIN32FLAGS);
513
514 dprintf(("OS2: WM_ACTIVATE %x %x %x", hwnd, mp1, mp2));
515 WinSetWindowULong(hwnd, OFFSET_WIN32FLAGS, SHORT1FROMMP(mp1) ? (flags | WINDOWFLAG_ACTIVE):(flags & ~WINDOWFLAG_ACTIVE));
516 if(win32wnd->IsWindowCreated())
517 {
518 win32wnd->MsgActivate((LOWORD(pWinMsg->wParam) == WA_ACTIVE_W) ? 1 : 0, HIWORD(pWinMsg->wParam), pWinMsg->lParam, (HWND)mp2);
519 }
520 break;
521 }
522
523 case WM_SIZE:
524 {
525 dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp1)));
526 win32wnd->SetVisibleRegionChanged(TRUE);
527 goto RunDefWndProc;
528 }
529
530
531 case WM_VRNENABLED:
532 dprintf(("OS2: WM_VRNENABLED %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
533 //Always call handler; even if mp1 is 0. If we don't do this, the
534 //DivX 4 player will never be allowed to draw after putting another window
535 //on top of it.
536 win32wnd->callVisibleRgnNotifyProc(TRUE);
537 if(!win32wnd->isComingToTop() && ((win32wnd->getExStyle() & WS_EX_TOPMOST_W) == WS_EX_TOPMOST_W))
538 {
539 HWND hwndrelated;
540 Win32BaseWindow *topwindow;
541
542 win32wnd->setComingToTop(TRUE);
543
544 hwndrelated = WinQueryWindow(hwnd, QW_PREV);
545 dprintf(("WM_VRNENABLED hwndrelated = %x (hwnd=%x)", hwndrelated, hwnd));
546 topwindow = Win32BaseWindow::GetWindowFromOS2Handle(hwndrelated);
547 if(topwindow == NULL || ((win32wnd->getExStyle() & WS_EX_TOPMOST_W) == 0)) {
548 //put window at the top of z order
549 WinSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER );
550 }
551 if(topwindow) RELEASE_WNDOBJ(topwindow);
552
553 win32wnd->setComingToTop(FALSE);
554 break;
555 }
556 goto RunDefWndProc;
557
558 case WM_VRNDISABLED:
559 dprintf(("OS2: WM_VRNDISABLED %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
560 //visible region is about to change or WinLockWindowUpdate called
561 //suspend window drawing
562 win32wnd->callVisibleRgnNotifyProc(FALSE);
563 goto RunDefWndProc;
564
565 case WIN32APP_SETFOCUSMSG:
566 //PM doesn't allow SetFocus calls during WM_SETFOCUS message processing;
567 //must delay this function call
568 //mp1 = win32 window handle
569 //mp2 = top parent if activation required
570 dprintf(("USER32: Delayed SetFocus %x %x %x call!", teb->o.odin.hwndFocus, mp1, mp2));
571 if(teb->o.odin.hwndFocus) {
572 RELEASE_WNDOBJ(win32wnd);
573 win32wnd = Win32BaseWindow::GetWindowFromHandle(teb->o.odin.hwndFocus);
574 if(win32wnd) {
575 if(mp2) {
576 SetActiveWindow((HWND)mp2);
577 }
578 if(!IsWindow(win32wnd->getWindowHandle())) break; //abort if window destroyed
579 WinFocusChange(HWND_DESKTOP, win32wnd->getOS2WindowHandle(), FC_NOSETACTIVE);
580 }
581 else DebugInt3();
582 }
583 break;
584
585 case WM_SETFOCUS:
586 {
587 HWND hwndFocus = (HWND)mp1;
588
589 dprintf(("OS2: WM_SETFOCUS %x %x (%x) %d", win32wnd->getWindowHandle(), mp1, OS2ToWin32Handle(hwndFocus), mp2));
590
591 //PM doesn't allow SetFocus calls during WM_SETFOCUS message processing;
592 //must delay this function call
593
594 teb->o.odin.fWM_SETFOCUS = TRUE;
595 teb->o.odin.hwndFocus = 0;
596 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC)
597 {
598 //another (non-win32) application's window
599 //set to NULL (allowed according to win32 SDK) to avoid problems
600 hwndFocus = NULL;
601 }
602 if((ULONG)mp2 == TRUE) {
603 HWND hwndFocusWin32 = OS2ToWin32Handle(hwndFocus);
604 recreateCaret (hwndFocusWin32);
605 win32wnd->MsgSetFocus(hwndFocusWin32);
606 }
607 else win32wnd->MsgKillFocus(OS2ToWin32Handle(hwndFocus));
608 teb->o.odin.fWM_SETFOCUS = FALSE;
609
610 break;
611 }
612
613 //**************************************************************************
614 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
615 //**************************************************************************
616
617 case WM_BUTTON1DOWN:
618 case WM_BUTTON1UP:
619 case WM_BUTTON1DBLCLK:
620 case WM_BUTTON2DOWN:
621 case WM_BUTTON2UP:
622 case WM_BUTTON2DBLCLK:
623 case WM_BUTTON3DOWN:
624 case WM_BUTTON3UP:
625 case WM_BUTTON3DBLCLK:
626 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
627 RELEASE_WNDOBJ(win32wnd);
628 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
629 }
630 if(win32wnd)
631 win32wnd->MsgButton(pWinMsg);
632
633 rc = (MRESULT)TRUE;
634 break;
635
636 case WM_BUTTON2MOTIONSTART:
637 case WM_BUTTON2MOTIONEND:
638 case WM_BUTTON2CLICK:
639 case WM_BUTTON1MOTIONSTART:
640 case WM_BUTTON1MOTIONEND:
641 case WM_BUTTON1CLICK:
642 case WM_BUTTON3MOTIONSTART:
643 case WM_BUTTON3MOTIONEND:
644 case WM_BUTTON3CLICK:
645 rc = (MRESULT)TRUE;
646 break;
647
648 case WM_MOUSEMOVE:
649 {
650 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
651 RELEASE_WNDOBJ(win32wnd);
652 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
653 }
654 if(win32wnd)
655 win32wnd->MsgMouseMove(pWinMsg);
656 break;
657 }
658
659 case WM_CONTROL:
660 goto RunDefWndProc;
661
662 case WM_COMMAND:
663 dprintf(("OS2: WM_COMMAND %x %x %x", hwnd, mp1, mp2));
664 win32wnd->DispatchMsgA(pWinMsg);
665 break;
666
667 case WM_SYSCOMMAND:
668 dprintf(("OS2: WM_SYSCOMMAND %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
669 win32wnd->DispatchMsgA(pWinMsg);
670 break;
671
672 case WM_RENDERFMT:
673 case WM_RENDERALLFMTS:
674 case WM_DESTROYCLIPBOARD:
675 win32wnd->DispatchMsgA(pWinMsg);
676 break;
677
678 case WM_CHAR_SPECIAL:
679 /* NO BREAK! FALLTHRU CASE! */
680
681 case WM_CHAR:
682 dprintf(("OS2: WM_CHAR %x %x %x, %x %x", win32wnd->getWindowHandle(), mp1, mp2, pWinMsg->wParam, pWinMsg->lParam));
683 win32wnd->MsgChar(pWinMsg);
684 break;
685
686 case WM_TIMER:
687 dprintf(("OS2: WM_TIMER %x %x time %x", win32wnd->getWindowHandle(), pWinMsg->wParam, GetTickCount()));
688 win32wnd->DispatchMsgA(pWinMsg);
689 goto RunDefWndProc;
690
691 case WM_SETWINDOWPARAMS:
692 {
693 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
694
695 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
696 if(wndParams->fsStatus & WPM_TEXT) {
697 win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText);
698 }
699 goto RunDefWndProc;
700 }
701
702 case WM_QUERYWINDOWPARAMS:
703 {
704 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
705 ULONG textlen;
706 PSZ wintext;
707
708 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
709 {
710 if(wndpars->fsStatus & WPM_TEXT)
711 win32wnd->MsgGetText(wndpars->pszText, wndpars->cchText);
712 if(wndpars->fsStatus & WPM_CCHTEXT)
713 wndpars->cchText = win32wnd->MsgGetTextLength();
714
715 wndpars->fsStatus = 0;
716 wndpars->cbCtlData = 0;
717 wndpars->cbPresParams = 0;
718 rc = (MRESULT)TRUE;
719 break;
720 }
721 goto RunDefWndProc;
722 }
723
724 case WM_PAINT:
725 {
726 RECTL rectl;
727 BOOL rc;
728
729 rc = WinQueryUpdateRect(hwnd, &rectl);
730 dprintf(("OS2: WM_PAINT %x (%d,%d) (%d,%d) rc=%d", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop, rc));
731
732 if(rc && win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
733 rectl.yBottom != rectl.yTop))
734 {
735 win32wnd->DispatchMsgA(pWinMsg);
736 }
737 else goto RunDefWndProc;
738 break;
739 }
740
741 case WM_ERASEBACKGROUND:
742 {
743 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
744 rc = (MRESULT)FALSE;
745 break;
746 }
747
748 case WM_CALCVALIDRECTS:
749 dprintf(("OS2: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
750 rc = (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
751 break;
752
753 case WM_REALIZEPALETTE:
754 {
755 dprintf(("OS2: WM_REALIZEPALETTE"));
756 goto RunDefWndProc;
757 }
758
759 case WM_HSCROLL:
760 case WM_VSCROLL:
761 dprintf(("OS2: %s %x %x %x", (msg == WM_HSCROLL) ? "WM_HSCROLL" : "WM_VSCROLL", win32wnd->getWindowHandle(), mp1, mp2));
762 win32wnd->DispatchMsgA(pWinMsg);
763 break;
764
765 case WM_DDE_INITIATE:
766 case WM_DDE_INITIATEACK:
767 case WM_DDE_REQUEST:
768 case WM_DDE_ACK:
769 case WM_DDE_DATA:
770 case WM_DDE_ADVISE:
771 case WM_DDE_UNADVISE:
772 case WM_DDE_POKE:
773 case WM_DDE_EXECUTE:
774 case WM_DDE_TERMINATE:
775 dprintf(("OS2: WM_DDE %x %x", msg, win32wnd->getWindowHandle()));
776 goto RunDefWndProc;
777
778 case WM_INITMENU:
779 case WM_MENUSELECT:
780 case WM_MENUEND:
781 case WM_NEXTMENU:
782 case WM_SYSCOLORCHANGE:
783 case WM_SYSVALUECHANGED:
784 case WM_SETSELECTION:
785 case WM_PPAINT:
786 case WM_PSETFOCUS:
787 case WM_PSYSCOLORCHANGE:
788 case WM_PSIZE:
789 case WM_PACTIVATE:
790 case WM_PCONTROL:
791 case WM_HELP:
792 case WM_APPTERMINATENOTIFY:
793 case WM_PRESPARAMCHANGED:
794 case WM_DRAWITEM:
795 case WM_MEASUREITEM:
796 case WM_CONTROLPOINTER:
797 case WM_QUERYDLGCODE:
798 case WM_SUBSTITUTESTRING:
799 case WM_MATCHMNEMONIC:
800 case WM_SAVEAPPLICATION:
801 case WM_SEMANTICEVENT:
802 default:
803 dprintf2(("OS2: RunDefWndProc hwnd %x msg %x mp1 %x mp2 %x", hwnd, msg, mp1, mp2));
804 goto RunDefWndProc;
805 }
806 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
807 RestoreOS2TIB();
808 return (MRESULT)rc;
809
810RunDefWndProc:
811// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
812 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
813 RestoreOS2TIB();
814 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
815} /* End of Win32WindowProc */
816//******************************************************************************
817//******************************************************************************
818MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
819{
820 POSTMSG_PACKET *postmsg;
821 OSLIBPOINT point, ClientPoint;
822 Win32BaseWindow *win32wnd;
823 TEB *teb;
824 MRESULT rc = 0;
825 MSG winMsg, *pWinMsg;
826
827 //Restore our FS selector
828 SetWin32TIB();
829
830 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- BEGIN
831 teb = GetThreadTEB();
832 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwnd);
833
834 if(!teb || (msg != WM_CREATE && win32wnd == NULL)) {
835 dprintf(("PMFRAME: Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
836 goto RunDefFrameWndProc;
837 }
838//// if(teb->o.odin.fIgnoreMsgs) {
839//// goto RunDefWndProc;
840//// }
841
842 if((teb->o.odin.msgstate & 1) == 0)
843 {//message that was sent directly to our window proc handler; translate it here
844 QMSG qmsg;
845
846 qmsg.msg = msg;
847 qmsg.hwnd = hwnd;
848 qmsg.mp1 = mp1;
849 qmsg.mp2 = mp2;
850 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
851 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
852 qmsg.reserved = 0;
853
854 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
855 {//message was not translated
856 memset(&winMsg, 0, sizeof(MSG));
857 }
858 pWinMsg = &winMsg;
859 }
860 else {
861 pWinMsg = &teb->o.odin.msg;
862 teb->o.odin.msgstate++;
863 }
864 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- END
865
866 switch( msg )
867 {
868 case WM_CREATE:
869 {
870 //WM_CREATE handled during client window creation
871 dprintf(("PMFRAME: WM_CREATE %x", hwnd));
872 goto RunDefFrameWndProc;
873 }
874
875 case WM_PAINT:
876 {
877 RECTL rectl;
878
879 HPS hps = WinBeginPaint(hwnd, NULL, &rectl);
880 dprintf(("PMFRAME: WM_PAINT %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop));
881
882 if(win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
883 rectl.yBottom != rectl.yTop))
884 {
885 PRECT pClient = win32wnd->getClientRectPtr();
886 PRECT pWindow = win32wnd->getWindowRect();
887
888 if(!(pClient->left == 0 && pClient->top == 0 &&
889 win32wnd->getClientHeight() == win32wnd->getWindowHeight() &&
890 win32wnd->getClientWidth() == win32wnd->getWindowWidth()))
891 {
892 RECT rectUpdate;
893
894 mapOS2ToWin32Rect(win32wnd->getWindowHeight(), (PRECTLOS2)&rectl, &rectUpdate);
895 win32wnd->MsgNCPaint(&rectUpdate);
896 }
897 }
898 WinEndPaint(hps);
899 break;
900 }
901
902 case WM_ERASEBACKGROUND:
903 {
904 dprintf(("PMFRAME:WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
905 rc = (MRESULT)FALSE;
906 break;
907 }
908
909 //**************************************************************************
910 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
911 //**************************************************************************
912
913 case WM_BUTTON1DOWN:
914 case WM_BUTTON1UP:
915 case WM_BUTTON1DBLCLK:
916 case WM_BUTTON2DOWN:
917 case WM_BUTTON2UP:
918 case WM_BUTTON2DBLCLK:
919 case WM_BUTTON3DOWN:
920 case WM_BUTTON3UP:
921 case WM_BUTTON3DBLCLK:
922 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
923 RELEASE_WNDOBJ(win32wnd);
924 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
925 }
926 if(win32wnd)
927 win32wnd->MsgButton(pWinMsg);
928
929 rc = (MRESULT)TRUE;
930 break;
931
932 case WM_BUTTON2MOTIONSTART:
933 case WM_BUTTON2MOTIONEND:
934 case WM_BUTTON2CLICK:
935 case WM_BUTTON1MOTIONSTART:
936 case WM_BUTTON1MOTIONEND:
937 case WM_BUTTON1CLICK:
938 case WM_BUTTON3MOTIONSTART:
939 case WM_BUTTON3MOTIONEND:
940 case WM_BUTTON3CLICK:
941 rc = (MRESULT)TRUE;
942 break;
943
944 case WM_MOUSEMOVE:
945 {
946 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
947 RELEASE_WNDOBJ(win32wnd);
948 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
949 }
950 if(win32wnd)
951 win32wnd->MsgMouseMove(pWinMsg);
952 break;
953 }
954
955 case WM_ADJUSTWINDOWPOS:
956 {
957 PSWP pswp = (PSWP)mp1;
958 SWP swpOld;
959 WINDOWPOS wp,wpOld;
960 ULONG ulFlags;
961 ULONG ret = 0;
962 HWND hParent = NULLHANDLE, hwndAfter;
963
964 dprintf(("PMFRAME:WM_ADJUSTWINDOWPOS %x %x %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
965
966 ulFlags = pswp->fl;
967
968 if(win32wnd->IsParentChanging()) {
969 rc = 0;
970 break;
971 }
972
973 if(pswp->fl & SWP_NOADJUST) {
974 //ignore weird messages (TODO: why are they sent?)
975 dprintf(("WARNING: WM_ADJUSTWINDOWPOS with SWP_NOADJUST flag!!"));
976 break;
977 }
978 //CB: show dialog in front of owner
979 if (win32wnd->IsModalDialogOwner())
980 {
981 dprintf(("win32wnd->IsModalDialogOwner %x", win32wnd->getWindowHandle()));
982 pswp->fl |= SWP_ZORDER;
983 pswp->hwndInsertBehind = win32wnd->getOS2HwndModalDialog();
984 if (pswp->fl & SWP_ACTIVATE)
985 {
986 pswp->fl &= ~SWP_ACTIVATE;
987 WinSetWindowPos(win32wnd->getOS2HwndModalDialog(),0,0,0,0,0,SWP_ACTIVATE);
988 }
989 }
990
991 if(!win32wnd->CanReceiveSizeMsgs())
992 break;
993
994 WinQueryWindowPos(hwnd, &swpOld);
995 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
996 if (win32wnd->isChild()) {
997 if(win32wnd->getParent()) {
998 hParent = win32wnd->getParent()->getOS2WindowHandle();
999 }
1000 else goto RunDefFrameWndProc;
1001 }
1002 }
1003 hwndAfter = pswp->hwndInsertBehind;
1004 if(win32wnd->getParent()) {
1005 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(), hwnd);
1006 }
1007 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1008
1009 wp.hwnd = win32wnd->getWindowHandle();
1010 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1011 {
1012 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1013 dprintf2(("SWP_ZORDER: %x %x", pswp->hwndInsertBehind, (wndAfter) ? wndAfter->getWindowHandle() : 0));
1014 if(wndAfter) {
1015 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1016 RELEASE_WNDOBJ(wndAfter);
1017 }
1018 else wp.hwndInsertAfter = HWND_TOP_W;
1019 }
1020
1021 wpOld = wp;
1022 win32wnd->MsgPosChanging((LPARAM)&wp);
1023
1024 if(win32wnd->getOldStyle() != win32wnd->getStyle())
1025 {
1026 OSLibSetWindowStyle(win32wnd->getOS2FrameWindowHandle(), win32wnd->getOS2WindowHandle(), win32wnd->getStyle(), win32wnd->getExStyle());
1027 if(fOS2Look) {
1028 DWORD dwOldStyle = win32wnd->getOldStyle();
1029 DWORD dwStyle = win32wnd->getStyle();
1030
1031 if((dwOldStyle & WS_MINIMIZE_W) && !(dwStyle & WS_MINIMIZE_W)) {
1032 //SC_RESTORE -> SC_MINIMIZE
1033 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), 0, SC_RESTORE, SC_MINIMIZE, hbmFrameMenu[0]);
1034 }
1035 else
1036 if((dwOldStyle & WS_MAXIMIZE_W) && !(dwStyle & WS_MAXIMIZE_W)) {
1037 //SC_RESTORE -> SC_MAXIMIZE
1038 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_RESTORE, SC_MAXIMIZE, hbmFrameMenu[1]);
1039 }
1040 else
1041 if(!(dwOldStyle & WS_MINIMIZE_W) && (dwStyle & WS_MINIMIZE_W)) {
1042 //SC_MINIMIZE -> SC_RESTORE
1043 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), 0, SC_MINIMIZE, SC_RESTORE, hbmFrameMenu[2]);
1044 }
1045 else
1046 if(!(dwOldStyle & WS_MAXIMIZE_W) && (dwStyle & WS_MAXIMIZE_W)) {
1047 //SC_MAXIMIZE -> SC_RESTORE
1048 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_MAXIMIZE, SC_RESTORE, hbmFrameMenu[2]);
1049 }
1050 }
1051 }
1052
1053 if ((wp.hwndInsertAfter != wpOld.hwndInsertAfter) ||
1054 (wp.x != wpOld.x) || (wp.y != wpOld.y) || (wp.cx != wpOld.cx) || (wp.cy != wpOld.cy) || (wp.flags != wpOld.flags))
1055 {
1056 ULONG flags = pswp->fl; //make a backup copy; OSLibMapWINDOWPOStoSWP will modify it
1057
1058 dprintf(("PMFRAME:WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
1059 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
1060
1061 if(win32wnd->getParent()) {
1062 OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, win32wnd->getParent()->getClientHeight(),
1063 hwnd);
1064 }
1065 else OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1066
1067 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
1068
1069 //OSLibMapWINDOWPOStoSWP can add flags, but we must not let it remove flags!
1070 if(pswp->fl & SWP_SIZE)
1071 flags |= SWP_SIZE;
1072
1073 if(pswp->fl & SWP_MOVE)
1074 flags |= SWP_MOVE;
1075
1076 pswp->fl = flags; //restore flags
1077
1078 pswp->fl |= SWP_NOADJUST;
1079 pswp->hwndInsertBehind = hwndAfter;
1080 pswp->hwnd = hwnd;
1081
1082 ret = 0xf;
1083 }
1084adjustend:
1085 //The next part needs to be done for top-level windows only
1086 if(!((win32wnd->getStyle() & (WS_POPUP_W|WS_CHILD_W)) == WS_CHILD_W))
1087 {
1088 //Setting these flags is necessary to avoid activation/focus problems
1089 if(ulFlags & SWP_DEACTIVATE) {
1090 ret |= AWP_DEACTIVATE;
1091 }
1092 if(ulFlags & SWP_ACTIVATE)
1093 {
1094 if(ulFlags & SWP_ZORDER) {
1095 dprintf(("Set FF_NOACTIVATESWP"));
1096 ULONG ulFrameFlags = WinQueryWindowUShort(hwnd, QWS_FLAGS);
1097 WinSetWindowUShort(hwnd, QWS_FLAGS, ulFrameFlags | FF_NOACTIVATESWP);
1098 }
1099
1100 if(!(ulFlags & SWP_SHOW))
1101 {
1102 ret |= AWP_ACTIVATE;
1103 }
1104 else
1105 {
1106 FrameSetFocus(hwnd);
1107 }
1108 }
1109 }
1110 else {
1111 if(ulFlags & (SWP_ACTIVATE|SWP_FOCUSACTIVATE))
1112 {
1113 win32wnd->MsgChildActivate(TRUE);
1114 if(fOS2Look) {
1115 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1116 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, (MPARAM)1, 0);
1117 }
1118 }
1119 else
1120 if(ulFlags & (SWP_DEACTIVATE|SWP_FOCUSDEACTIVATE))
1121 {
1122 win32wnd->MsgChildActivate(FALSE);
1123 if(fOS2Look) {
1124 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1125 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, 0, 0);
1126 }
1127 }
1128 }
1129 dprintf(("WM_ADJUSTWINDOWPOS ret %x flags %x", ret, WinQueryWindowUShort(hwnd, QWS_FLAGS)));
1130 rc = (MRESULT)ret;
1131 break;
1132 }
1133
1134 case WM_WINDOWPOSCHANGED:
1135 {
1136 PSWP pswp = (PSWP)mp1,pswpOld = pswp+1;
1137 SWP swpOld = *(pswp + 1);
1138 WINDOWPOS wp;
1139 ULONG flAfp = (ULONG)mp2;
1140 HWND hParent = NULLHANDLE;
1141 RECTL rect;
1142
1143 dprintf(("PMFRAME:WM_WINDOWPOSCHANGED (%x) %x %x (%d,%d) (%d,%d)", mp2, win32wnd->getWindowHandle(), pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
1144 if(win32wnd->IsParentChanging()) {
1145 goto PosChangedEnd;
1146 }
1147
1148 //SvL: When a window is made visible, then we don't receive a
1149 // WM_VRNENABLED message (for some weird reason)
1150 if(pswp->fl & SWP_SHOW) {
1151 win32wnd->callVisibleRgnNotifyProc(TRUE);
1152 }
1153 else
1154 if(pswp->fl & SWP_HIDE) {
1155 win32wnd->callVisibleRgnNotifyProc(FALSE);
1156 }
1157
1158 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0)
1159 {
1160 if(pswp->fl & SWP_RESTORE && win32wnd->getStyle() & WS_MINIMIZE_W) {
1161 dprintf(("Restoring minimized window %x", win32wnd->getWindowHandle()));
1162 win32wnd->ShowWindow(SW_RESTORE_W);
1163 }
1164 if(pswp->fl & SWP_SHOW) {
1165 WinShowWindow(win32wnd->getOS2WindowHandle(), 1);
1166 }
1167 else
1168 if(pswp->fl & SWP_HIDE) {
1169 WinShowWindow(win32wnd->getOS2WindowHandle(), 0);
1170 }
1171 //MUST call the old frame window proc!
1172 goto RunDefFrameWndProc;
1173 }
1174
1175 if(pswp->fl & (SWP_MOVE | SWP_SIZE))
1176 {
1177 if(win32wnd->isChild())
1178 {
1179 if(win32wnd->getParent()) {
1180 hParent = win32wnd->getParent()->getOS2WindowHandle();
1181 }
1182 else goto PosChangedEnd; //parent has just been destroyed
1183 }
1184 }
1185
1186
1187 if(win32wnd->getParent()) {
1188 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
1189 hwnd);
1190 }
1191 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1192
1193 wp.hwnd = win32wnd->getWindowHandle();
1194 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1195 {
1196 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1197 dprintf2(("SWP_ZORDER: %x %x", pswp->hwndInsertBehind, (wndAfter) ? wndAfter->getWindowHandle() : 0));
1198 if(wndAfter) {
1199 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1200 RELEASE_WNDOBJ(wndAfter);
1201 }
1202 else wp.hwndInsertAfter = HWND_TOP_W;
1203 }
1204
1205 if(pswp->fl & SWP_SHOW) {
1206 WinShowWindow(win32wnd->getOS2WindowHandle(), 1);
1207 }
1208 else
1209 if(pswp->fl & SWP_HIDE) {
1210 WinShowWindow(win32wnd->getOS2WindowHandle(), 0);
1211 }
1212
1213 if(flAfp & AWP_ACTIVATE)
1214 {
1215 FrameSetFocus(hwnd);
1216 }
1217
1218#ifndef USE_CALCVALIDRECT
1219 if((pswp->fl & (SWP_MOVE | SWP_SIZE)))
1220 {
1221 //CB: todo: use result for WM_CALCVALIDRECTS
1222 //Get old client rectangle (for invalidation of frame window parts later on)
1223 //Use new window height to calculate the client area
1224 mapWin32ToOS2Rect(pswp->cy, win32wnd->getClientRectPtr(), (PRECTLOS2)&rect);
1225
1226 //Note: Also updates the new window rectangle
1227 win32wnd->MsgFormatFrame(&wp);
1228
1229 if(win32wnd->isOwnDC()) {
1230 setPageXForm(win32wnd, (pDCData)GpiQueryDCData(win32wnd->getOwnDC()));
1231 }
1232
1233 if(win32wnd->CanReceiveSizeMsgs())
1234 win32wnd->MsgPosChanged((LPARAM)&wp);
1235
1236 if((pswp->fl & SWP_SIZE) && ((pswp->cx != pswpOld->cx) || (pswp->cy != pswpOld->cy)))
1237 {
1238 //redraw the frame (to prevent unnecessary client updates)
1239 BOOL redrawAll = FALSE;
1240
1241 dprintf2(("WM_WINDOWPOSCHANGED: redraw frame"));
1242 if (win32wnd->getWindowClass())
1243 {
1244 DWORD dwStyle = win32wnd->getWindowClass()->getClassLongA(GCL_STYLE_W);
1245
1246 if ((dwStyle & CS_HREDRAW_W) && (pswp->cx != pswpOld->cx))
1247 redrawAll = TRUE;
1248 else
1249 if ((dwStyle & CS_VREDRAW_W) && (pswp->cy != pswpOld->cy))
1250 redrawAll = TRUE;
1251 }
1252 else redrawAll = TRUE;
1253
1254 if(win32wnd->IsMixMaxStateChanging()) {
1255 dprintf(("WM_CALCVALIDRECT: window changed min/max/restore state, invalidate entire window"));
1256 redrawAll = TRUE;
1257 }
1258
1259 if (redrawAll)
1260 {
1261 //CB: redraw all children for now
1262 // -> problems with update region if we don't do it
1263 // todo: rewrite whole handling
1264 WinInvalidateRect(hwnd,NULL,TRUE);
1265 }
1266 else
1267 {
1268 HPS hps = WinGetPS(hwnd);
1269 RECTL frame,client,arcl[4];
1270
1271 WinQueryWindowRect(hwnd,&frame);
1272
1273 //top
1274 arcl[0].xLeft = 0;
1275 arcl[0].xRight = frame.xRight;
1276 arcl[0].yBottom = rect.yTop;
1277 arcl[0].yTop = frame.yTop;
1278 //right
1279 arcl[1].xLeft = rect.xRight;
1280 arcl[1].xRight = frame.xRight;
1281 arcl[1].yBottom = 0;
1282 arcl[1].yTop = frame.yTop;
1283 //left
1284 arcl[2].xLeft = 0;
1285 arcl[2].xRight = rect.xLeft;
1286 arcl[2].yBottom = 0;
1287 arcl[2].yTop = frame.yTop;
1288 //bottom
1289 arcl[3].xLeft = 0;
1290 arcl[3].xRight = frame.xRight;
1291 arcl[3].yBottom = 0;
1292 arcl[3].yTop = rect.yBottom;
1293
1294 HRGN hrgn = GpiCreateRegion(hps,4,(PRECTL)&arcl);
1295
1296 WinInvalidateRegion(hwnd,hrgn,FALSE);
1297 GpiDestroyRegion(hps,hrgn);
1298 WinReleasePS(hps);
1299 }
1300 }
1301 }
1302 else
1303 {
1304#endif //USE_CALCVALIDRECT
1305 if(win32wnd->CanReceiveSizeMsgs())
1306 win32wnd->MsgPosChanged((LPARAM)&wp);
1307#ifndef USE_CALCVALIDRECT
1308 }
1309#endif
1310
1311PosChangedEnd:
1312 rc = (MRESULT)FALSE;
1313 break;
1314 }
1315
1316 case WM_CALCVALIDRECTS:
1317#ifdef USE_CALCVALIDRECT
1318 {
1319 PRECTL oldRect = (PRECTL)mp1, newRect = oldRect+1;
1320 PSWP pswp = (PSWP)mp2;
1321 SWP swpOld;
1322 WINDOWPOS wp;
1323 RECTL newClientRect, oldClientRect;
1324 ULONG nccalcret;
1325// UINT res = CVR_ALIGNLEFT | CVR_ALIGNTOP;
1326 UINT res = 0;
1327
1328 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
1329
1330 //Get old position info
1331 WinQueryWindowPos(hwnd, &swpOld);
1332
1333 if(win32wnd->getParent()) {
1334 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
1335 win32wnd->getParent()->getClientRectPtr()->left,
1336 win32wnd->getParent()->getClientRectPtr()->top,
1337 hwnd);
1338 }
1339 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), 0, 0, hwnd);
1340
1341 wp.hwnd = win32wnd->getWindowHandle();
1342 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1343 {
1344 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1345 if(wndAfter) {
1346 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1347 RELEASE_WNDOBJ(wndAfter);
1348 }
1349 else wp.hwndInsertAfter = HWND_TOP_W;
1350 }
1351
1352 //Get old client rectangle
1353 mapWin32ToOS2Rect(oldRect->yTop - oldRect->yBottom, win32wnd->getClientRectPtr(), (PRECTLOS2)&oldClientRect);
1354
1355 //Note: Also updates the new window rectangle
1356 nccalcret = win32wnd->MsgFormatFrame(&wp);
1357
1358 //Get new client rectangle
1359 mapWin32ToOS2Rect(pswp->cy, win32wnd->getClientRectPtr(), (PRECTLOS2)&newClientRect);
1360
1361 if(nccalcret == 0) {
1362 res = CVR_ALIGNTOP | CVR_ALIGNLEFT;
1363 }
1364 else {
1365 if(nccalcret & WVR_ALIGNTOP_W) {
1366 res |= CVR_ALIGNTOP;
1367 }
1368 else
1369 if(nccalcret & WVR_ALIGNBOTTOM_W) {
1370 res |= CVR_ALIGNBOTTOM;
1371 }
1372
1373 if(nccalcret & WVR_ALIGNLEFT_W) {
1374 res |= CVR_ALIGNLEFT;
1375 }
1376 else
1377 if(nccalcret & WVR_ALIGNRIGHT_W) {
1378 res |= CVR_ALIGNRIGHT;
1379 }
1380
1381 if(nccalcret & WVR_REDRAW_W) {//WVR_REDRAW_W = (WVR_HREDRAW | WVR_VREDRAW)
1382 res |= CVR_REDRAW;
1383 }
1384 else
1385 if(nccalcret & WVR_VALIDRECTS_W) {
1386 //TODO:
1387 //res = 0;
1388 }
1389 }
1390 if(win32wnd->IsMixMaxStateChanging()) {
1391 dprintf(("WM_CALCVALIDRECT: window changed min/max/restore state, invalidate entire window"));
1392 res |= CVR_REDRAW;
1393 }
1394 if(res == (CVR_ALIGNTOP|CVR_ALIGNLEFT)) {
1395 oldRect->xRight -= oldClientRect.xLeft;
1396 oldRect->yBottom += oldClientRect.yBottom;
1397 newRect->xRight -= newClientRect.xLeft;
1398 newRect->yBottom += newClientRect.yBottom;
1399 }
1400 rc = res;
1401 break;
1402 }
1403#else
1404 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
1405 rc = (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
1406 break;
1407#endif
1408
1409 case WM_CALCFRAMERECT:
1410 dprintf(("PMFRAME:WM_CALCFRAMERECT %x", win32wnd->getWindowHandle()));
1411 rc = (MRESULT)TRUE;
1412 break;
1413
1414 case WM_QUERYCTLTYPE:
1415 // This is a frame window
1416 dprintf(("PMFRAME:WM_QUERYCTLTYPE %x", win32wnd->getWindowHandle()));
1417 rc = (MRESULT)CCT_FRAME;
1418 break;
1419
1420#ifdef DEBUG
1421 case WM_QUERYFOCUSCHAIN:
1422 dprintf2(("PMFRAME:WM_QUERYFOCUSCHAIN %x fsCmd %x parent %x", win32wnd->getWindowHandle(), SHORT1FROMMP(mp1), (mp2) ? OS2ToWin32Handle((DWORD)mp2) : 0));
1423
1424 RestoreOS2TIB();
1425 rc = pfnFrameWndProc(hwnd, msg, mp1, mp2);
1426 SetWin32TIB();
1427 dprintf2(("PMFRAME:WM_QUERYFOCUSCHAIN %x fsCmd %x parent %x returned %x", win32wnd->getWindowHandle(), SHORT1FROMMP(mp1), (mp2) ? OS2ToWin32Handle((DWORD)mp2) : 0, (rc) ? OS2ToWin32Handle((DWORD)rc) : 0));
1428 break;
1429// goto RunDefFrameWndProc;
1430#endif
1431
1432 case WM_FOCUSCHANGE:
1433 {
1434 HWND hwndFocus = (HWND)mp1;
1435 HWND hwndLoseFocus, hwndGainFocus;
1436 USHORT usSetFocus = SHORT1FROMMP(mp2);
1437 USHORT fsFocusChange = SHORT2FROMMP(mp2);
1438
1439 //Save window that gains focus so we can determine which
1440 //process we lose activation to
1441 hwndFocusChange = (HWND)mp1;
1442
1443 dprintf(("PMFRAME:WM_FOCUSCHANGE %x %x (%x) %x %x", win32wnd->getWindowHandle(), OS2ToWin32Handle(hwndFocus), hwndFocus, usSetFocus, fsFocusChange));
1444 goto RunDefFrameWndProc;
1445 }
1446
1447#ifdef DEBUG
1448 case WM_SETFOCUS:
1449 {
1450 dprintf(("PMFRAME: WM_SETFOCUS %x %x", win32wnd->getWindowHandle(), hwnd));
1451 goto RunDefFrameWndProc;
1452 }
1453#endif
1454
1455 case WM_ACTIVATE:
1456 {
1457 HWND hwndTitle;
1458 USHORT flags = WinQueryWindowUShort(hwnd,QWS_FLAGS);
1459
1460 dprintf(("PMFRAME: WM_ACTIVATE %x %x %x", win32wnd->getWindowHandle(), mp1, OS2ToWin32Handle((DWORD)mp2)));
1461 if (win32wnd->IsWindowCreated())
1462 {
1463 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
1464 if(fOS2Look) {
1465 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1466 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, mp1, 0);
1467 }
1468 if(SHORT1FROMMP(mp1) == 0) {
1469 //deactivate
1470 WinSendDlgItemMsg(hwnd, FID_CLIENT, WM_ACTIVATE, mp1, mp2);
1471 }
1472 PID pidThis, pidPartner, pidTemp;
1473 TID tidPartner;
1474 HENUM henum;
1475 HWND hwndEnum;
1476
1477 WinQueryWindowProcess(hwnd, &pidThis, NULL);
1478 WinQueryWindowProcess(hwndFocusChange, &pidPartner, &tidPartner);
1479
1480 if(pidThis != pidPartner) {
1481 //Gain or lose activation to window in other process
1482 //must send WM_ACTIVATEAPP to top-level windows
1483
1484 //Iterate over all child windows of the desktop
1485 henum = WinBeginEnumWindows(HWND_DESKTOP);
1486
1487 while(hwndEnum = WinGetNextWindow(henum))
1488 {
1489 WinQueryWindowProcess(hwndEnum, &pidTemp, NULL);
1490 if(pidTemp == pidThis)
1491 {
1492 SendMessageA(OS2ToWin32Handle(hwndEnum), WM_ACTIVATEAPP_W, (WPARAM)SHORT1FROMMP(mp1), (LPARAM)tidPartner);
1493 }
1494 }
1495 WinEndEnumWindows(henum);
1496 }
1497 if(SHORT1FROMMP(mp1)) {
1498 //activate
1499 WinSendDlgItemMsg(hwnd, FID_CLIENT, WM_ACTIVATE, mp1, mp2);
1500 }
1501
1502 //CB: show owner behind the dialog
1503 if (win32wnd->IsModalDialog())
1504 {
1505 if(win32wnd->getOwner()) {
1506 Win32BaseWindow *topOwner = Win32BaseWindow::GetWindowFromHandle(win32wnd->getOwner()->GetTopParent());
1507
1508 if (topOwner) {
1509 WinSetWindowPos(topOwner->getOS2FrameWindowHandle(),hwnd,0,0,0,0,SWP_ZORDER);
1510 RELEASE_WNDOBJ(topOwner);
1511 }
1512 }
1513 }
1514 }
1515 else
1516 {
1517 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
1518 }
1519 rc = 0;
1520 break;
1521 }
1522
1523 case WM_ENABLE:
1524 dprintf(("PMFRAME: WM_ENABLE %x", hwnd));
1525 win32wnd->MsgEnable(SHORT1FROMMP(mp1));
1526 break;
1527
1528 case WM_SHOW:
1529 dprintf(("PMFRAME: WM_SHOW %x %d", hwnd, mp1));
1530 //show client window
1531 WinShowWindow(win32wnd->getOS2WindowHandle(), (BOOL)mp1);
1532 break;
1533
1534 case WM_QUERYTRACKINFO:
1535 {
1536 PTRACKINFO trackInfo = (PTRACKINFO)mp2;
1537
1538 dprintf(("PMFRAME:WM_QUERYTRACKINFO %x", win32wnd->getWindowHandle()));
1539 trackInfo->cxBorder = 4;
1540 trackInfo->cyBorder = 4;
1541 win32wnd->AdjustTrackInfo((PPOINT)&trackInfo->ptlMinTrackSize,(PPOINT)&trackInfo->ptlMaxTrackSize);
1542 rc = (MRESULT)TRUE;
1543 break;
1544 }
1545
1546 case WM_QUERYBORDERSIZE:
1547 {
1548 PWPOINT size = (PWPOINT)mp1;
1549
1550 dprintf(("PMFRAME:WM_QUERYBORDERSIZE %x", win32wnd->getWindowHandle()));
1551
1552 size->x = 0;
1553 size->y = 0;
1554 rc = (MRESULT)TRUE;
1555 break;
1556 }
1557
1558#ifdef DEBUG
1559 case WM_QUERYFRAMEINFO:
1560 dprintf(("PMFRAME:WM_QUERYFRAMEINFO %x", win32wnd->getWindowHandle()));
1561 goto RunDefFrameWndProc;
1562#endif
1563
1564 case WM_FORMATFRAME:
1565 dprintf(("PMFRAME:WM_FORMATFRAME %x", win32wnd->getWindowHandle()));
1566 break;
1567
1568#ifdef DEBUG
1569 case WM_ADJUSTFRAMEPOS:
1570 {
1571 PSWP pswp = (PSWP)mp1;
1572
1573 dprintf(("PMFRAME:WM_ADJUSTFRAMEPOS %x %x %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
1574 goto RunDefFrameWndProc;
1575 }
1576
1577 case WM_OWNERPOSCHANGE:
1578 {
1579 PSWP pswp = (PSWP)mp1;
1580
1581 dprintf(("PMFRAME:WM_OWNERPOSCHANGE %x %x %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->hwnd, pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
1582 goto RunDefFrameWndProc;
1583 }
1584#endif
1585
1586 case WM_MINMAXFRAME:
1587 {
1588 PSWP swp = (PSWP)mp1;
1589
1590 if (!win32wnd->IsWindowCreated()) goto RunDefWndProc;
1591
1592 dprintf(("PMFRAME:WM_MINMAXFRAME %x",hwnd));
1593 if ((swp->fl & SWP_MAXIMIZE) == SWP_MAXIMIZE)
1594 {
1595 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MINIMIZE_W) | WS_MAXIMIZE_W);
1596
1597 RECT rect;
1598
1599 rect.left = rect.top = rect.right = rect.bottom = 0;
1600 win32wnd->AdjustMaximizedRect(&rect);
1601 swp->x += rect.left;
1602 swp->cx += rect.right-rect.left;
1603 swp->y -= rect.bottom;
1604 swp->cy += rect.bottom-rect.top;
1605 }
1606 else
1607 if ((swp->fl & SWP_MINIMIZE) == SWP_MINIMIZE)
1608 {
1609 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MAXIMIZE_W) | WS_MINIMIZE_W);
1610 }
1611 else
1612 if ((swp->fl & SWP_RESTORE) == SWP_RESTORE)
1613 {
1614 win32wnd->setStyle(win32wnd->getStyle() & ~(WS_MINIMIZE_W | WS_MAXIMIZE_W));
1615 }
1616 goto RunDefWndProc;
1617 }
1618
1619#ifdef DEBUG
1620 case WM_UPDATEFRAME:
1621 dprintf(("PMFRAME:WM_UPDATEFRAME %x", win32wnd->getWindowHandle()));
1622 goto RunDefFrameWndProc;
1623#endif
1624
1625 case WM_TRACKFRAME:
1626 dprintf(("PMFRAME: WM_TRACKFRAME %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
1627 if(fOS2Look) {//sent by titlebar control
1628#ifdef CUSTOM_TRACKFRAME
1629 Frame_SysCommandSizeMove(win32wnd, SC_MOVE_W+HTCAPTION_W);
1630#else
1631 FrameTrackFrame(win32wnd, TF_MOVE);
1632#endif
1633 }
1634 rc = 0;
1635 break;
1636
1637 case WM_SYSCOMMAND:
1638 dprintf(("PMFRAME: WM_SYSCOMMAND %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
1639 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
1640 RELEASE_WNDOBJ(win32wnd);
1641 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
1642 }
1643 if(win32wnd)
1644 win32wnd->DispatchMsgA(pWinMsg);
1645 break;
1646
1647#ifdef DEBUG
1648 case WM_DDE_INITIATE:
1649 case WM_DDE_INITIATEACK:
1650 case WM_DDE_REQUEST:
1651 case WM_DDE_ACK:
1652 case WM_DDE_DATA:
1653 case WM_DDE_ADVISE:
1654 case WM_DDE_UNADVISE:
1655 case WM_DDE_POKE:
1656 case WM_DDE_EXECUTE:
1657 case WM_DDE_TERMINATE:
1658 dprintf(("PMFRAME: WM_DDE %x %x", msg, win32wnd->getWindowHandle()));
1659 break;
1660#endif
1661
1662 default:
1663 goto RunDefFrameWndProc;
1664 }
1665 RestoreOS2TIB();
1666 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1667 return (MRESULT)rc;
1668
1669RunDefFrameWndProc:
1670 dprintf2(("RunDefFrameWndProc"));
1671 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1672 RestoreOS2TIB();
1673 return pfnFrameWndProc(hwnd, msg, mp1, mp2);
1674
1675RunDefWndProc:
1676 dprintf2(("RunDefWndProc"));
1677 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1678 RestoreOS2TIB();
1679 //calling WinDefWindowProc here breaks Opera hotlist window (WM_ADJUSTWINDOWPOS)
1680// return pfnFrameWndProc(hwnd, msg, mp1, mp2);
1681 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
1682}
1683//******************************************************************************
1684//******************************************************************************
1685void FrameSetFocus(HWND hwnd)
1686{
1687 HWND hwndFocusSave = WinQueryWindowULong(hwnd, QWL_HWNDFOCUSSAVE);
1688 if(!WinIsWindow(hab, hwndFocusSave)) {
1689 hwndFocusSave = WinWindowFromID(hwnd, FID_CLIENT);
1690 WinSetWindowULong(hwnd, QWL_HWNDFOCUSSAVE, hwndFocusSave);
1691 }
1692 dprintf(("FrameSetFocus: hwndFocusSave %x %x", OS2ToWin32Handle(hwndFocusSave), hwndFocusSave));
1693 WinSetFocus(HWND_DESKTOP, hwndFocusSave);
1694
1695 ULONG ulFrameFlags = WinQueryWindowUShort(hwnd, QWS_FLAGS);
1696 ulFrameFlags &= ~FF_NOACTIVATESWP;
1697 WinSetWindowUShort(hwnd, QWS_FLAGS, ulFrameFlags);
1698}
1699#ifndef CUSTOM_TRACKFRAME
1700//******************************************************************************
1701//TODO: Quickly moving a window two times doesn't force a repaint (1st time)
1702//
1703//
1704BOOL (APIENTRY *WinTrackWindow)(HWND hwndTrack, PTRACKINFO pti) = NULL;
1705//
1706//******************************************************************************
1707VOID FrameTrackFrame(Win32BaseWindow *win32wnd,DWORD flags)
1708{
1709 TRACKINFO track;
1710 RECTL rcl;
1711 PRECT pWindowRect, pClientRect;
1712 HWND hwndTracking;
1713 LONG parentHeight, parentWidth;
1714 static BOOL fInit = FALSE;
1715 APIRET rc;
1716 BOOL ret;
1717 HWND hwnd = win32wnd->getWindowHandle();
1718
1719 if(!fInit) {
1720 HMODULE hModule;
1721 char buf[CCHMAXPATH];
1722 rc = DosLoadModule(buf, sizeof(buf), "PMMERGE", &hModule);
1723 rc = DosQueryProcAddr(hModule, 5466, NULL, (PFN *)&WinTrackWindow);
1724 if(rc) WinTrackWindow = NULL;
1725 fInit = TRUE;
1726 }
1727 dprintf(("FrameTrackFrame: %x %x", hwnd, flags));
1728 track.cxBorder = 4;
1729 track.cyBorder = 4; /* 4 pel wide lines used for rectangle */
1730 track.cxGrid = 1;
1731 track.cyGrid = 1; /* smooth tracking with mouse */
1732 track.cxKeyboard = 8;
1733 track.cyKeyboard = 8; /* faster tracking using cursor keys */
1734
1735 pWindowRect = win32wnd->getWindowRect();
1736 if(win32wnd->getParent()) {
1737 parentHeight = win32wnd->getParent()->getClientHeight();
1738 parentWidth = win32wnd->getParent()->getClientWidth();
1739 hwndTracking = win32wnd->getParent()->getOS2WindowHandle();
1740 }
1741 else {
1742 parentHeight = OSLibQueryScreenHeight();
1743 parentWidth = OSLibQueryScreenWidth();
1744 hwndTracking = HWND_DESKTOP;
1745 }
1746
1747 mapWin32ToOS2Rect(parentHeight, pWindowRect, (PRECTLOS2)&track.rclTrack);
1748 rcl = track.rclTrack;
1749 WinQueryWindowRect(hwndTracking, &track.rclBoundary);
1750
1751 track.ptlMinTrackSize.x = 10;
1752 track.ptlMinTrackSize.y = 10; /* set smallest allowed size of rectangle */
1753 track.ptlMaxTrackSize.x = parentWidth;
1754 track.ptlMaxTrackSize.y = parentHeight; /* set largest allowed size of rectangle */
1755
1756 win32wnd->AdjustTrackInfo((PPOINT)&track.ptlMinTrackSize, (PPOINT)&track.ptlMaxTrackSize);
1757
1758 track.fs = flags;
1759
1760 BOOL fDynamicDrag = WinQuerySysValue(HWND_DESKTOP, SVOS_DYNAMICDRAG);
1761
1762 //TODO: send WM_QUERYDRAGICON to fetch icon (not really necessary)
1763
1764 SendMessageA( hwnd, WM_ENTERSIZEMOVE_W, 0, 0);
1765
1766 SEL sel = RestoreOS2FS();
1767 if(fDynamicDrag && WinTrackWindow) {
1768 ret = WinTrackWindow(win32wnd->getOS2FrameWindowHandle(), &track);
1769 }
1770 else ret = WinTrackRect(hwndTracking, NULL, &track);
1771 SetFS(sel);
1772
1773//TODO:
1774// if (HOOK_CallHooksA( WH_CBT_W, HCBT_MOVESIZE_W, (WPARAM)hwnd, (LPARAM)&sizingRect )) moved = FALSE;
1775
1776 SendMessageA( hwnd, WM_EXITSIZEMOVE_W, 0, 0 );
1777 SendMessageA( hwnd, WM_SETVISIBLE_W, !IsIconic(hwnd), 0L);
1778
1779 if(ret) {
1780 /* if successful copy final position back */
1781 if(!WinEqualRect(0, &rcl, &track.rclTrack)) {
1782 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));
1783 if(flags == TF_MOVE) {
1784 WinSetWindowPos(win32wnd->getOS2FrameWindowHandle(),
1785 0, track.rclTrack.xLeft, track.rclTrack.yBottom,
1786 0, 0, SWP_MOVE);
1787 }
1788 else {
1789 WinSetWindowPos(win32wnd->getOS2FrameWindowHandle(),
1790 0, track.rclTrack.xLeft, track.rclTrack.yBottom,
1791 track.rclTrack.xRight - track.rclTrack.xLeft,
1792 track.rclTrack.yTop - track.rclTrack.yBottom,
1793 SWP_SIZE|SWP_MOVE);
1794 }
1795 }
1796 return;
1797 }
1798 return;
1799}
1800#endif
1801//******************************************************************************
1802//******************************************************************************
1803void FrameReplaceMenuItem(HWND hwndMenu, ULONG nIndex, ULONG idOld, ULONG idNew,
1804 HBITMAP hbmNew)
1805{
1806 MENUITEM mi;
1807
1808 if (!hwndMenu)
1809 return;
1810
1811 WinEnableWindowUpdate(hwndMenu, FALSE);
1812
1813 if (WinSendMsg(hwndMenu, MM_QUERYITEM, MPFROM2SHORT(idOld, TRUE), MPFROMP(&mi)))
1814 {
1815 WinSendMsg(hwndMenu, MM_REMOVEITEM, (MPARAM)idOld, 0);
1816 mi.afStyle = MIS_BITMAP | MIS_SYSCOMMAND;
1817 mi.afAttribute = 0;
1818 mi.hwndSubMenu = 0;
1819 mi.id = idNew;
1820 mi.hItem = (ULONG)hbmNew;
1821 WinSendMsg(hwndMenu, MM_INSERTITEM, (MPARAM)&mi, 0);
1822 }
1823 WinEnableWindowUpdate(hwndMenu, TRUE);
1824
1825 WinInvalidateRect(hwndMenu, NULL, TRUE);
1826}
1827//******************************************************************************
1828//******************************************************************************
Note: See TracBrowser for help on using the repository browser.