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

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

PM windows should have no owner if none is specified. (instead of their parent)

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