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

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