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

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

KOMH: DBCS updates/fixes

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