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

Last change on this file since 7264 was 7263, checked in by sandervl, 24 years ago

updates for sending WM_DEVICECHANGE on CD status change

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