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

Last change on this file since 9101 was 9101, checked in by sandervl, 23 years ago

Ugly hack added to work around crash in PM when child window calls DestroyWindow for parent or owner in WM_DESTROY handler (solution: postpone DestroyWindow for parent/owner)

File size: 73.6 KB
Line 
1/* $Id: pmwindow.cpp,v 1.188 2002-08-23 15:06:00 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#include "dragdrop.h"
54
55#define DBG_LOCALLOG DBG_pmwindow
56#include "dbglocal.h"
57
58//define this to use the new code for WM_CALCVALIDRECT handling
59//#define USE_CALCVALIDRECT
60
61HMQ hmq = 0; /* Message queue handle */
62HAB hab = 0;
63RECTL desktopRectl = {0};
64ULONG ScreenWidth = 0;
65ULONG ScreenHeight = 0;
66ULONG ScreenBitsPerPel = 0;
67BOOL fOS2Look = FALSE;
68BOOL fForceMonoCursor = FALSE;
69BOOL fDragDropActive = FALSE;
70BOOL fDragDropDisabled = FALSE;
71HBITMAP hbmFrameMenu[3] = {0};
72
73static PFNWP pfnFrameWndProc = NULL;
74static HWND hwndFocusChange = 0;
75 HWND hwndCD = 0;
76
77// this holds the font height that the display driver returns using DevQueryCaps
78// 13 would be small fonts, 16 medium fonts and 20 large fonts
79LONG CapsCharHeight = 0;
80
81// Note:
82// For a "lonekey"-press of AltGr, we only receive WM_KEYUP
83// messages. If the key is pressed longer and starts to repeat,
84// WM_KEYDOWN messages come in properly.
85static BOOL fKeyAltGrDown = FALSE;
86
87
88static char *PMDragExtractFiles(PDRAGINFO pDragInfo, ULONG *pcItems, ULONG *pulBytes);
89static BOOL PMDragValidate(PDRAGINFO pDragInfo);
90
91MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
92MRESULT EXPENTRY Win32CDWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
93MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
94void FrameReplaceMenuItem(HWND hwndMenu, ULONG nIndex, ULONG idOld, ULONG idNew,
95 HBITMAP hbmNew);
96void FrameSetFocus(HWND hwnd);
97
98VOID APIENTRY DspInitSystemDriverName(PSZ pszDriverName, ULONG lenDriverName);
99
100#ifdef DEBUG
101static char *DbgGetStringSWPFlags(ULONG flags);
102static char *DbgPrintQFCFlags(ULONG flags);
103#endif
104
105//******************************************************************************
106// Initialize PM; create hab, message queue and register special Win32 window classes
107//
108// This is called from the initterm, so we call it only once for each process.
109// We make sure PM is up and running for our purposes and init the existing
110// thread 0.
111//******************************************************************************
112BOOL InitPM()
113{
114 hab = WinInitialize(0);
115 dprintf(("Winitialize returned %x", hab));
116 hmq = WinCreateMsgQueue(hab, 0);
117
118 if(!hab || !hmq)
119 {
120 UINT error;
121 //CB: only fail on real error
122 error = WinGetLastError(hab) & 0xFFFF; //error code
123 if (!hab || (error != PMERR_MSG_QUEUE_ALREADY_EXISTS))
124 {
125 dprintf(("WinInitialize or WinCreateMsgQueue failed %x %x", hab, hmq));
126 dprintf((" Error = %x",error));
127 if(error == PMERR_NOT_IN_A_PM_SESSION) return TRUE;
128
129 return(FALSE);
130 }
131 else
132 {
133 if(!hab) {
134 hab = WinQueryAnchorBlock(HWND_DESKTOP);
135 dprintf(("WinQueryAnchorBlock returned %x", hab));
136 }
137 if(!hmq) {
138 PTIB ptib;
139 PPIB ppib;
140
141 DosGetInfoBlocks(&ptib, &ppib);
142
143 hmq = WinQueueFromID(hab, ppib->pib_ulpid, ptib->tib_ptib2->tib2_ultid);
144 }
145 }
146 }
147
148 // store our HAB and HMQ in the TEB - we need it quite often
149 // and they don't map 1:1 to Windows entities
150 SetThreadHAB(hab);
151 dprintf(("InitPM: hmq = %x", hmq));
152 SetThreadMessageQueue(hmq);
153
154 BOOL rc = WinSetCp(hmq, GetDisplayCodepage());
155 dprintf(("InitPM: WinSetCP was %sOK", rc ? "" : "not "));
156
157 //CD polling window class
158 if(!WinRegisterClass( /* Register window class */
159 hab, /* Anchor block handle */
160 (PSZ)WIN32_CDCLASS, /* Window class name */
161 (PFNWP)Win32CDWindowProc, /* Address of window procedure */
162 0,
163 0))
164 {
165 dprintf(("WinRegisterClass Win32BaseWindow failed"));
166 return(FALSE);
167 }
168
169 //Standard Odin window class
170 if(!WinRegisterClass( /* Register window class */
171 hab, /* Anchor block handle */
172 (PSZ)WIN32_STDCLASS, /* Window class name */
173 (PFNWP)Win32WindowProc, /* Address of window procedure */
174 0,
175 NROF_WIN32WNDBYTES))
176 {
177 dprintf(("WinRegisterClass Win32BaseWindow failed"));
178 return(FALSE);
179 }
180
181 CLASSINFO FrameClassInfo;
182 if(!WinQueryClassInfo (hab, WC_FRAME, &FrameClassInfo)) {
183 dprintf (("WinQueryClassInfo WC_FRAME failed"));
184 return (FALSE);
185 }
186 pfnFrameWndProc = FrameClassInfo.pfnWindowProc;
187
188 dprintf(("WC_FRAME style %x", FrameClassInfo.flClassStyle));
189
190 // this is our OS/2 window class for frame windows
191 if(!WinRegisterClass( /* Register window class */
192 hab, /* Anchor block handle */
193 (PSZ)WIN32_STDFRAMECLASS, /* Window class name */
194 (PFNWP)Win32FrameWindowProc, /* Address of window procedure */
195 CS_FRAME,
196 FrameClassInfo.cbWindowData))
197 {
198 dprintf(("WinRegisterClass Win32BaseWindow failed %x", WinGetLastError(hab)));
199 return(FALSE);
200 }
201
202 // get the screen dimensions and store them
203 WinQueryWindowRect(HWND_DESKTOP, &desktopRectl);
204 ScreenWidth = desktopRectl.xRight;
205 ScreenHeight = desktopRectl.yTop;
206
207 HDC hdc; /* Device-context handle */
208 /* context data structure */
209 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
210 NULL, NULL, NULL};
211
212 /* create memory device context - it's temporary to query some information */
213 hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
214
215 // check if we have the OS/2 Look and Feel enabled
216 fOS2Look = PROFILE_GetOdinIniBool(ODINSYSTEM_SECTION, "OS2Look", FALSE);
217 if(fOS2Look)
218 {
219 CHAR szDisplay[30];
220 HMODULE hModDisplay;
221
222 SYSCOLOR_Init(FALSE); //use OS/2 colors
223
224 // query the name of the display driver resource DLL to load
225 // some standard bitmaps from it
226 DspInitSystemDriverName(szDisplay, sizeof(szDisplay));
227 DosQueryModuleHandle(szDisplay, &hModDisplay);
228
229 hbmFrameMenu[0] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MINBUTTON, 0, 0);
230 hbmFrameMenu[1] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MAXBUTTON, 0, 0);
231 hbmFrameMenu[2] = GpiLoadBitmap(hdc, hModDisplay, SBMP_RESTOREBUTTON, 0, 0);
232 }
233
234 // find out which colordepth we're running
235 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, (PLONG)&ScreenBitsPerPel);
236
237 // query the font height to find out whether we have small or large fonts
238 DevQueryCaps(hdc, CAPS_GRAPHICS_CHAR_HEIGHT, 1, (PLONG)&CapsCharHeight);
239
240 DevCloseDC(hdc);
241
242 dprintf(("InitPM: Desktop (%d,%d) bpp %d", ScreenWidth, ScreenHeight, ScreenBitsPerPel));
243 return TRUE;
244} /* End of main */
245//******************************************************************************
246//menu.cpp
247BOOL MENU_Init();
248//******************************************************************************
249// AH TODO 2002-07-18
250// Note: this looks a lot like unnecessary code duplication. We should call this
251// function from InitPM...
252//******************************************************************************
253void WIN32API SetWindowAppearance(int fLooks)
254{
255 if(fLooks == OS2_APPEARANCE || fLooks == OS2_APPEARANCE_SYSMENU)
256 {
257 CHAR szDisplay[30];
258 HMODULE hModDisplay;
259
260 SYSCOLOR_Init(FALSE); //use OS/2 colors
261
262 if(hbmFrameMenu[0] == 0)
263 {
264 CHAR szDisplay[30];
265 HMODULE hModDisplay;
266 HDC hdc; /* Device-context handle */
267 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
268 NULL, NULL, NULL};
269
270 /* create memory device context */
271 hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
272
273 DspInitSystemDriverName(szDisplay, sizeof(szDisplay));
274 DosQueryModuleHandle(szDisplay, &hModDisplay);
275
276 hbmFrameMenu[0] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MINBUTTON, 0, 0);
277 hbmFrameMenu[1] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MAXBUTTON, 0, 0);
278 hbmFrameMenu[2] = GpiLoadBitmap(hdc, hModDisplay, SBMP_RESTOREBUTTON, 0, 0);
279 DevCloseDC(hdc);
280 }
281 }
282 fOS2Look = fLooks;
283 MENU_Init();
284}
285//******************************************************************************
286//******************************************************************************
287void WIN32API CustForceMonoCursor()
288{
289 fForceMonoCursor = TRUE;
290}
291//******************************************************************************
292//******************************************************************************
293void WIN32API DisableDragDrop(BOOL fDisabled)
294{
295 fDragDropDisabled = fDisabled;
296}
297//******************************************************************************
298//CD notification window class
299//******************************************************************************
300MRESULT EXPENTRY Win32CDWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
301{
302#pragma pack(1)
303 typedef struct
304 {
305 BYTE ucCommandInfo;
306 WORD usDriveUnit;
307 } ParameterBlock;
308#pragma pack()
309
310 MRESULT rc = 0;
311 static ULONG drives[26] = {0};
312 static int drivestatus[26] = {0};
313
314 switch( msg )
315 {
316 //OS/2 msgs
317 case WM_CREATE:
318 {
319 char drive[4];
320
321 //skip floppy drives
322 drive[0] = 'C';
323 drive[1] = ':';
324 drive[2] = '\0';
325
326 for(int i=2;i<26;i++) {
327 drives[i] = GetDriveTypeA(drive);
328 if(drives[i] == DRIVE_CDROM_W)
329 {
330 DWORD parsize = sizeof(ParameterBlock);
331 DWORD datasize = 2;
332 WORD status = 0;
333 DWORD rc;
334 ParameterBlock parm;
335
336 parm.ucCommandInfo = 0;
337 parm.usDriveUnit = i;
338 rc = DosDevIOCtl(-1, IOCTL_DISK, DSK_GETLOCKSTATUS, &parm, sizeof(parm), &parsize,
339 &status, sizeof(status), &datasize);
340 if(rc != NO_ERROR) {
341 dprintf(("DosDevIOCtl failed with rc %d", rc));
342 drives[i] = 0;
343 continue;
344 }
345 //if no disk present, return FALSE
346 if(status & 4) {
347 drivestatus[i] = status & 4;
348 }
349 }
350 drive[0]++;
351 }
352 WinStartTimer(hab, hwnd, TIMERID_DRIVEPOLL, 32*60);
353//// WinStartTimer(hab, hwnd, TIMERID_DRIVEPOLL, 32*3);
354//// WinStartTimer(hab, hwnd, TIMERID_DRIVEPOLL, 5000);
355 rc = (MRESULT)FALSE;
356 break;
357 }
358 case WM_TIMER:
359 {
360 for(int i=0;i<26;i++)
361 {
362 //for now only cdrom/dvd drives
363 if(drives[i] == DRIVE_CDROM_W)
364 {
365 DWORD parsize = sizeof(ParameterBlock);
366 DWORD datasize = 2;
367 WORD status = 0;
368 DWORD rc;
369 ParameterBlock parm;
370
371 parm.ucCommandInfo = 0;
372 parm.usDriveUnit = i;
373 rc = DosDevIOCtl(-1, IOCTL_DISK, DSK_GETLOCKSTATUS, &parm, sizeof(parm), &parsize,
374 &status, sizeof(status), &datasize);
375 if(rc != NO_ERROR) {
376 dprintf(("DosDevIOCtl failed with rc %d", rc));
377 return FALSE;
378 }
379 //Send WM_DEVICECHANGE message when CD status changes
380 if((status & 4) != drivestatus[i])
381 {
382 PID pidThis, pidTemp;
383 HENUM henum;
384 HWND hwndEnum;
385 DEV_BROADCAST_VOLUME volchange;
386
387 dprintf(("Disk status 0x%x", status));
388
389 volchange.dbcv_size = sizeof(volchange);
390 volchange.dbcv_devicetype = DBT_DEVTYP_VOLUME;
391 volchange.dbcv_reserved = 0;
392 volchange.dbcv_unitmask = (1 << i);
393 volchange.dbcv_flags = DBTF_MEDIA;
394
395 WinQueryWindowProcess(hwnd, &pidThis, NULL);
396
397 //Iterate over all child windows of the desktop
398 henum = WinBeginEnumWindows(HWND_DESKTOP);
399
400 SetWin32TIB();
401 while(hwndEnum = WinGetNextWindow(henum))
402 {
403 WinQueryWindowProcess(hwndEnum, &pidTemp, NULL);
404 if(pidTemp == pidThis)
405 {
406 HWND hwndWin32 = OS2ToWin32Handle(hwndEnum);
407 if(hwndWin32) {
408 SendMessageA(hwndWin32,
409 WM_DEVICECHANGE_W,
410 (status & 4) ? DBT_DEVICEARRIVAL : DBT_DEVICEREMOVECOMPLETE,
411 (LPARAM)&volchange);
412 }
413 }
414 }
415 RestoreOS2TIB();
416 WinEndEnumWindows(henum);
417
418 drivestatus[i] = (status & 4);
419 }
420 }
421 }
422 break;
423 }
424
425 case WM_DESTROY:
426 dprintf(("WM_DESTROY for CD notification window"));
427 WinStopTimer(hab, hwnd, TIMERID_DRIVEPOLL);
428 break;
429
430 default:
431 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
432 }
433 return (MRESULT)rc;
434}
435//******************************************************************************
436// Win32 window message handler
437// The PM window procedure for our client window class (non frame)
438//******************************************************************************
439MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
440{
441 Win32BaseWindow *win32wnd;
442 TEB *teb;
443 MSG winMsg, *pWinMsg;
444 MRESULT rc = 0;
445 POSTMSG_PACKET *postmsg;
446 OSLIBPOINT point, ClientPoint;
447
448 // restore our FS selector
449 SetWin32TIB();
450
451 // BEGIN NOTE-------------->>>>>> If this is changed, also change Win32FrameWindowProc!! <<<<<<<<<<<-------------------- BEGIN
452 teb = GetThreadTEB();
453 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
454
455//// dprintf(("window %x msg %x", (win32wnd) ? win32wnd->getWindowHandle() : 0, msg));
456
457 // do some sanity checking here:
458 // - we need to have a TEB handle
459 // - unless this is WM_CREATE (the very first message), there has to be
460 // a USER32 window object for this window handle
461 if(!teb || (msg != WM_CREATE && win32wnd == NULL)) {
462 dprintf(("OS2: Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
463 goto RunDefWndProc;
464 }
465//// if(teb->o.odin.fIgnoreMsgs) {
466//// goto RunDefWndProc;
467//// }
468
469 // check if the message state counter in the TEB is odd
470 // This means the message has been sent directly from PM to our message
471 // handler (so it is the first time we know about this PM message).
472 // If this is the case, we have to translate it here to a Win32
473 // message first. The other case is that the message is the result of a
474 // WinDispatchMsg call and therefore has already been translated.
475 if((teb->o.odin.msgstate & 1) == 0)
476 {
477 // message that was sent directly to our window proc handler; translate it here
478 QMSG qmsg;
479
480 qmsg.msg = msg;
481 qmsg.hwnd = hwnd;
482 qmsg.mp1 = mp1;
483 qmsg.mp2 = mp2;
484 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
485 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
486 qmsg.reserved = 0;
487
488 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
489 {//message was not translated
490 memset(&winMsg, 0, sizeof(MSG));
491 }
492 pWinMsg = &winMsg;
493 }
494 else {
495 // message has already been translated before (GetMessage/PeekMessage).
496 // Use the translated information. Flip the translation flag.
497 pWinMsg = &teb->o.odin.msg;
498 teb->o.odin.msgstate++;
499 }
500 // END NOTE-------------->>>>>> If this is changed, also change Win32FrameWindowProc!! <<<<<<<<<<<-------------------- END
501
502 if(msg >= WIN32APP_POSTMSG) {
503 //probably win32 app user message
504 dprintf2(("Posted message %x->%x", msg, msg-WIN32APP_POSTMSG));
505 if((ULONG)mp1 == WIN32MSG_MAGICA) {
506 rc = (MRESULT)win32wnd->DispatchMsgA(pWinMsg);
507 }
508 else
509 if((ULONG)mp1 == WIN32MSG_MAGICW) {
510 rc = (MRESULT)win32wnd->DispatchMsgW(pWinMsg);
511 }
512 else {//broadcasted message
513 rc = (MRESULT)win32wnd->DispatchMsgA(pWinMsg);
514 }
515 RELEASE_WNDOBJ(win32wnd);
516 RestoreOS2TIB();
517 return rc;
518 }
519
520 switch( msg )
521 {
522 //OS/2 msgs
523 case WM_CREATE:
524 {
525 if(teb->o.odin.newWindow == 0)
526 goto createfail;
527
528 //Processing is done in after WinCreateWindow returns
529 dprintf(("OS2: WM_CREATE %x", hwnd));
530 win32wnd = (Win32BaseWindow *)teb->o.odin.newWindow;
531 win32wnd->addRef();
532 teb->o.odin.newWindow = 0;
533 if(win32wnd->MsgCreate(hwnd) == FALSE)
534 {
535 rc = (MRESULT)TRUE; //discontinue window creation
536 break;
537 }
538
539 //Create CD notification window
540 if(hwndCD == 0) {
541 hwndCD = WinCreateWindow(HWND_DESKTOP, WIN32_CDCLASS,
542 NULL, 0, 0, 0, 0, 0,
543 HWND_DESKTOP, HWND_TOP, 0, NULL, NULL);
544 }
545
546 createfail:
547 rc = (MRESULT)FALSE;
548 break;
549 }
550
551 case WM_QUIT:
552 dprintf(("OS2: WM_QUIT %x", hwnd));
553 win32wnd->MsgQuit();
554 break;
555
556 case WM_CLOSE:
557 dprintf(("OS2: WM_CLOSE %x", hwnd));
558 win32wnd->MsgClose();
559 break;
560
561 case WM_DESTROY:
562 dprintf(("OS2: WM_DESTROY %x", hwnd));
563 win32wnd->MsgDestroy();
564 WinSetVisibleRegionNotify(hwnd, FALSE);
565 goto RunDefWndProc;
566
567 case WM_ENABLE:
568 dprintf(("OS2: WM_ENABLE %x", hwnd));
569 break;
570
571 case WM_SHOW:
572 dprintf(("OS2: WM_SHOW %x %d", hwnd, mp1));
573 win32wnd->MsgShow((ULONG)mp1);
574 break;
575
576 case WM_ACTIVATE:
577 {
578 ULONG flags = WinQueryWindowULong(hwnd, OFFSET_WIN32FLAGS);
579
580 dprintf(("OS2: WM_ACTIVATE %x %x %x", hwnd, mp1, mp2));
581 WinSetWindowULong(hwnd, OFFSET_WIN32FLAGS, SHORT1FROMMP(mp1) ? (flags | WINDOWFLAG_ACTIVE):(flags & ~WINDOWFLAG_ACTIVE));
582 if(win32wnd->IsWindowCreated())
583 {
584 win32wnd->MsgActivate((LOWORD(pWinMsg->wParam) == WA_ACTIVE_W) ? 1 : 0, HIWORD(pWinMsg->wParam), pWinMsg->lParam, (HWND)mp2);
585 }
586 break;
587 }
588
589 case WM_SIZE:
590 {
591 dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp1)));
592 win32wnd->SetVisibleRegionChanged(TRUE);
593 goto RunDefWndProc;
594 }
595
596
597 case WM_VRNENABLED:
598 dprintf(("OS2: WM_VRNENABLED %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
599 //Always call handler; even if mp1 is 0. If we don't do this, the
600 //DivX 4 player will never be allowed to draw after putting another window
601 //on top of it.
602 win32wnd->callVisibleRgnNotifyProc(TRUE);
603 if(!win32wnd->isComingToTop() && ((win32wnd->getExStyle() & WS_EX_TOPMOST_W) == WS_EX_TOPMOST_W))
604 {
605 HWND hwndrelated;
606 Win32BaseWindow *topwindow;
607
608 win32wnd->setComingToTop(TRUE);
609
610 hwndrelated = WinQueryWindow(hwnd, QW_PREV);
611 dprintf(("WM_VRNENABLED hwndrelated = %x (hwnd=%x)", hwndrelated, hwnd));
612 topwindow = Win32BaseWindow::GetWindowFromOS2Handle(hwndrelated);
613 if(topwindow == NULL || ((win32wnd->getExStyle() & WS_EX_TOPMOST_W) == 0)) {
614 //put window at the top of z order
615 WinSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER );
616 }
617 if(topwindow) RELEASE_WNDOBJ(topwindow);
618
619 win32wnd->setComingToTop(FALSE);
620 break;
621 }
622 goto RunDefWndProc;
623
624 case WM_VRNDISABLED:
625 dprintf(("OS2: WM_VRNDISABLED %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
626 //visible region is about to change or WinLockWindowUpdate called
627 //suspend window drawing
628 win32wnd->callVisibleRgnNotifyProc(FALSE);
629 goto RunDefWndProc;
630
631 case WIN32APP_SETFOCUSMSG:
632 //PM doesn't allow SetFocus calls during WM_SETFOCUS message processing;
633 //must delay this function call
634 //mp1 = win32 window handle
635 //mp2 = top parent if activation required
636 dprintf(("USER32: Delayed SetFocus %x %x %x call!", teb->o.odin.hwndFocus, mp1, mp2));
637 if(teb->o.odin.hwndFocus) {
638 RELEASE_WNDOBJ(win32wnd);
639 win32wnd = Win32BaseWindow::GetWindowFromHandle(teb->o.odin.hwndFocus);
640 if(win32wnd) {
641 if(mp2) {
642 SetActiveWindow((HWND)mp2);
643 }
644 if(!IsWindow(win32wnd->getWindowHandle())) break; //abort if window destroyed
645 WinFocusChange(HWND_DESKTOP, win32wnd->getOS2WindowHandle(), FC_NOSETACTIVE);
646 }
647 else DebugInt3();
648 }
649 break;
650
651 case WM_SETFOCUS:
652 {
653 HWND hwndFocus = (HWND)mp1;
654
655 dprintf(("OS2: WM_SETFOCUS %x %x (%x) %d", win32wnd->getWindowHandle(), mp1, OS2ToWin32Handle(hwndFocus), mp2));
656
657 //PM doesn't allow SetFocus calls during WM_SETFOCUS message processing;
658 //must delay this function call
659
660 teb->o.odin.fWM_SETFOCUS = TRUE;
661 teb->o.odin.hwndFocus = 0;
662 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC)
663 {
664 //another (non-win32) application's window
665 //set to NULL (allowed according to win32 SDK) to avoid problems
666 hwndFocus = NULL;
667 }
668 if((ULONG)mp2 == TRUE) {
669 HWND hwndFocusWin32 = OS2ToWin32Handle(hwndFocus);
670 recreateCaret (hwndFocusWin32);
671 win32wnd->MsgSetFocus(hwndFocusWin32);
672 }
673 else win32wnd->MsgKillFocus(OS2ToWin32Handle(hwndFocus));
674 teb->o.odin.fWM_SETFOCUS = FALSE;
675
676 break;
677 }
678
679 //**************************************************************************
680 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
681 //**************************************************************************
682
683 case WM_BUTTON1DOWN:
684 case WM_BUTTON1UP:
685 case WM_BUTTON1DBLCLK:
686 case WM_BUTTON2DOWN:
687 case WM_BUTTON2UP:
688 case WM_BUTTON2DBLCLK:
689 case WM_BUTTON3DOWN:
690 case WM_BUTTON3UP:
691 case WM_BUTTON3DBLCLK:
692 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
693 RELEASE_WNDOBJ(win32wnd);
694 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
695 }
696 if(win32wnd)
697 win32wnd->MsgButton(pWinMsg);
698
699 rc = (MRESULT)TRUE;
700 break;
701
702 case WM_BUTTON2MOTIONSTART:
703 case WM_BUTTON2MOTIONEND:
704 case WM_BUTTON2CLICK:
705 case WM_BUTTON1MOTIONSTART:
706 case WM_BUTTON1MOTIONEND:
707 case WM_BUTTON1CLICK:
708 case WM_BUTTON3MOTIONSTART:
709 case WM_BUTTON3MOTIONEND:
710 case WM_BUTTON3CLICK:
711 rc = (MRESULT)TRUE;
712 break;
713
714 case WM_MOUSEMOVE:
715 {
716 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
717 RELEASE_WNDOBJ(win32wnd);
718 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
719 }
720 if(win32wnd)
721 win32wnd->MsgMouseMove(pWinMsg);
722 break;
723 }
724
725 case WM_CONTROL:
726 goto RunDefWndProc;
727
728 case WM_COMMAND:
729 dprintf(("OS2: WM_COMMAND %x %x %x", hwnd, mp1, mp2));
730 win32wnd->DispatchMsgA(pWinMsg);
731 break;
732
733 case WM_SYSCOMMAND:
734 dprintf(("OS2: WM_SYSCOMMAND %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
735 win32wnd->DispatchMsgA(pWinMsg);
736 break;
737
738 case WM_RENDERFMT:
739 case WM_RENDERALLFMTS:
740 case WM_DESTROYCLIPBOARD:
741 case WM_DRAWCLIPBOARD:
742 win32wnd->DispatchMsgA(pWinMsg);
743 break;
744
745 case WM_CHAR_SPECIAL:
746 /* NO BREAK! FALLTHRU CASE! */
747
748 case WM_CHAR:
749 dprintf(("OS2: WM_CHAR %x %x %x, %x %x", win32wnd->getWindowHandle(), mp1, mp2, pWinMsg->wParam, pWinMsg->lParam));
750 win32wnd->MsgChar(pWinMsg);
751 break;
752
753 case WM_TIMER:
754 dprintf(("OS2: WM_TIMER %x %x time %x", win32wnd->getWindowHandle(), pWinMsg->wParam, GetTickCount()));
755 win32wnd->DispatchMsgA(pWinMsg);
756 goto RunDefWndProc;
757
758 case WM_SETWINDOWPARAMS:
759 {
760 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
761
762 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
763 if(wndParams->fsStatus & WPM_TEXT) {
764 win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText);
765 }
766 goto RunDefWndProc;
767 }
768
769 case WM_QUERYWINDOWPARAMS:
770 {
771 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
772 ULONG textlen;
773 PSZ wintext;
774
775 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
776 {
777 if(wndpars->fsStatus & WPM_TEXT)
778 win32wnd->MsgGetText(wndpars->pszText, wndpars->cchText);
779 if(wndpars->fsStatus & WPM_CCHTEXT)
780 wndpars->cchText = win32wnd->MsgGetTextLength();
781
782 wndpars->fsStatus = 0;
783 wndpars->cbCtlData = 0;
784 wndpars->cbPresParams = 0;
785 rc = (MRESULT)TRUE;
786 break;
787 }
788 goto RunDefWndProc;
789 }
790
791 case WM_PAINT:
792 {
793 RECTL rectl;
794 BOOL rc;
795
796 rc = WinQueryUpdateRect(hwnd, &rectl);
797 dprintf(("OS2: WM_PAINT %x (%d,%d) (%d,%d) rc=%d", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop, rc));
798
799 if(rc && win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
800 rectl.yBottom != rectl.yTop) && !IsIconic(win32wnd->GetTopParent()))
801 {
802 win32wnd->DispatchMsgA(pWinMsg);
803 }
804 else goto RunDefWndProc;
805 break;
806 }
807
808 case WM_ERASEBACKGROUND:
809 {
810 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
811 rc = (MRESULT)FALSE;
812 break;
813 }
814
815 case WM_CALCVALIDRECTS:
816 dprintf(("OS2: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
817 rc = (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
818 break;
819
820 case WM_REALIZEPALETTE:
821 {
822 dprintf(("OS2: WM_REALIZEPALETTE"));
823 goto RunDefWndProc;
824 }
825
826 case WM_HSCROLL:
827 case WM_VSCROLL:
828 dprintf(("OS2: %s %x %x %x", (msg == WM_HSCROLL) ? "WM_HSCROLL" : "WM_VSCROLL", win32wnd->getWindowHandle(), mp1, mp2));
829 win32wnd->DispatchMsgA(pWinMsg);
830 break;
831
832 case DM_DRAGOVER:
833 {
834 PDRAGINFO pDragInfo = (PDRAGINFO)mp1;
835 PDRAGITEM pDragItem;
836 USHORT sxDrop = SHORT1FROMMP(mp2);
837 USHORT syDrop = SHORT2FROMMP(mp2);
838
839 dprintf(("OS2: DM_DRAGOVER %x (%d,%d)", win32wnd->getWindowHandle(), sxDrop, syDrop));
840
841 if(fDragDropDisabled) {
842 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
843 break;
844 }
845
846 //does this window accept dropped files?
847 if(!DragDropAccept(win32wnd->getWindowHandle())) {
848 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
849 break;
850 }
851
852 if(PMDragValidate(pDragInfo) == FALSE) {
853 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
854 break;
855 }
856 if(win32wnd->isDragDropActive() == FALSE) {
857 ULONG ulBytes, cItems;
858 char *pszFiles;
859
860 pszFiles = PMDragExtractFiles(pDragInfo, &cItems, &ulBytes);
861 if(pszFiles) {
862 POINT point = {sxDrop, syDrop};
863 if(DragDropDragEnter(win32wnd->getWindowHandle(), point, cItems, pszFiles, ulBytes, DROPEFFECT_COPY_W) == FALSE) {
864 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
865 }
866 else {
867 fDragDropActive = TRUE;
868 rc = (MRFROM2SHORT(DOR_DROP, DO_MOVE));
869 win32wnd->setDragDropActive(TRUE);
870 }
871 free(pszFiles);
872 }
873 else {
874 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
875 }
876 }
877 else {
878 if(DragDropDragOver(win32wnd->getWindowHandle(), DROPEFFECT_COPY_W) == FALSE) {
879 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
880 }
881 else rc = (MRFROM2SHORT(DOR_DROP, DO_MOVE));
882 }
883 break;
884 }
885
886 case DM_DRAGLEAVE:
887 {
888 dprintf(("OS2: DM_DRAGLEAVE %x", win32wnd->getWindowHandle()));
889
890 if(fDragDropDisabled) {
891 break;
892 }
893
894 fDragDropActive = FALSE;
895
896 //does this window accept dropped files?
897 if(!DragDropAccept(win32wnd->getWindowHandle())) {
898 break;
899 }
900
901 DragDropDragLeave(win32wnd->getWindowHandle());
902 win32wnd->setDragDropActive(FALSE);
903 break;
904 }
905
906 case DM_DROP:
907 {
908 PDRAGINFO pDragInfo = (PDRAGINFO)mp1;
909 PDRAGITEM pDragItem;
910 USHORT sxDrop = SHORT1FROMMP(mp2);
911 USHORT syDrop = SHORT2FROMMP(mp2);
912 USHORT usIndicator, usOp;
913
914 dprintf(("OS2: DM_DROP %x (%d,%d)", win32wnd->getWindowHandle(), sxDrop, syDrop));
915
916 fDragDropActive = FALSE;
917 rc = (MRFROM2SHORT (DOR_NODROP, 0));
918
919 if(fDragDropDisabled) {
920 rc = (MRFROM2SHORT (DOR_NODROP, 0));
921 break;
922 }
923
924 //does this window accept dropped files?
925 if(!DragDropAccept(win32wnd->getWindowHandle())) {
926 break;
927 }
928
929 ULONG ulBytes, cItems;
930 char *pszFiles;
931
932 pszFiles = PMDragExtractFiles(pDragInfo, &cItems, &ulBytes);
933 if(pszFiles) {
934 POINT point = {sxDrop, syDrop};
935 if(DragDropFiles(win32wnd->getWindowHandle(), point, cItems, pszFiles, ulBytes) == FALSE) {
936 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
937 }
938 else {
939 rc = (MRFROM2SHORT(DOR_DROP, DO_MOVE));
940 win32wnd->setDragDropActive(FALSE);
941 }
942 free(pszFiles);
943 }
944 else {
945 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
946 }
947 break;
948 }
949
950 case WM_DDE_INITIATE:
951 case WM_DDE_INITIATEACK:
952 case WM_DDE_REQUEST:
953 case WM_DDE_ACK:
954 case WM_DDE_DATA:
955 case WM_DDE_ADVISE:
956 case WM_DDE_UNADVISE:
957 case WM_DDE_POKE:
958 case WM_DDE_EXECUTE:
959 case WM_DDE_TERMINATE:
960 dprintf(("OS2: WM_DDE %x %x", msg, win32wnd->getWindowHandle()));
961 goto RunDefWndProc;
962
963 case WM_INITMENU:
964 case WM_MENUSELECT:
965 case WM_MENUEND:
966 case WM_NEXTMENU:
967 case WM_SYSCOLORCHANGE:
968 case WM_SYSVALUECHANGED:
969 case WM_SETSELECTION:
970 case WM_PPAINT:
971 case WM_PSETFOCUS:
972 case WM_PSYSCOLORCHANGE:
973 case WM_PSIZE:
974 case WM_PACTIVATE:
975 case WM_PCONTROL:
976 case WM_HELP:
977 case WM_APPTERMINATENOTIFY:
978 case WM_PRESPARAMCHANGED:
979 case WM_DRAWITEM:
980 case WM_MEASUREITEM:
981 case WM_CONTROLPOINTER:
982 case WM_QUERYDLGCODE:
983 case WM_SUBSTITUTESTRING:
984 case WM_MATCHMNEMONIC:
985 case WM_SAVEAPPLICATION:
986 case WM_SEMANTICEVENT:
987 default:
988 dprintf2(("OS2: RunDefWndProc hwnd %x msg %x mp1 %x mp2 %x", hwnd, msg, mp1, mp2));
989 goto RunDefWndProc;
990 }
991 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
992 RestoreOS2TIB();
993 return (MRESULT)rc;
994
995RunDefWndProc:
996// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
997 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
998 RestoreOS2TIB();
999 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
1000} /* End of Win32WindowProc */
1001//******************************************************************************
1002//******************************************************************************
1003MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1004{
1005 POSTMSG_PACKET *postmsg;
1006 OSLIBPOINT point, ClientPoint;
1007 Win32BaseWindow *win32wnd;
1008 TEB *teb;
1009 MRESULT rc = 0;
1010 MSG winMsg, *pWinMsg;
1011
1012 //Restore our FS selector
1013 SetWin32TIB();
1014
1015 // BEGIN NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- BEGIN
1016 teb = GetThreadTEB();
1017 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwnd);
1018
1019 // do some sanity checking here:
1020 // - we need to have a TEB handle
1021 // - unless this is WM_CREATE (the very first message), there has to be
1022 // a USER32 window object for this window handle
1023 if(!teb || (msg != WM_CREATE && win32wnd == NULL)) {
1024 dprintf(("PMFRAME: Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
1025 goto RunDefFrameWndProc;
1026 }
1027//// if(teb->o.odin.fIgnoreMsgs) {
1028//// goto RunDefWndProc;
1029//// }
1030
1031 // check if the message state counter in the TEB is odd
1032 // This means the message has been sent directly from PM to our message
1033 // handler (so it is the first time we know about this PM message).
1034 // If this is the case, we have to translate it here to a Win32
1035 // message first. The other case is that the message is the result of a
1036 // WinDispatchMsg call and therefore has already been translated.
1037 if((teb->o.odin.msgstate & 1) == 0)
1038 {//message that was sent directly to our window proc handler; translate it here
1039 QMSG qmsg;
1040
1041 qmsg.msg = msg;
1042 qmsg.hwnd = hwnd;
1043 qmsg.mp1 = mp1;
1044 qmsg.mp2 = mp2;
1045 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
1046 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
1047 qmsg.reserved = 0;
1048
1049 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
1050 {//message was not translated
1051 memset(&winMsg, 0, sizeof(MSG));
1052 }
1053 pWinMsg = &winMsg;
1054 }
1055 else {
1056 // message has already been translated before (GetMessage/PeekMessage).
1057 // Use the translated information. Flip the translation flag.
1058 pWinMsg = &teb->o.odin.msg;
1059 teb->o.odin.msgstate++;
1060 }
1061 // END NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- END
1062
1063 switch( msg )
1064 {
1065 case WM_CREATE:
1066 {
1067 //WM_CREATE handled during client window creation
1068 dprintf(("PMFRAME: WM_CREATE %x", hwnd));
1069 goto RunDefFrameWndProc;
1070 }
1071
1072//hack alert; PM crashes if child calls DestroyWindow for parent/owner in WM_DESTROY
1073// handler; must postpone it, so do it here
1074 case WIN32APP_POSTPONEDESTROY:
1075 OSLibWinDestroyWindow(hwnd);
1076 break;
1077//hack end
1078
1079#ifdef DEBUG
1080 case WM_CLOSE:
1081 {
1082 dprintf(("PMFRAME: WM_CLOSE %x", hwnd));
1083 goto RunDefFrameWndProc;
1084 }
1085#endif
1086
1087 case WM_PAINT:
1088 {
1089 RECTL rectl;
1090
1091 HPS hps = WinBeginPaint(hwnd, NULL, &rectl);
1092 dprintf(("PMFRAME: WM_PAINT %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop));
1093
1094 if(win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
1095 rectl.yBottom != rectl.yTop))
1096 {
1097 PRECT pClient = win32wnd->getClientRectPtr();
1098 PRECT pWindow = win32wnd->getWindowRect();
1099
1100 if(!(pClient->left == 0 && pClient->top == 0 &&
1101 win32wnd->getClientHeight() == win32wnd->getWindowHeight() &&
1102 win32wnd->getClientWidth() == win32wnd->getWindowWidth()))
1103 {
1104 RECT rectUpdate;
1105
1106 mapOS2ToWin32Rect(win32wnd->getWindowHeight(), (PRECTLOS2)&rectl, &rectUpdate);
1107 win32wnd->MsgNCPaint(&rectUpdate);
1108 }
1109 }
1110 WinEndPaint(hps);
1111 break;
1112 }
1113
1114 case WM_ERASEBACKGROUND:
1115 {
1116 dprintf(("PMFRAME:WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
1117 rc = (MRESULT)FALSE;
1118 break;
1119 }
1120
1121 //**************************************************************************
1122 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
1123 //**************************************************************************
1124
1125 case WM_BUTTON1DOWN:
1126 case WM_BUTTON1UP:
1127 case WM_BUTTON1DBLCLK:
1128 case WM_BUTTON2DOWN:
1129 case WM_BUTTON2UP:
1130 case WM_BUTTON2DBLCLK:
1131 case WM_BUTTON3DOWN:
1132 case WM_BUTTON3UP:
1133 case WM_BUTTON3DBLCLK:
1134 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
1135 RELEASE_WNDOBJ(win32wnd);
1136 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
1137 }
1138 if(win32wnd)
1139 win32wnd->MsgButton(pWinMsg);
1140
1141 rc = (MRESULT)TRUE;
1142 break;
1143
1144 case WM_BUTTON2MOTIONSTART:
1145 case WM_BUTTON2MOTIONEND:
1146 case WM_BUTTON2CLICK:
1147 case WM_BUTTON1MOTIONSTART:
1148 case WM_BUTTON1MOTIONEND:
1149 case WM_BUTTON1CLICK:
1150 case WM_BUTTON3MOTIONSTART:
1151 case WM_BUTTON3MOTIONEND:
1152 case WM_BUTTON3CLICK:
1153 rc = (MRESULT)TRUE;
1154 break;
1155
1156 case WM_MOUSEMOVE:
1157 {
1158 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
1159 RELEASE_WNDOBJ(win32wnd);
1160 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
1161 }
1162 if(win32wnd)
1163 win32wnd->MsgMouseMove(pWinMsg);
1164 break;
1165 }
1166
1167 case WM_ADJUSTWINDOWPOS:
1168 {
1169 PSWP pswp = (PSWP)mp1;
1170 SWP swpOld;
1171 WINDOWPOS wp,wpOld;
1172 ULONG ulFlags;
1173 ULONG ret = 0;
1174 HWND hParent = NULLHANDLE, hwndAfter;
1175
1176 dprintf(("PMFRAME:WM_ADJUSTWINDOWPOS %x %x %x (%s) (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->hwnd, pswp->fl, DbgGetStringSWPFlags(pswp->fl), pswp->x, pswp->y, pswp->cx, pswp->cy));
1177
1178 ulFlags = pswp->fl;
1179
1180 if(win32wnd->IsParentChanging()) {
1181 rc = 0;
1182 break;
1183 }
1184
1185 //@@PF all commands from minimized window viewer or from Ctrl-Esc
1186 //are 'pure' and should be handled only by DeFrameProc - this is weird
1187 //but without them we will not have results. Pure = plain flag of restore/minimize/maximize
1188 if((pswp->fl == SWP_MINIMIZE) || (pswp->fl & SWP_RESTORE)) {
1189 // note the purity of SWP no other SWP_FLAGS allowed
1190 goto RunDefFrameWndProc;
1191 }
1192
1193 if(pswp->fl & SWP_NOADJUST) {
1194 //ignore weird messages (TODO: why are they sent?)
1195 dprintf(("WARNING: WM_ADJUSTWINDOWPOS with SWP_NOADJUST flag!!"));
1196 break;
1197 }
1198 if ((pswp->fl == SWP_FOCUSACTIVATE) || (pswp->fl == SWP_FOCUSDEACTIVATE))
1199 {
1200 dprintf(("Pure focus flags are not sent to win32 windows"));
1201 goto RunDefFrameWndProc;
1202 }
1203
1204 //CB: show dialog in front of owner
1205 if (win32wnd->IsModalDialogOwner())
1206 {
1207 dprintf(("win32wnd->IsModalDialogOwner %x", win32wnd->getWindowHandle()));
1208 pswp->fl |= SWP_ZORDER;
1209 pswp->hwndInsertBehind = win32wnd->getOS2HwndModalDialog();
1210 if (pswp->fl & SWP_ACTIVATE)
1211 {
1212 pswp->fl &= ~SWP_ACTIVATE;
1213 WinSetWindowPos(win32wnd->getOS2HwndModalDialog(),0,0,0,0,0,SWP_ACTIVATE);
1214 }
1215 }
1216
1217 if(!win32wnd->CanReceiveSizeMsgs())
1218 break;
1219
1220 WinQueryWindowPos(hwnd, &swpOld);
1221 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
1222 if (win32wnd->isChild()) {
1223 if(win32wnd->getParent()) {
1224 hParent = win32wnd->getParent()->getOS2WindowHandle();
1225 }
1226 else goto RunDefFrameWndProc;
1227 }
1228 }
1229 hwndAfter = pswp->hwndInsertBehind;
1230 if(win32wnd->getParent()) {
1231 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(), hwnd);
1232 }
1233 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1234
1235 wp.hwnd = win32wnd->getWindowHandle();
1236 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1237 {
1238 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1239 dprintf2(("SWP_ZORDER: %x %x", pswp->hwndInsertBehind, (wndAfter) ? wndAfter->getWindowHandle() : 0));
1240 if(wndAfter) {
1241 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1242 RELEASE_WNDOBJ(wndAfter);
1243 }
1244 else wp.hwndInsertAfter = HWND_TOP_W;
1245 }
1246
1247 wpOld = wp;
1248 win32wnd->MsgPosChanging((LPARAM)&wp);
1249
1250 if(win32wnd->getOldStyle() != win32wnd->getStyle())
1251 {
1252 OSLibSetWindowStyle(win32wnd->getOS2FrameWindowHandle(), win32wnd->getOS2WindowHandle(), win32wnd->getStyle(), win32wnd->getExStyle());
1253 if(fOS2Look) {
1254 DWORD dwOldStyle = win32wnd->getOldStyle();
1255 DWORD dwStyle = win32wnd->getStyle();
1256
1257 win32wnd->setOldStyle(dwStyle);
1258 if((dwOldStyle & WS_MINIMIZE_W) && !(dwStyle & WS_MINIMIZE_W)) {
1259 //SC_RESTORE -> SC_MINIMIZE
1260 dprintf(("%x -> SC_RESTORE -> SC_MINIMIZE", win32wnd->getWindowHandle()));
1261 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), 0, SC_RESTORE, SC_MINIMIZE, hbmFrameMenu[0]);
1262 if(dwStyle & WS_MAXIMIZE_W) {
1263 //SC_MAXIMIZE -> SC_RESTORE
1264 dprintf(("%x -> SC_MAXIMIZE -> SC_RESTORE", win32wnd->getWindowHandle()));
1265 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_MAXIMIZE, SC_RESTORE, hbmFrameMenu[2]);
1266 }
1267 }
1268 else
1269 if((dwOldStyle & WS_MAXIMIZE_W) && !(dwStyle & WS_MAXIMIZE_W)) {
1270 //SC_RESTORE -> SC_MAXIMIZE
1271 dprintf(("%x -> SC_RESTORE -> SC_MAXIMIZE", win32wnd->getWindowHandle()));
1272 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_RESTORE, SC_MAXIMIZE, hbmFrameMenu[1]);
1273 }
1274 else
1275 if(!(dwOldStyle & WS_MINIMIZE_W) && (dwStyle & WS_MINIMIZE_W)) {
1276 //SC_MINIMIZE -> SC_RESTORE
1277 dprintf(("%x -> SC_MINIMIZE -> SC_RESTORE", win32wnd->getWindowHandle()));
1278 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), 0, SC_MINIMIZE, SC_RESTORE, hbmFrameMenu[2]);
1279 }
1280 else
1281 if(!(dwOldStyle & WS_MAXIMIZE_W) && (dwStyle & WS_MAXIMIZE_W)) {
1282 //SC_MAXIMIZE -> SC_RESTORE
1283 dprintf(("%x -> SC_MAXIMIZE -> SC_RESTORE", win32wnd->getWindowHandle()));
1284 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_MAXIMIZE, SC_RESTORE, hbmFrameMenu[2]);
1285 }
1286 }
1287 }
1288
1289 if ((wp.hwndInsertAfter != wpOld.hwndInsertAfter) ||
1290 (wp.x != wpOld.x) || (wp.y != wpOld.y) || (wp.cx != wpOld.cx) || (wp.cy != wpOld.cy) || (wp.flags != wpOld.flags))
1291 {
1292 ULONG flags = pswp->fl; //make a backup copy; OSLibMapWINDOWPOStoSWP will modify it
1293
1294 dprintf(("PMFRAME:WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
1295 dprintf(("%x (%s) (%d,%d), (%d,%d)", pswp->fl, DbgGetStringSWPFlags(pswp->fl), pswp->x, pswp->y, pswp->cx, pswp->cy));
1296
1297 if(win32wnd->getParent()) {
1298 OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, win32wnd->getParent()->getClientHeight(),
1299 hwnd);
1300 }
1301 else OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1302
1303 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
1304
1305 //OSLibMapWINDOWPOStoSWP can add flags, but we must not let it remove flags!
1306 if(pswp->fl & SWP_SIZE)
1307 flags |= SWP_SIZE;
1308
1309 if(pswp->fl & SWP_MOVE)
1310 flags |= SWP_MOVE;
1311
1312 pswp->fl = flags; //restore flags
1313
1314 pswp->fl |= SWP_NOADJUST;
1315 pswp->hwndInsertBehind = hwndAfter;
1316 pswp->hwnd = hwnd;
1317
1318 ret = 0xf;
1319 }
1320adjustend:
1321 //The next part needs to be done for top-level windows only
1322 if(!((win32wnd->getStyle() & (WS_POPUP_W|WS_CHILD_W)) == WS_CHILD_W))
1323 {
1324 //Setting these flags is necessary to avoid activation/focus problems
1325 if(ulFlags & SWP_DEACTIVATE) {
1326 ret |= AWP_DEACTIVATE;
1327 }
1328 if(ulFlags & SWP_ACTIVATE)
1329 {
1330 if(ulFlags & SWP_ZORDER) {
1331 dprintf(("Set FF_NOACTIVATESWP"));
1332 ULONG ulFrameFlags = WinQueryWindowUShort(hwnd, QWS_FLAGS);
1333 WinSetWindowUShort(hwnd, QWS_FLAGS, ulFrameFlags | FF_NOACTIVATESWP);
1334 }
1335
1336 if(!(ulFlags & SWP_SHOW))
1337 {
1338 ret |= AWP_ACTIVATE;
1339 }
1340 else
1341 {
1342 FrameSetFocus(hwnd);
1343 }
1344 }
1345 }
1346 else {
1347 if(ulFlags & (SWP_ACTIVATE|SWP_FOCUSACTIVATE))
1348 {
1349 win32wnd->MsgChildActivate(TRUE);
1350 if(fOS2Look) {
1351 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1352 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, (MPARAM)1, 0);
1353 }
1354 }
1355 else
1356 if(ulFlags & (SWP_DEACTIVATE|SWP_FOCUSDEACTIVATE))
1357 {
1358 win32wnd->MsgChildActivate(FALSE);
1359 if(fOS2Look) {
1360 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1361 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, 0, 0);
1362 }
1363 }
1364 }
1365 dprintf(("WM_ADJUSTWINDOWPOS ret %x flags %x", ret, WinQueryWindowUShort(hwnd, QWS_FLAGS)));
1366 rc = (MRESULT)ret;
1367 break;
1368 }
1369
1370 case WM_WINDOWPOSCHANGED:
1371 {
1372 PSWP pswp = (PSWP)mp1,pswpOld = pswp+1;
1373 SWP swpOld = *(pswp + 1);
1374 WINDOWPOS wp;
1375 ULONG flAfp = (ULONG)mp2;
1376 HWND hParent = NULLHANDLE;
1377 RECTL rect;
1378
1379 dprintf(("PMFRAME:WM_WINDOWPOSCHANGED (%x) %x %x (%s) (%d,%d) (%d,%d)", mp2, win32wnd->getWindowHandle(), pswp->fl, DbgGetStringSWPFlags(pswp->fl), pswp->x, pswp->y, pswp->cx, pswp->cy));
1380 if(win32wnd->IsParentChanging()) {
1381 goto PosChangedEnd;
1382 }
1383
1384 //SvL: When a window is made visible, then we don't receive a
1385 // WM_VRNENABLED message (for some weird reason)
1386 if(pswp->fl & SWP_SHOW) {
1387 win32wnd->callVisibleRgnNotifyProc(TRUE);
1388 }
1389 else
1390 if(pswp->fl & SWP_HIDE) {
1391 win32wnd->callVisibleRgnNotifyProc(FALSE);
1392 }
1393
1394 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0)
1395 {
1396 if(pswp->fl & SWP_RESTORE && win32wnd->getStyle() & WS_MINIMIZE_W) {
1397 dprintf(("Restoring minimized window %x", win32wnd->getWindowHandle()));
1398 win32wnd->ShowWindow(SW_RESTORE_W);
1399 }
1400 if(pswp->fl & SWP_SHOW) {
1401 WinShowWindow(win32wnd->getOS2WindowHandle(), 1);
1402 }
1403 else
1404 if(pswp->fl & SWP_HIDE) {
1405 WinShowWindow(win32wnd->getOS2WindowHandle(), 0);
1406 }
1407 //MUST call the old frame window proc!
1408 goto RunDefFrameWndProc;
1409 }
1410
1411 if(pswp->fl & (SWP_MOVE | SWP_SIZE))
1412 {
1413 if(win32wnd->isChild())
1414 {
1415 if(win32wnd->getParent()) {
1416 hParent = win32wnd->getParent()->getOS2WindowHandle();
1417 }
1418 else goto PosChangedEnd; //parent has just been destroyed
1419 }
1420 }
1421
1422
1423 if(win32wnd->getParent()) {
1424 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
1425 hwnd);
1426 }
1427 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1428
1429 wp.hwnd = win32wnd->getWindowHandle();
1430 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1431 {
1432 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1433 dprintf2(("SWP_ZORDER: %x %x", pswp->hwndInsertBehind, (wndAfter) ? wndAfter->getWindowHandle() : 0));
1434 if(wndAfter) {
1435 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1436 RELEASE_WNDOBJ(wndAfter);
1437 }
1438 else wp.hwndInsertAfter = HWND_TOP_W;
1439 }
1440
1441 if(pswp->fl & SWP_SHOW) {
1442 WinShowWindow(win32wnd->getOS2WindowHandle(), 1);
1443 }
1444 else
1445 if(pswp->fl & SWP_HIDE) {
1446 WinShowWindow(win32wnd->getOS2WindowHandle(), 0);
1447 }
1448
1449 if(flAfp & AWP_ACTIVATE)
1450 {
1451 FrameSetFocus(hwnd);
1452 }
1453
1454#ifndef USE_CALCVALIDRECT
1455 if((pswp->fl & (SWP_MOVE | SWP_SIZE)))
1456 {
1457 //CB: todo: use result for WM_CALCVALIDRECTS
1458 //Get old client rectangle (for invalidation of frame window parts later on)
1459 //Use new window height to calculate the client area
1460 mapWin32ToOS2Rect(pswp->cy, win32wnd->getClientRectPtr(), (PRECTLOS2)&rect);
1461
1462 //Note: Also updates the new window rectangle
1463 win32wnd->MsgFormatFrame(&wp);
1464
1465 if(win32wnd->isOwnDC()) {
1466 setPageXForm(win32wnd, (pDCData)GpiQueryDCData(win32wnd->getOwnDC()));
1467 }
1468
1469 if(win32wnd->CanReceiveSizeMsgs())
1470 win32wnd->MsgPosChanged((LPARAM)&wp);
1471
1472 if((pswp->fl & SWP_SIZE) && ((pswp->cx != pswpOld->cx) || (pswp->cy != pswpOld->cy)))
1473 {
1474 //redraw the frame (to prevent unnecessary client updates)
1475 BOOL redrawAll = FALSE;
1476
1477 dprintf2(("WM_WINDOWPOSCHANGED: redraw frame"));
1478 if (win32wnd->getWindowClass())
1479 {
1480 DWORD dwStyle = win32wnd->getWindowClass()->getClassLongA(GCL_STYLE_W);
1481
1482 if ((dwStyle & CS_HREDRAW_W) && (pswp->cx != pswpOld->cx))
1483 redrawAll = TRUE;
1484 else
1485 if ((dwStyle & CS_VREDRAW_W) && (pswp->cy != pswpOld->cy))
1486 redrawAll = TRUE;
1487 }
1488 else redrawAll = TRUE;
1489
1490 if(win32wnd->IsMixMaxStateChanging()) {
1491 dprintf(("WM_CALCVALIDRECT: window changed min/max/restore state, invalidate entire window"));
1492 redrawAll = TRUE;
1493 }
1494
1495 if (redrawAll)
1496 {
1497 //CB: redraw all children for now
1498 // -> problems with update region if we don't do it
1499 // todo: rewrite whole handling
1500 WinInvalidateRect(hwnd,NULL,TRUE);
1501 }
1502 else
1503 {
1504 HPS hps = WinGetPS(hwnd);
1505 RECTL frame,client,arcl[4];
1506
1507 WinQueryWindowRect(hwnd,&frame);
1508
1509 //top
1510 arcl[0].xLeft = 0;
1511 arcl[0].xRight = frame.xRight;
1512 arcl[0].yBottom = rect.yTop;
1513 arcl[0].yTop = frame.yTop;
1514 //right
1515 arcl[1].xLeft = rect.xRight;
1516 arcl[1].xRight = frame.xRight;
1517 arcl[1].yBottom = 0;
1518 arcl[1].yTop = frame.yTop;
1519 //left
1520 arcl[2].xLeft = 0;
1521 arcl[2].xRight = rect.xLeft;
1522 arcl[2].yBottom = 0;
1523 arcl[2].yTop = frame.yTop;
1524 //bottom
1525 arcl[3].xLeft = 0;
1526 arcl[3].xRight = frame.xRight;
1527 arcl[3].yBottom = 0;
1528 arcl[3].yTop = rect.yBottom;
1529
1530 HRGN hrgn = GpiCreateRegion(hps,4,(PRECTL)&arcl);
1531
1532 WinInvalidateRegion(hwnd,hrgn,FALSE);
1533 GpiDestroyRegion(hps,hrgn);
1534 WinReleasePS(hps);
1535 }
1536 }
1537 }
1538 else
1539 {
1540#endif //USE_CALCVALIDRECT
1541 if(win32wnd->CanReceiveSizeMsgs())
1542 win32wnd->MsgPosChanged((LPARAM)&wp);
1543#ifndef USE_CALCVALIDRECT
1544 }
1545#endif
1546
1547PosChangedEnd:
1548 rc = (MRESULT)FALSE;
1549 break;
1550 }
1551
1552 case WM_CALCVALIDRECTS:
1553#ifdef USE_CALCVALIDRECT
1554 {
1555 PRECTL oldRect = (PRECTL)mp1, newRect = oldRect+1;
1556 PSWP pswp = (PSWP)mp2;
1557 SWP swpOld;
1558 WINDOWPOS wp;
1559 RECTL newClientRect, oldClientRect;
1560 ULONG nccalcret;
1561// UINT res = CVR_ALIGNLEFT | CVR_ALIGNTOP;
1562 UINT res = 0;
1563
1564 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
1565
1566 //Get old position info
1567 WinQueryWindowPos(hwnd, &swpOld);
1568
1569 if(win32wnd->getParent()) {
1570 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
1571 win32wnd->getParent()->getClientRectPtr()->left,
1572 win32wnd->getParent()->getClientRectPtr()->top,
1573 hwnd);
1574 }
1575 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), 0, 0, hwnd);
1576
1577 wp.hwnd = win32wnd->getWindowHandle();
1578 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1579 {
1580 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1581 if(wndAfter) {
1582 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1583 RELEASE_WNDOBJ(wndAfter);
1584 }
1585 else wp.hwndInsertAfter = HWND_TOP_W;
1586 }
1587
1588 //Get old client rectangle
1589 mapWin32ToOS2Rect(oldRect->yTop - oldRect->yBottom, win32wnd->getClientRectPtr(), (PRECTLOS2)&oldClientRect);
1590
1591 //Note: Also updates the new window rectangle
1592 nccalcret = win32wnd->MsgFormatFrame(&wp);
1593
1594 //Get new client rectangle
1595 mapWin32ToOS2Rect(pswp->cy, win32wnd->getClientRectPtr(), (PRECTLOS2)&newClientRect);
1596
1597 if(nccalcret == 0) {
1598 res = CVR_ALIGNTOP | CVR_ALIGNLEFT;
1599 }
1600 else {
1601 if(nccalcret & WVR_ALIGNTOP_W) {
1602 res |= CVR_ALIGNTOP;
1603 }
1604 else
1605 if(nccalcret & WVR_ALIGNBOTTOM_W) {
1606 res |= CVR_ALIGNBOTTOM;
1607 }
1608
1609 if(nccalcret & WVR_ALIGNLEFT_W) {
1610 res |= CVR_ALIGNLEFT;
1611 }
1612 else
1613 if(nccalcret & WVR_ALIGNRIGHT_W) {
1614 res |= CVR_ALIGNRIGHT;
1615 }
1616
1617 if(nccalcret & WVR_REDRAW_W) {//WVR_REDRAW_W = (WVR_HREDRAW | WVR_VREDRAW)
1618 res |= CVR_REDRAW;
1619 }
1620 else
1621 if(nccalcret & WVR_VALIDRECTS_W) {
1622 //TODO:
1623 //res = 0;
1624 }
1625 }
1626 if(win32wnd->IsMixMaxStateChanging()) {
1627 dprintf(("WM_CALCVALIDRECT: window changed min/max/restore state, invalidate entire window"));
1628 res |= CVR_REDRAW;
1629 }
1630 if(res == (CVR_ALIGNTOP|CVR_ALIGNLEFT)) {
1631 oldRect->xRight -= oldClientRect.xLeft;
1632 oldRect->yBottom += oldClientRect.yBottom;
1633 newRect->xRight -= newClientRect.xLeft;
1634 newRect->yBottom += newClientRect.yBottom;
1635 }
1636 rc = res;
1637 break;
1638 }
1639#else
1640 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
1641 rc = (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
1642 break;
1643#endif
1644
1645 case WM_CALCFRAMERECT:
1646 dprintf(("PMFRAME:WM_CALCFRAMERECT %x", win32wnd->getWindowHandle()));
1647 rc = (MRESULT)TRUE;
1648 break;
1649
1650 case WM_QUERYCTLTYPE:
1651 // This is a frame window
1652 dprintf(("PMFRAME:WM_QUERYCTLTYPE %x", win32wnd->getWindowHandle()));
1653 rc = (MRESULT)CCT_FRAME;
1654 break;
1655
1656#ifdef DEBUG
1657 case WM_QUERYFOCUSCHAIN:
1658 dprintf2(("PMFRAME:WM_QUERYFOCUSCHAIN %x fsCmd %x (%s) parent %x", win32wnd->getWindowHandle(), SHORT1FROMMP(mp1), DbgPrintQFCFlags(SHORT1FROMMP(mp1)), (mp2) ? OS2ToWin32Handle((DWORD)mp2) : 0));
1659
1660 RestoreOS2TIB();
1661 rc = pfnFrameWndProc(hwnd, msg, mp1, mp2);
1662 SetWin32TIB();
1663 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));
1664 break;
1665// goto RunDefFrameWndProc;
1666#endif
1667
1668 case WM_FOCUSCHANGE:
1669 {
1670 HWND hwndFocus = (HWND)mp1;
1671 HWND hwndLoseFocus, hwndGainFocus;
1672 USHORT usSetFocus = SHORT1FROMMP(mp2);
1673 USHORT fsFocusChange = SHORT2FROMMP(mp2);
1674
1675 //Save window that gains focus so we can determine which
1676 //process we lose activation to
1677 hwndFocusChange = (HWND)mp1;
1678
1679 dprintf(("PMFRAME:WM_FOCUSCHANGE %x %x (%x) %x %x", win32wnd->getWindowHandle(), OS2ToWin32Handle(hwndFocus), hwndFocus, usSetFocus, fsFocusChange));
1680 goto RunDefFrameWndProc;
1681 }
1682
1683#ifdef DEBUG
1684 case WM_SETFOCUS:
1685 {
1686 dprintf(("PMFRAME: WM_SETFOCUS %x %x", win32wnd->getWindowHandle(), hwnd));
1687 goto RunDefFrameWndProc;
1688 }
1689#endif
1690
1691 case WM_ACTIVATE:
1692 {
1693 HWND hwndTitle;
1694 USHORT flags = WinQueryWindowUShort(hwnd,QWS_FLAGS);
1695
1696 dprintf(("PMFRAME: WM_ACTIVATE %x %x %x", win32wnd->getWindowHandle(), mp1, OS2ToWin32Handle((DWORD)mp2)));
1697 if (win32wnd->IsWindowCreated())
1698 {
1699 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
1700 if(fOS2Look) {
1701 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1702 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, mp1, 0);
1703 }
1704 if(SHORT1FROMMP(mp1) == 0) {
1705 //deactivate
1706 WinSendDlgItemMsg(hwnd, FID_CLIENT, WM_ACTIVATE, mp1, mp2);
1707 }
1708 PID pidThis, pidPartner, pidTemp;
1709 TID tidPartner;
1710 HENUM henum;
1711 HWND hwndEnum;
1712
1713 WinQueryWindowProcess(hwnd, &pidThis, NULL);
1714 WinQueryWindowProcess(hwndFocusChange, &pidPartner, &tidPartner);
1715
1716 if(pidThis != pidPartner) {
1717 //Gain or lose activation to window in other process
1718 //must send WM_ACTIVATEAPP to top-level windows
1719
1720 //Iterate over all child windows of the desktop
1721 henum = WinBeginEnumWindows(HWND_DESKTOP);
1722
1723 while(hwndEnum = WinGetNextWindow(henum))
1724 {
1725 WinQueryWindowProcess(hwndEnum, &pidTemp, NULL);
1726 if(pidTemp == pidThis)
1727 {
1728 SendMessageA(OS2ToWin32Handle(hwndEnum), WM_ACTIVATEAPP_W, (WPARAM)SHORT1FROMMP(mp1), (LPARAM)tidPartner);
1729 }
1730 }
1731 WinEndEnumWindows(henum);
1732 }
1733 if(SHORT1FROMMP(mp1)) {
1734 //activate
1735 WinSendDlgItemMsg(hwnd, FID_CLIENT, WM_ACTIVATE, mp1, mp2);
1736 }
1737
1738 //CB: show owner behind the dialog
1739 if (win32wnd->IsModalDialog())
1740 {
1741 if(win32wnd->getOwner()) {
1742 Win32BaseWindow *topOwner = Win32BaseWindow::GetWindowFromHandle(win32wnd->getOwner()->GetTopParent());
1743
1744 if (topOwner) {
1745 WinSetWindowPos(topOwner->getOS2FrameWindowHandle(),hwnd,0,0,0,0,SWP_ZORDER);
1746 RELEASE_WNDOBJ(topOwner);
1747 }
1748 }
1749 }
1750 }
1751 else
1752 {
1753 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
1754 }
1755 rc = 0;
1756 break;
1757 }
1758
1759 case WM_ENABLE:
1760 dprintf(("PMFRAME: WM_ENABLE %x", hwnd));
1761 win32wnd->MsgEnable(SHORT1FROMMP(mp1));
1762 break;
1763
1764 case WM_SHOW:
1765 dprintf(("PMFRAME: WM_SHOW %x %d", hwnd, mp1));
1766 //show client window
1767 WinShowWindow(win32wnd->getOS2WindowHandle(), (BOOL)mp1);
1768 break;
1769
1770 case WM_QUERYTRACKINFO:
1771 {
1772 PTRACKINFO trackInfo = (PTRACKINFO)mp2;
1773
1774 dprintf(("PMFRAME:WM_QUERYTRACKINFO %x", win32wnd->getWindowHandle()));
1775 trackInfo->cxBorder = 4;
1776 trackInfo->cyBorder = 4;
1777 win32wnd->AdjustTrackInfo((PPOINT)&trackInfo->ptlMinTrackSize,(PPOINT)&trackInfo->ptlMaxTrackSize);
1778 rc = (MRESULT)TRUE;
1779 break;
1780 }
1781
1782 case WM_QUERYBORDERSIZE:
1783 {
1784 PWPOINT size = (PWPOINT)mp1;
1785
1786 dprintf(("PMFRAME:WM_QUERYBORDERSIZE %x", win32wnd->getWindowHandle()));
1787
1788 size->x = 0;
1789 size->y = 0;
1790 rc = (MRESULT)TRUE;
1791 break;
1792 }
1793
1794#ifdef DEBUG
1795 case WM_QUERYFRAMEINFO:
1796 dprintf(("PMFRAME:WM_QUERYFRAMEINFO %x", win32wnd->getWindowHandle()));
1797 goto RunDefFrameWndProc;
1798#endif
1799
1800 case WM_FORMATFRAME:
1801 dprintf(("PMFRAME:WM_FORMATFRAME %x", win32wnd->getWindowHandle()));
1802 break;
1803
1804#ifdef DEBUG
1805 case WM_ADJUSTFRAMEPOS:
1806 {
1807 PSWP pswp = (PSWP)mp1;
1808
1809 dprintf(("PMFRAME:WM_ADJUSTFRAMEPOS %x %x %x (%s) (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->hwnd, pswp->fl, DbgGetStringSWPFlags(pswp->fl), pswp->x, pswp->y, pswp->cx, pswp->cy));
1810 goto RunDefFrameWndProc;
1811 }
1812
1813 case WM_OWNERPOSCHANGE:
1814 {
1815 PSWP pswp = (PSWP)mp1;
1816
1817 dprintf(("PMFRAME:WM_OWNERPOSCHANGE %x %x %x (%s) (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), pswp->hwnd, pswp->fl, DbgGetStringSWPFlags(pswp->fl), pswp->x, pswp->y, pswp->cx, pswp->cy));
1818 goto RunDefFrameWndProc;
1819 }
1820#endif
1821
1822 case WM_MINMAXFRAME:
1823 {
1824 PSWP swp = (PSWP)mp1;
1825
1826 if (!win32wnd->IsWindowCreated()) goto RunDefWndProc;
1827
1828 dprintf(("PMFRAME:WM_MINMAXFRAME %x",hwnd));
1829 if ((swp->fl & SWP_MAXIMIZE) == SWP_MAXIMIZE)
1830 {
1831 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MINIMIZE_W) | WS_MAXIMIZE_W);
1832
1833 RECT rect;
1834
1835 rect.left = rect.top = rect.right = rect.bottom = 0;
1836 win32wnd->AdjustMaximizedRect(&rect);
1837 swp->x += rect.left;
1838 swp->cx += rect.right-rect.left;
1839 swp->y -= rect.bottom;
1840 swp->cy += rect.bottom-rect.top;
1841 }
1842 else
1843 if ((swp->fl & SWP_MINIMIZE) == SWP_MINIMIZE)
1844 {
1845 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MAXIMIZE_W) | WS_MINIMIZE_W);
1846 }
1847 else
1848 if ((swp->fl & SWP_RESTORE) == SWP_RESTORE)
1849 {
1850 win32wnd->setStyle(win32wnd->getStyle() & ~(WS_MINIMIZE_W | WS_MAXIMIZE_W));
1851 }
1852 goto RunDefWndProc;
1853 }
1854
1855#ifdef DEBUG
1856 case WM_UPDATEFRAME:
1857 dprintf(("PMFRAME:WM_UPDATEFRAME %x", win32wnd->getWindowHandle()));
1858 goto RunDefFrameWndProc;
1859#endif
1860
1861 case WM_TRACKFRAME:
1862 dprintf(("PMFRAME: WM_TRACKFRAME %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
1863 if(fOS2Look) {//sent by titlebar control
1864 Frame_SysCommandSizeMove(win32wnd, SC_MOVE_W+HTCAPTION_W);
1865 }
1866 rc = 0;
1867 break;
1868
1869 case WM_SYSCOMMAND:
1870 dprintf(("PMFRAME: WM_SYSCOMMAND %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
1871 if (fOS2Look == OS2_APPEARANCE_SYSMENU && mp1 == (MPARAM)OSSC_SYSMENU)
1872 goto RunDefFrameWndProc;
1873
1874 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
1875 RELEASE_WNDOBJ(win32wnd);
1876 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
1877 }
1878 if(win32wnd)
1879 win32wnd->DispatchMsgA(pWinMsg);
1880 break;
1881
1882#ifdef DEBUG
1883 case WM_DDE_INITIATE:
1884 case WM_DDE_INITIATEACK:
1885 case WM_DDE_REQUEST:
1886 case WM_DDE_ACK:
1887 case WM_DDE_DATA:
1888 case WM_DDE_ADVISE:
1889 case WM_DDE_UNADVISE:
1890 case WM_DDE_POKE:
1891 case WM_DDE_EXECUTE:
1892 case WM_DDE_TERMINATE:
1893 dprintf(("PMFRAME: WM_DDE %x %x", msg, win32wnd->getWindowHandle()));
1894 break;
1895#endif
1896
1897 default:
1898 goto RunDefFrameWndProc;
1899 }
1900 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1901 RestoreOS2TIB();
1902 return (MRESULT)rc;
1903
1904RunDefFrameWndProc:
1905 dprintf2(("RunDefFrameWndProc"));
1906 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1907 RestoreOS2TIB();
1908 return pfnFrameWndProc(hwnd, msg, mp1, mp2);
1909
1910RunDefWndProc:
1911 dprintf2(("RunDefWndProc"));
1912 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1913 RestoreOS2TIB();
1914 //calling WinDefWindowProc here breaks Opera hotlist window (WM_ADJUSTWINDOWPOS)
1915// return pfnFrameWndProc(hwnd, msg, mp1, mp2);
1916 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
1917}
1918//******************************************************************************
1919//******************************************************************************
1920void FrameSetFocus(HWND hwnd)
1921{
1922 HWND hwndFocusSave = WinQueryWindowULong(hwnd, QWL_HWNDFOCUSSAVE);
1923 if(!WinIsWindow(hab, hwndFocusSave)) {
1924 hwndFocusSave = WinWindowFromID(hwnd, FID_CLIENT);
1925 WinSetWindowULong(hwnd, QWL_HWNDFOCUSSAVE, hwndFocusSave);
1926 }
1927 dprintf(("FrameSetFocus: hwndFocusSave %x %x", OS2ToWin32Handle(hwndFocusSave), hwndFocusSave));
1928 WinSetFocus(HWND_DESKTOP, hwndFocusSave);
1929
1930 ULONG ulFrameFlags = WinQueryWindowUShort(hwnd, QWS_FLAGS);
1931 ulFrameFlags &= ~FF_NOACTIVATESWP;
1932 WinSetWindowUShort(hwnd, QWS_FLAGS, ulFrameFlags);
1933}
1934//******************************************************************************
1935//******************************************************************************
1936void FrameReplaceMenuItem(HWND hwndMenu, ULONG nIndex, ULONG idOld, ULONG idNew,
1937 HBITMAP hbmNew)
1938{
1939 MENUITEM mi;
1940
1941 if (!hwndMenu)
1942 return;
1943
1944 WinEnableWindowUpdate(hwndMenu, FALSE);
1945
1946 if (WinSendMsg(hwndMenu, MM_QUERYITEM, MPFROM2SHORT(idOld, TRUE), MPFROMP(&mi)))
1947 {
1948 WinSendMsg(hwndMenu, MM_REMOVEITEM, (MPARAM)idOld, 0);
1949 mi.afStyle = MIS_BITMAP | MIS_SYSCOMMAND;
1950 mi.afAttribute = 0;
1951 mi.hwndSubMenu = 0;
1952 mi.id = idNew;
1953 mi.hItem = (ULONG)hbmNew;
1954 WinSendMsg(hwndMenu, MM_INSERTITEM, (MPARAM)&mi, 0);
1955 }
1956 WinEnableWindowUpdate(hwndMenu, TRUE);
1957
1958 WinInvalidateRect(hwndMenu, NULL, TRUE);
1959}
1960//******************************************************************************
1961//******************************************************************************
1962static char *PMDragExtractFiles(PDRAGINFO pDragInfo, ULONG *pcItems, ULONG *pulBytes)
1963{
1964 PDRAGITEM pDragItem;
1965 int i, cItems;
1966 BOOL ret;
1967 char szFileName[CCHMAXPATH];
1968 char szContainerName[CCHMAXPATH];
1969 ULONG ulBytes;
1970 char *pszCurFile = NULL;
1971
1972 /* Get access to the DRAGINFO data structure */
1973 if(!DrgAccessDraginfo(pDragInfo)) {
1974 return NULL;
1975 }
1976
1977 cItems = DrgQueryDragitemCount(pDragInfo);
1978
1979 //computer memory required to hold all filenames
1980 int bufsize = 0;
1981 for (i = 0; i < cItems; i++) {
1982 pDragItem = DrgQueryDragitemPtr(pDragInfo, i);
1983
1984 bufsize += DrgQueryStrNameLen(pDragItem->hstrContainerName) + DrgQueryStrNameLen(pDragItem->hstrSourceName);
1985 bufsize++; //0 terminator
1986 bufsize++; //+ potential missing backslash
1987 }
1988 bufsize++; //extra 0 terminator
1989 char *pszFiles = (char *)malloc(bufsize);
1990 if(pszFiles == NULL) {
1991 dprintf(("Out of memory!!"));
1992 DebugInt3();
1993 goto failure;
1994 }
1995 memset(pszFiles, 0, bufsize);
1996
1997 pszCurFile = pszFiles;
1998
1999 //copy all filenames
2000 for (i = 0; i < cItems; i++) {
2001 char *pszTemp = pszCurFile;
2002
2003 pDragItem = DrgQueryDragitemPtr(pDragInfo, i);
2004
2005 ulBytes = DrgQueryStrNameLen(pDragItem->hstrContainerName);
2006 ulBytes = DrgQueryStrName(pDragItem->hstrContainerName,
2007 ulBytes, pszCurFile);
2008 if(pszCurFile[ulBytes-1] != '\\') {
2009 pszCurFile[ulBytes] = '\\';
2010 pszCurFile++;
2011 }
2012 pszCurFile += ulBytes;
2013
2014 ulBytes = DrgQueryStrNameLen(pDragItem->hstrSourceName);
2015 ulBytes = DrgQueryStrName(pDragItem->hstrSourceName,
2016 ulBytes+1, pszCurFile);
2017 pszCurFile += ulBytes + 1; //+ terminator
2018
2019 dprintf(("dropped file %s", pszTemp));
2020 }
2021
2022 /* Release the draginfo data structure */
2023 DrgFreeDraginfo(pDragInfo);
2024
2025 *pulBytes = bufsize;
2026 *pcItems = cItems;
2027
2028 return pszFiles;
2029
2030failure:
2031 /* Release the draginfo data structure */
2032 DrgFreeDraginfo(pDragInfo);
2033 if(pszFiles) {
2034 free(pszFiles);
2035 }
2036 return NULL;
2037}
2038//******************************************************************************
2039//******************************************************************************
2040static BOOL PMDragValidate(PDRAGINFO pDragInfo)
2041{
2042 PDRAGITEM pDragItem;
2043 ULONG ulBytes;
2044 int i, cItems;
2045 BOOL ret;
2046 char szFileName[CCHMAXPATH];
2047 char szContainerName[CCHMAXPATH];
2048 USHORT usOp = DO_MOVE;
2049
2050 /* Get access to the DRAGINFO data structure */
2051 if(!DrgAccessDraginfo(pDragInfo)) {
2052 return FALSE;
2053 }
2054
2055 /* Can we accept this drop? */
2056 switch (pDragInfo->usOperation) {
2057 /* Return DOR_NODROPOP if current operation */
2058 /* is link or unknown */
2059 case DO_LINK:
2060 case DO_COPY:
2061 case DO_UNKNOWN:
2062 goto failure;
2063
2064 /* Our default operation is Move */
2065 case DO_MOVE:
2066 case DO_DEFAULT:
2067 pDragItem = DrgQueryDragitemPtr(pDragInfo, 0);
2068 ulBytes = DrgQueryStrName(pDragItem->hstrContainerName,
2069 sizeof(szContainerName),
2070 szContainerName);
2071 ulBytes = DrgQueryStrName(pDragItem->hstrSourceName,
2072 sizeof(szFileName),
2073 szFileName);
2074 if (!ulBytes) {
2075 goto failure;
2076 }
2077
2078 dprintf(("dropped file %s%s", szContainerName, szFileName));
2079 break;
2080 }
2081
2082 cItems = DrgQueryDragitemCount(pDragInfo);
2083
2084 /* Now, we need to look at each item in turn */
2085 for (i = 0; i < cItems; i++) {
2086 pDragItem = DrgQueryDragitemPtr(pDragInfo, i);
2087
2088 /* Make sure we can move for a Move request */
2089 if (!((pDragItem->fsSupportedOps & DO_MOVEABLE) &&
2090 (usOp == (USHORT)DO_MOVE)))
2091 {
2092 dprintf(("item %d not accepted", i));
2093 goto failure;
2094 }
2095 }
2096 /* Release the draginfo data structure */
2097 DrgFreeDraginfo(pDragInfo);
2098 return TRUE;
2099
2100failure:
2101 DrgFreeDraginfo(pDragInfo);
2102 return FALSE;
2103}
2104//******************************************************************************
2105//******************************************************************************
2106#ifdef DEBUG
2107static char *DbgGetStringSWPFlags(ULONG flags)
2108{
2109 static char szSWPFlags[512];
2110
2111 szSWPFlags[0] = 0;
2112
2113 if(flags & SWP_SIZE) {
2114 strcat(szSWPFlags, "SWP_SIZE ");
2115 }
2116 if(flags & SWP_MOVE) {
2117 strcat(szSWPFlags, "SWP_MOVE ");
2118 }
2119 if(flags & SWP_ZORDER) {
2120 strcat(szSWPFlags, "SWP_ZORDER ");
2121 }
2122 if(flags & SWP_SHOW) {
2123 strcat(szSWPFlags, "SWP_SHOW ");
2124 }
2125 if(flags & SWP_HIDE) {
2126 strcat(szSWPFlags, "SWP_HIDE ");
2127 }
2128 if(flags & SWP_NOREDRAW) {
2129 strcat(szSWPFlags, "SWP_NOREDRAW ");
2130 }
2131 if(flags & SWP_NOADJUST) {
2132 strcat(szSWPFlags, "SWP_NOADJUST ");
2133 }
2134 if(flags & SWP_ACTIVATE) {
2135 strcat(szSWPFlags, "SWP_ACTIVATE ");
2136 }
2137 if(flags & SWP_DEACTIVATE) {
2138 strcat(szSWPFlags, "SWP_DEACTIVATE ");
2139 }
2140 if(flags & SWP_EXTSTATECHANGE) {
2141 strcat(szSWPFlags, "SWP_EXTSTATECHANGE ");
2142 }
2143 if(flags & SWP_MINIMIZE) {
2144 strcat(szSWPFlags, "SWP_MINIMIZE ");
2145 }
2146 if(flags & SWP_MAXIMIZE) {
2147 strcat(szSWPFlags, "SWP_MAXIMIZE ");
2148 }
2149 if(flags & SWP_RESTORE) {
2150 strcat(szSWPFlags, "SWP_RESTORE ");
2151 }
2152 if(flags & SWP_FOCUSACTIVATE) {
2153 strcat(szSWPFlags, "SWP_FOCUSACTIVATE ");
2154 }
2155 if(flags & SWP_FOCUSDEACTIVATE) {
2156 strcat(szSWPFlags, "SWP_FOCUSDEACTIVATE ");
2157 }
2158 if(flags & SWP_NOAUTOCLOSE) {
2159 strcat(szSWPFlags, "SWP_NOAUTOCLOSE ");
2160 }
2161 return szSWPFlags;
2162}
2163static char *DbgPrintQFCFlags(ULONG flags)
2164{
2165 static char szQFCFlags[64];
2166
2167 szQFCFlags[0] = 0;
2168
2169 if(flags & QFC_NEXTINCHAIN) {
2170 strcat(szQFCFlags, "QFC_NEXTINCHAIN");
2171 }
2172 else
2173 if(flags & QFC_ACTIVE) {
2174 strcat(szQFCFlags, "QFC_ACTIVE");
2175 }
2176 else
2177 if(flags & QFC_FRAME) {
2178 strcat(szQFCFlags, "QFC_FRAME");
2179 }
2180 else
2181 if(flags & QFC_SELECTACTIVE) {
2182 strcat(szQFCFlags, "QFC_SELECTACTIVE");
2183 }
2184 else
2185 if(flags & QFC_PARTOFCHAIN) {
2186 strcat(szQFCFlags, "QFC_PARTOFCHAIN");
2187 }
2188
2189 return szQFCFlags;
2190}
2191#endif
2192//******************************************************************************
2193//******************************************************************************
Note: See TracBrowser for help on using the repository browser.