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

Last change on this file since 10276 was 10276, checked in by sandervl, 22 years ago

compile fixes

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