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

Last change on this file since 21348 was 21348, checked in by vladest, 16 years ago

Fixed double chars in standalone apps
Fixed umlaut and other national characters suppot in inputline

File size: 94.2 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))
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 win32wnd->MsgButton(pWinMsg);
878
879 rc = (MRESULT)TRUE;
880 break;
881
882 case WM_BUTTON2MOTIONSTART:
883 case WM_BUTTON2MOTIONEND:
884 case WM_BUTTON2CLICK:
885 case WM_BUTTON1MOTIONSTART:
886 case WM_BUTTON1MOTIONEND:
887 case WM_BUTTON1CLICK:
888 case WM_BUTTON3MOTIONSTART:
889 case WM_BUTTON3MOTIONEND:
890 case WM_BUTTON3CLICK:
891 rc = (MRESULT)TRUE;
892 break;
893
894 case WM_MOUSEMOVE:
895 {
896 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
897 RELEASE_WNDOBJ(win32wnd);
898 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
899 }
900 if(win32wnd)
901 win32wnd->MsgMouseMove(pWinMsg);
902 break;
903 }
904
905 case WM_CONTROL:
906 goto RunDefWndProc;
907
908 case WM_COMMAND:
909 dprintf(("OS2: WM_COMMAND %x %x %x", hwnd, mp1, mp2));
910 win32wnd->DispatchMsgA(pWinMsg);
911 break;
912
913 case WM_SYSCOMMAND:
914 dprintf(("OS2: WM_SYSCOMMAND %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
915 win32wnd->DispatchMsgA(pWinMsg);
916 break;
917
918 case WM_RENDERFMT:
919 case WM_RENDERALLFMTS:
920 case WM_DESTROYCLIPBOARD:
921 case WM_DRAWCLIPBOARD:
922 win32wnd->DispatchMsgA(pWinMsg);
923 break;
924
925 case WM_CHAR_SPECIAL:
926 /* NO BREAK! FALLTHRU CASE! */
927
928 case WM_CHAR:
929 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)));
930 win32wnd->MsgChar(pWinMsg);
931 /*
932 * now, we need to send WM_CHAR message
933 * to inform Win32 window that an char was input
934 * We ignoring wm_char sending in case of Ctrl or Alt pressed
935 * Also we
936 */
937 /* sending only after WINWM_KEYDOWN */
938 /* checking for alphanum chars and number. did I miss something?
939 */
940 if (WINWM_KEYDOWN == pWinMsg->message &&
941 (((SHORT1FROMMP(mp1) & KC_CHAR) &&
942 !(SHORT1FROMMP(mp1) & KC_VIRTUALKEY)) ||
943 (SHORT1FROMMP(mp1) & KC_DEADKEY)))
944 {
945 MSG extramsg;
946 char cpfrom[10] = {0};
947 char cpto[10] = {0};
948 ULONG ulCpSize, ulCP;
949
950
951 memcpy(&extramsg, pWinMsg, sizeof(MSG));
952 extramsg.message = WINWM_CHAR;
953 DosQueryCp(sizeof(ulCP), &ulCP, &ulCpSize);
954 sprintf(cpfrom,"IBM-%d\0", ulCP);
955 sprintf(cpto,"IBM-%d\0", GetDisplayCodepage());
956 if (cp2cp(cpfrom, cpto, (char*)&mp2, (char*)&extramsg.wParam, 1))
957 extramsg.wParam = (ULONG)mp2;
958
959 if(SHORT1FROMMP(mp1) & KC_DEADKEY)
960 {
961 extramsg.message++; //WM_DEADCHAR/WM_SYSDEADCHAR
962 }
963
964 win32wnd->MsgChar(&extramsg);
965 goto RunDefWndProc;
966 }
967 break;
968
969 case WM_TIMER:
970 dprintf(("OS2: WM_TIMER %x %x time %x", win32wnd->getWindowHandle(), pWinMsg->wParam, GetTickCount()));
971 win32wnd->DispatchMsgA(pWinMsg);
972 goto RunDefWndProc;
973
974 case WM_SETWINDOWPARAMS:
975 {
976 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
977
978 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
979 if(wndParams->fsStatus & WPM_TEXT) {
980 win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText);
981 }
982 goto RunDefWndProc;
983 }
984
985 case WM_QUERYWINDOWPARAMS:
986 {
987 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
988 ULONG textlen;
989 PSZ wintext;
990
991 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
992 {
993 if(wndpars->fsStatus & WPM_TEXT)
994 win32wnd->MsgGetText(wndpars->pszText, wndpars->cchText);
995 if(wndpars->fsStatus & WPM_CCHTEXT)
996 wndpars->cchText = win32wnd->MsgGetTextLength();
997
998 wndpars->fsStatus = 0;
999 wndpars->cbCtlData = 0;
1000 wndpars->cbPresParams = 0;
1001 rc = (MRESULT)TRUE;
1002 break;
1003 }
1004 goto RunDefWndProc;
1005 }
1006
1007 case WM_PAINT:
1008 {
1009 RECTL rectl;
1010 BOOL rc;
1011
1012 win32wnd->checkForDirtyUpdateRegion();
1013
1014 rc = WinQueryUpdateRect(hwnd, &rectl);
1015 dprintf(("OS2: WM_PAINT %x (%d,%d) (%d,%d) rc=%d", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop, rc));
1016
1017 if(rc && win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
1018 rectl.yBottom != rectl.yTop) && !IsIconic(win32wnd->GetTopParent()))
1019 {
1020 win32wnd->DispatchMsgA(pWinMsg);
1021 if(WinQueryUpdateRect(hwnd, NULL) == TRUE)
1022 {//the application didn't validate the update region; Windows
1023 //will only send a WM_PAINT once until another part of the
1024 //window is invalidated. Unfortunately PM keeps on sending
1025 //WM_PAINT messages until we validate the update region.
1026
1027 win32wnd->saveAndValidateUpdateRegion();
1028 }
1029 }
1030 else goto RunDefWndProc;
1031 break;
1032 }
1033
1034 case WM_ERASEBACKGROUND:
1035 {
1036 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
1037 rc = (MRESULT)FALSE;
1038 break;
1039 }
1040
1041 case WM_CALCVALIDRECTS:
1042 dprintf(("OS2: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
1043 rc = (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
1044 break;
1045
1046 case WM_REALIZEPALETTE:
1047 {
1048 dprintf(("OS2: WM_REALIZEPALETTE %x", win32wnd->getWindowHandle()));
1049 win32wnd->DispatchMsgA(pWinMsg);
1050 break;
1051 }
1052
1053 case WM_HSCROLL:
1054 case WM_VSCROLL:
1055 dprintf(("OS2: %s %x %x %x", (msg == WM_HSCROLL) ? "WM_HSCROLL" : "WM_VSCROLL", win32wnd->getWindowHandle(), mp1, mp2));
1056 win32wnd->DispatchMsgA(pWinMsg);
1057 break;
1058
1059 case WM_IMEREQUEST:
1060 case WM_IMECONTROL:
1061 case WM_IMENOTIFY:
1062 if( pWinMsg->message )
1063 {
1064 win32wnd->DispatchMsgA( pWinMsg );
1065
1066 if(( pWinMsg->message = WM_IME_NOTIFY_W ) &&
1067 ( pWinMsg->wParam == IMN_SETOPENSTATUS_W ))
1068 {
1069 MSG m;
1070
1071 m.message = WM_IME_NOTIFY_W;
1072 m.wParam = IMN_SETCONVERSIONMODE_W;
1073 m.lParam = 0;
1074
1075 win32wnd->DispatchMsgA( &m );
1076 }
1077 }
1078 else
1079 goto RunDefWndProc;
1080 break;
1081
1082 case DM_DRAGOVER:
1083 {
1084 PDRAGINFO pDragInfo = (PDRAGINFO)mp1;
1085 PDRAGITEM pDragItem;
1086 USHORT sxDrop = SHORT1FROMMP(mp2);
1087 USHORT syDrop = SHORT2FROMMP(mp2);
1088
1089 dprintf(("OS2: DM_DRAGOVER %x (%d,%d)", win32wnd->getWindowHandle(), sxDrop, syDrop));
1090
1091 if(fDragDropDisabled) {
1092 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
1093 break;
1094 }
1095
1096 //does this window accept dropped files?
1097 if(!DragDropAccept(win32wnd->getWindowHandle())) {
1098 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
1099 break;
1100 }
1101
1102 if(PMDragValidate(pDragInfo) == FALSE) {
1103 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
1104 break;
1105 }
1106 if(win32wnd->isDragDropActive() == FALSE) {
1107 ULONG ulBytes, cItems;
1108 char *pszFiles;
1109
1110 pszFiles = PMDragExtractFiles(pDragInfo, &cItems, &ulBytes);
1111 if(pszFiles) {
1112 POINT point = {sxDrop, syDrop};
1113 if(DragDropDragEnter(win32wnd->getWindowHandle(), point, cItems, pszFiles, ulBytes, DROPEFFECT_COPY_W) == FALSE) {
1114 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
1115 }
1116 else {
1117 fDragDropActive = TRUE;
1118 rc = (MRFROM2SHORT(DOR_DROP, DO_MOVE));
1119 win32wnd->setDragDropActive(TRUE);
1120 }
1121 free(pszFiles);
1122 }
1123 else {
1124 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
1125 }
1126 }
1127 else {
1128 if(DragDropDragOver(win32wnd->getWindowHandle(), DROPEFFECT_COPY_W) == FALSE) {
1129 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
1130 }
1131 else rc = (MRFROM2SHORT(DOR_DROP, DO_MOVE));
1132 }
1133 break;
1134 }
1135
1136 case DM_DRAGLEAVE:
1137 {
1138 dprintf(("OS2: DM_DRAGLEAVE %x", win32wnd->getWindowHandle()));
1139
1140 if(fDragDropDisabled) {
1141 break;
1142 }
1143
1144 fDragDropActive = FALSE;
1145
1146 //does this window accept dropped files?
1147 if(!DragDropAccept(win32wnd->getWindowHandle())) {
1148 break;
1149 }
1150
1151 DragDropDragLeave(win32wnd->getWindowHandle());
1152 win32wnd->setDragDropActive(FALSE);
1153 break;
1154 }
1155
1156 case DM_DROP:
1157 {
1158 PDRAGINFO pDragInfo = (PDRAGINFO)mp1;
1159 PDRAGITEM pDragItem;
1160 USHORT sxDrop = SHORT1FROMMP(mp2);
1161 USHORT syDrop = SHORT2FROMMP(mp2);
1162 USHORT usIndicator, usOp;
1163
1164 dprintf(("OS2: DM_DROP %x (%d,%d)", win32wnd->getWindowHandle(), sxDrop, syDrop));
1165
1166 fDragDropActive = FALSE;
1167 rc = (MRFROM2SHORT (DOR_NODROP, 0));
1168
1169 if(fDragDropDisabled) {
1170 rc = (MRFROM2SHORT (DOR_NODROP, 0));
1171 break;
1172 }
1173
1174 //does this window accept dropped files?
1175 if(!DragDropAccept(win32wnd->getWindowHandle())) {
1176 break;
1177 }
1178
1179 ULONG ulBytes, cItems;
1180 char *pszFiles;
1181
1182 pszFiles = PMDragExtractFiles(pDragInfo, &cItems, &ulBytes);
1183 if(pszFiles) {
1184 POINT point = {sxDrop, syDrop};
1185 if(DragDropFiles(win32wnd->getWindowHandle(), point, cItems, pszFiles, ulBytes) == FALSE) {
1186 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
1187 }
1188 else {
1189 rc = (MRFROM2SHORT(DOR_DROP, DO_MOVE));
1190 win32wnd->setDragDropActive(FALSE);
1191 }
1192 free(pszFiles);
1193 }
1194 else {
1195 rc = (MRFROM2SHORT (DOR_NEVERDROP, 0));
1196 }
1197 break;
1198 }
1199
1200 case DM_RENDER:
1201 {
1202 PDRAGTRANSFER pDragTransfer = (PDRAGTRANSFER)mp1;
1203
1204 dprintf(("OS2: DM_RENDER %x", pDragTransfer));
1205
1206 rc = (MRESULT)OSLibRenderFormat(pDragTransfer);
1207 break;
1208 }
1209
1210 case DM_RENDERPREPARE:
1211 {
1212 PDRAGTRANSFER pDragTransfer = (PDRAGTRANSFER)mp1;
1213
1214 dprintf(("OS2: DM_RENDERPREPARE %x", pDragTransfer));
1215 break;
1216 }
1217
1218 case DM_ENDCONVERSATION:
1219 {
1220 dprintf(("OS2: DM_ENDCONVERSATION"));
1221 rc = (MRESULT)OSLibEndConversation();
1222 break;
1223 }
1224
1225 case DM_RENDERFILE:
1226 {
1227 dprintf(("OS2: DM_ENDCONVERSATION"));
1228 rc = FALSE;
1229 break;
1230 }
1231
1232 case WM_DDE_INITIATE:
1233 case WM_DDE_INITIATEACK:
1234 case WM_DDE_REQUEST:
1235 case WM_DDE_ACK:
1236 case WM_DDE_DATA:
1237 case WM_DDE_ADVISE:
1238 case WM_DDE_UNADVISE:
1239 case WM_DDE_POKE:
1240 case WM_DDE_EXECUTE:
1241 case WM_DDE_TERMINATE:
1242 dprintf(("OS2: WM_DDE %x %x", msg, win32wnd->getWindowHandle()));
1243 goto RunDefWndProc;
1244
1245 case WM_INITMENU:
1246 case WM_MENUSELECT:
1247 case WM_MENUEND:
1248 case WM_NEXTMENU:
1249 case WM_SYSCOLORCHANGE:
1250 case WM_SYSVALUECHANGED:
1251 case WM_SETSELECTION:
1252 case WM_PPAINT:
1253 case WM_PSETFOCUS:
1254 case WM_PSYSCOLORCHANGE:
1255 case WM_PSIZE:
1256 case WM_PACTIVATE:
1257 case WM_PCONTROL:
1258 case WM_HELP:
1259 case WM_APPTERMINATENOTIFY:
1260 case WM_PRESPARAMCHANGED:
1261 case WM_DRAWITEM:
1262 case WM_MEASUREITEM:
1263 case WM_CONTROLPOINTER:
1264 case WM_QUERYDLGCODE:
1265 case WM_SUBSTITUTESTRING:
1266 case WM_MATCHMNEMONIC:
1267 case WM_SAVEAPPLICATION:
1268 case WM_SEMANTICEVENT:
1269 default:
1270 dprintf2(("OS2: RunDefWndProc hwnd %x msg %x mp1 %x mp2 %x", hwnd, msg, mp1, mp2));
1271 goto RunDefWndProc;
1272 }
1273 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1274 RestoreOS2TIB();
1275 ODIN_UnsetExceptionHandler(&exceptRegRec);
1276
1277#ifdef DEBUG
1278 dbg_ThreadPopCall();
1279#endif
1280 return (MRESULT)rc;
1281
1282RunDefWndProc:
1283// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
1284 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1285
1286 RestoreOS2TIB();
1287 ODIN_UnsetExceptionHandler(&exceptRegRec);
1288
1289#ifdef DEBUG
1290 dbg_ThreadPopCall();
1291#endif
1292 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
1293} /* End of Win32WindowProc */
1294//******************************************************************************
1295//******************************************************************************
1296MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
1297{
1298 POSTMSG_PACKET *postmsg;
1299 OSLIBPOINT point, ClientPoint;
1300 Win32BaseWindow *win32wnd;
1301 TEB *teb;
1302 MRESULT rc = 0;
1303 MSG winMsg, *pWinMsg;
1304 EXCEPTIONREGISTRATIONRECORD exceptRegRec = {0,0};
1305
1306#ifdef DEBUG
1307 dbg_ThreadPushCall("Win32FrameWindowProc");
1308#endif
1309
1310 ODIN_SetExceptionHandler(&exceptRegRec);
1311 //Restore our FS selector
1312 SetWin32TIB();
1313
1314 // BEGIN NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- BEGIN
1315 teb = GetThreadTEB();
1316 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwnd);
1317
1318 // do some sanity checking here:
1319 // - we need to have a TEB handle
1320 // - unless this is WM_CREATE (the very first message), there has to be
1321 // a USER32 window object for this window handle
1322 // - thread must not be suspended in WaitMessage
1323 if(!teb || (msg != WM_CREATE && win32wnd == NULL) || teb->o.odin.fWaitMessageSuspend) {
1324 if(teb && teb->o.odin.fWaitMessageSuspend)
1325 dprintf(("PMFRAME: fWaitMessageSuspend window %x msg %x -> run default frame proc", hwnd, msg));
1326 else dprintf(("PMFRAME: Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
1327 goto RunDefFrameWndProc;
1328 }
1329//// if(teb->o.odin.fIgnoreMsgs) {
1330//// goto RunDefWndProc;
1331//// }
1332
1333 // check if the message state counter in the TEB is odd
1334 // This means the message has been sent directly from PM to our message
1335 // handler (so it is the first time we know about this PM message).
1336 // If this is the case, we have to translate it here to a Win32
1337 // message first. The other case is that the message is the result of a
1338 // WinDispatchMsg call and therefore has already been translated.
1339 if((teb->o.odin.msgstate & 1) == 0)
1340 {//message that was sent directly to our window proc handler; translate it here
1341 QMSG qmsg;
1342
1343 qmsg.msg = msg;
1344 qmsg.hwnd = hwnd;
1345 qmsg.mp1 = mp1;
1346 qmsg.mp2 = mp2;
1347 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
1348 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
1349 qmsg.reserved = 0;
1350
1351 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
1352 {//message was not translated
1353 memset(&winMsg, 0, sizeof(MSG));
1354 }
1355 pWinMsg = &winMsg;
1356 }
1357 else {
1358 // message has already been translated before (GetMessage/PeekMessage).
1359 // Use the translated information. Flip the translation flag.
1360 pWinMsg = &teb->o.odin.msg;
1361 teb->o.odin.msgstate++;
1362 }
1363 // END NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- END
1364
1365 switch( msg )
1366 {
1367 case WM_CREATE:
1368 {
1369 //WM_CREATE handled during client window creation
1370 dprintf(("PMFRAME: WM_CREATE %x", hwnd));
1371 goto RunDefFrameWndProc;
1372 }
1373
1374//hack alert; PM crashes if child calls DestroyWindow for parent/owner in WM_DESTROY
1375// handler; must postpone it, so do it here
1376 case WIN32APP_POSTPONEDESTROY:
1377 OSLibWinDestroyWindow(hwnd);
1378 break;
1379//hack end
1380
1381#ifdef DEBUG
1382 case WM_CLOSE:
1383 {
1384 dprintf(("PMFRAME: WM_CLOSE %x", hwnd));
1385 goto RunDefFrameWndProc;
1386 }
1387#endif
1388
1389 case WM_PAINT:
1390 {
1391 RECTL rectl;
1392 HRGN hrgn;
1393
1394 hrgn = CreateRectRgn(0, 0, 0, 0);
1395 GetUpdateRgnFrame(win32wnd->getWindowHandle(), hrgn);
1396
1397 HPS hps = WinBeginPaint(hwnd, NULL, &rectl);
1398 dprintf(("PMFRAME: WM_PAINT %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop));
1399
1400 if(win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
1401 rectl.yBottom != rectl.yTop))
1402 {
1403 PRECT pClient = win32wnd->getClientRectPtr();
1404 PRECT pWindow = win32wnd->getWindowRect();
1405
1406 if(!(pClient->left == 0 && pClient->top == 0 &&
1407 win32wnd->getClientHeight() == win32wnd->getWindowHeight() &&
1408 win32wnd->getClientWidth() == win32wnd->getWindowWidth()))
1409 {
1410 RECT rectUpdate;
1411
1412 mapOS2ToWin32Rect(win32wnd->getWindowHeight(), (PRECTLOS2)&rectl, &rectUpdate);
1413 win32wnd->MsgNCPaint(&rectUpdate, hrgn);
1414 }
1415 }
1416 WinEndPaint(hps);
1417
1418 DeleteObject(hrgn);
1419 break;
1420 }
1421
1422 case WM_ERASEBACKGROUND:
1423 {
1424 dprintf(("PMFRAME:WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
1425 rc = (MRESULT)FALSE;
1426 break;
1427 }
1428
1429 //**************************************************************************
1430 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
1431 //**************************************************************************
1432
1433 case WM_BUTTON1DOWN:
1434 case WM_BUTTON1UP:
1435 case WM_BUTTON1DBLCLK:
1436 case WM_BUTTON2DOWN:
1437 case WM_BUTTON2UP:
1438 case WM_BUTTON2DBLCLK:
1439 case WM_BUTTON3DOWN:
1440 case WM_BUTTON3UP:
1441 case WM_BUTTON3DBLCLK:
1442 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
1443 RELEASE_WNDOBJ(win32wnd);
1444 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
1445 }
1446 if(win32wnd)
1447 win32wnd->MsgButton(pWinMsg);
1448
1449 rc = (MRESULT)TRUE;
1450 break;
1451
1452 case WM_BUTTON2MOTIONSTART:
1453 case WM_BUTTON2MOTIONEND:
1454 case WM_BUTTON2CLICK:
1455 case WM_BUTTON1MOTIONSTART:
1456 case WM_BUTTON1MOTIONEND:
1457 case WM_BUTTON1CLICK:
1458 case WM_BUTTON3MOTIONSTART:
1459 case WM_BUTTON3MOTIONEND:
1460 case WM_BUTTON3CLICK:
1461 rc = (MRESULT)TRUE;
1462 break;
1463
1464 case WM_MOUSEMOVE:
1465 {
1466 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
1467 RELEASE_WNDOBJ(win32wnd);
1468 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
1469 }
1470 if(win32wnd)
1471 win32wnd->MsgMouseMove(pWinMsg);
1472 break;
1473 }
1474
1475 case WM_CHAR_SPECIAL_CONSOLE_BREAK:
1476 {
1477 //ignore this message. don't forward it to the default PM frame window handler
1478 //as that one sends it to the client. as a result we end up translating
1479 //it twice
1480 break;
1481 }
1482
1483 case WM_CHAR:
1484 {
1485 dprintf(("PMFRAME:WM_CHAR"));
1486 break;
1487 }
1488
1489 case WM_ADJUSTWINDOWPOS:
1490 {
1491 PSWP pswp = (PSWP)mp1;
1492 SWP swpOld;
1493 WINDOWPOS wp,wpOld;
1494 ULONG ulFlags;
1495 ULONG ret = 0;
1496 HWND hParent = NULLHANDLE, hwndAfter;
1497
1498 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));
1499
1500 ulFlags = pswp->fl;
1501
1502 if(win32wnd->IsParentChanging()) {
1503 rc = 0;
1504 break;
1505 }
1506
1507 //@@PF all commands from minimized window viewer or from Ctrl-Esc
1508 //are 'pure' and should be handled only by DeFrameProc - this is weird
1509 //but without them we will not have results. Pure = plain flag of restore/minimize/maximize
1510 if((pswp->fl == SWP_MINIMIZE) || (pswp->fl & SWP_RESTORE)) {
1511 // note the purity of SWP no other SWP_FLAGS allowed
1512 goto RunDefFrameWndProc;
1513 }
1514
1515 if(pswp->fl & SWP_NOADJUST) {
1516 //ignore weird messages (TODO: why are they sent?)
1517 dprintf(("WARNING: WM_ADJUSTWINDOWPOS with SWP_NOADJUST flag!!"));
1518 break;
1519
1520 }
1521
1522 //PF Pure flags should not cause any subsequent messages to win32 windows
1523 //we should route them to DefFrameWndProc and check highlight.
1524
1525 if ((pswp->fl == SWP_FOCUSACTIVATE) || (pswp->fl == SWP_FOCUSDEACTIVATE))
1526 {
1527 if (fOS2Look)
1528 {
1529 if(pswp->fl == SWP_FOCUSACTIVATE)
1530 {
1531 dprintf2(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1532 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, (MPARAM)1, 0);
1533 }
1534 else
1535 {
1536 dprintf2(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1537 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, 0, 0);
1538 }
1539 }
1540 goto RunDefFrameWndProc;
1541 }
1542
1543 //CB: show dialog in front of owner
1544 if (win32wnd->IsModalDialogOwner())
1545 {
1546 dprintf(("win32wnd->IsModalDialogOwner %x", win32wnd->getWindowHandle()));
1547 pswp->fl |= SWP_ZORDER;
1548 pswp->hwndInsertBehind = win32wnd->getOS2HwndModalDialog();
1549 if (pswp->fl & SWP_ACTIVATE)
1550 {
1551 pswp->fl &= ~SWP_ACTIVATE;
1552 WinSetWindowPos(win32wnd->getOS2HwndModalDialog(),0,0,0,0,0,SWP_ACTIVATE);
1553 }
1554 }
1555
1556 if(!win32wnd->CanReceiveSizeMsgs())
1557 break;
1558
1559 WinQueryWindowPos(hwnd, &swpOld);
1560 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
1561 if (win32wnd->isChild()) {
1562 if(win32wnd->getParent()) {
1563 hParent = win32wnd->getParent()->getOS2WindowHandle();
1564 }
1565 else goto RunDefFrameWndProc;
1566 }
1567 }
1568 hwndAfter = pswp->hwndInsertBehind;
1569 if(win32wnd->getParent()) {
1570 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(), hwnd);
1571 }
1572 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1573
1574 wp.hwnd = win32wnd->getWindowHandle();
1575 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1576 {
1577 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1578 dprintf2(("SWP_ZORDER: %x %x", pswp->hwndInsertBehind, (wndAfter) ? wndAfter->getWindowHandle() : 0));
1579 if(wndAfter) {
1580 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1581 RELEASE_WNDOBJ(wndAfter);
1582 }
1583 else wp.hwndInsertAfter = HWND_TOP_W;
1584 }
1585
1586 wpOld = wp;
1587 win32wnd->MsgPosChanging((LPARAM)&wp);
1588
1589 if(win32wnd->getOldStyle() != win32wnd->getStyle())
1590 {
1591 OSLibSetWindowStyle(win32wnd->getOS2FrameWindowHandle(), win32wnd->getOS2WindowHandle(), win32wnd->getStyle(), win32wnd->getExStyle(), win32wnd->getStyle());
1592 if(fOS2Look) {
1593 DWORD dwOldStyle = win32wnd->getOldStyle();
1594 DWORD dwStyle = win32wnd->getStyle();
1595
1596 win32wnd->setOldStyle(dwStyle);
1597 if((dwOldStyle & WS_MINIMIZE_W) && !(dwStyle & WS_MINIMIZE_W)) {
1598 //SC_RESTORE -> SC_MINIMIZE
1599 dprintf(("%x -> SC_RESTORE -> SC_MINIMIZE", win32wnd->getWindowHandle()));
1600 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), 0, SC_RESTORE, SC_MINIMIZE, hbmFrameMenu[PMMENU_MINBUTTON]);
1601 if(dwStyle & WS_MAXIMIZE_W) {
1602 //SC_MAXIMIZE -> SC_RESTORE
1603 dprintf(("%x -> SC_MAXIMIZE -> SC_RESTORE (1)", win32wnd->getWindowHandle()));
1604 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_MAXIMIZE, SC_RESTORE, hbmFrameMenu[PMMENU_RESTOREBUTTON]);
1605 }
1606 }
1607 else
1608 if((dwOldStyle & WS_MAXIMIZE_W) && !(dwStyle & WS_MAXIMIZE_W)) {
1609 //SC_RESTORE -> SC_MAXIMIZE
1610 dprintf(("%x -> SC_RESTORE -> SC_MAXIMIZE", win32wnd->getWindowHandle()));
1611 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_RESTORE, SC_MAXIMIZE, hbmFrameMenu[PMMENU_MAXBUTTON]);
1612 }
1613 else
1614 if(!(dwOldStyle & WS_MINIMIZE_W) && (dwStyle & WS_MINIMIZE_W)) {
1615 //SC_MINIMIZE -> SC_RESTORE
1616 dprintf(("%x -> SC_MINIMIZE -> SC_RESTORE", win32wnd->getWindowHandle()));
1617 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), 0, SC_MINIMIZE, SC_RESTORE, hbmFrameMenu[PMMENU_RESTOREBUTTON]);
1618 }
1619 else
1620 if(!(dwOldStyle & WS_MAXIMIZE_W) && (dwStyle & WS_MAXIMIZE_W)) {
1621 //SC_MAXIMIZE -> SC_RESTORE
1622 dprintf(("%x -> SC_MAXIMIZE -> SC_RESTORE (2)", win32wnd->getWindowHandle()));
1623 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_MAXIMIZE, SC_RESTORE, hbmFrameMenu[PMMENU_RESTOREBUTTON]);
1624 }
1625 }
1626 }
1627
1628 if ((wp.hwndInsertAfter != wpOld.hwndInsertAfter) ||
1629 (wp.x != wpOld.x) || (wp.y != wpOld.y) || (wp.cx != wpOld.cx) || (wp.cy != wpOld.cy) || (wp.flags != wpOld.flags))
1630 {
1631 ULONG flags = pswp->fl; //make a backup copy; OSLibMapWINDOWPOStoSWP will modify it
1632
1633 dprintf(("PMFRAME:WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
1634 dprintf(("%x (%s) (%d,%d), (%d,%d)", pswp->fl, DbgGetStringSWPFlags(pswp->fl), pswp->x, pswp->y, pswp->cx, pswp->cy));
1635
1636 if(win32wnd->getParent()) {
1637 OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, win32wnd->getParent()->getClientHeight(),
1638 hwnd);
1639 }
1640 else OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1641
1642 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
1643
1644 //OSLibMapWINDOWPOStoSWP can add flags, but we must not let it remove flags!
1645 if(pswp->fl & SWP_SIZE)
1646 flags |= SWP_SIZE;
1647
1648 if(pswp->fl & SWP_MOVE)
1649 flags |= SWP_MOVE;
1650
1651 pswp->fl = flags; //restore flags
1652
1653 pswp->fl |= SWP_NOADJUST;
1654 pswp->hwndInsertBehind = hwndAfter;
1655 pswp->hwnd = hwnd;
1656
1657 ret = 0xf;
1658 }
1659adjustend:
1660 //The next part needs to be done for top-level windows only
1661 if(!((win32wnd->getStyle() & (WS_POPUP_W|WS_CHILD_W)) == WS_CHILD_W))
1662 {
1663 //Setting these flags is necessary to avoid activation/focus problems
1664 if(ulFlags & SWP_DEACTIVATE) {
1665 ret |= AWP_DEACTIVATE;
1666 }
1667 if(ulFlags & SWP_ACTIVATE)
1668 {
1669 if(ulFlags & SWP_ZORDER) {
1670 dprintf(("Set FF_NOACTIVATESWP"));
1671 ULONG ulFrameFlags = WinQueryWindowUShort(hwnd, QWS_FLAGS);
1672 WinSetWindowUShort(hwnd, QWS_FLAGS, ulFrameFlags | FF_NOACTIVATESWP);
1673 }
1674
1675 if(!(ulFlags & SWP_SHOW))
1676 {
1677 ret |= AWP_ACTIVATE;
1678 }
1679 else
1680 {
1681 FrameSetFocus(hwnd);
1682 }
1683 }
1684 }
1685 else {
1686 if(ulFlags & (SWP_ACTIVATE|SWP_FOCUSACTIVATE))
1687 {
1688 win32wnd->MsgChildActivate(TRUE);
1689 if(fOS2Look) {
1690 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1691 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, (MPARAM)1, 0);
1692 }
1693 }
1694 else
1695 if(ulFlags & (SWP_DEACTIVATE|SWP_FOCUSDEACTIVATE))
1696 {
1697 win32wnd->MsgChildActivate(FALSE);
1698 if(fOS2Look) {
1699 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1700 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, 0, 0);
1701 }
1702 }
1703 }
1704#ifdef DEBUG
1705 dprintf(("WM_ADJUSTWINDOWPOS ret %x flags %x", ret, WinQueryWindowUShort(hwnd, QWS_FLAGS)));
1706 if(ret == 0x0f) {
1707 dprintf(("PMFRAME:WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
1708 dprintf(("%x (%s) (%d,%d), (%d,%d)", pswp->fl, DbgGetStringSWPFlags(pswp->fl), pswp->x, pswp->y, pswp->cx, pswp->cy));
1709 }
1710#endif
1711 rc = (MRESULT)ret;
1712 break;
1713 }
1714
1715 case WM_WINDOWPOSCHANGED:
1716 {
1717 PSWP pswp = (PSWP)mp1,pswpOld = pswp+1;
1718 SWP swpOld = *(pswp + 1);
1719 WINDOWPOS wp;
1720 ULONG flAfp = (ULONG)mp2;
1721 HWND hParent = NULLHANDLE;
1722 RECTL rect;
1723
1724 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)));
1725 if(win32wnd->IsParentChanging()) {
1726 goto PosChangedEnd;
1727 }
1728
1729 // PF: MDI window is not a common OS/2 frame window so we just skipped all
1730 // PM default processing for it that basicly moved this window to 0,0 point
1731 // and changed frame controls. Now do our own processing.
1732
1733 if ((pswp->fl & SWP_MAXIMIZE) && (win32wnd->getExStyle() & WS_EX_MDICHILD_W))
1734 {
1735 SendMessageA(win32wnd->getWindowHandle(), WM_SYSCOMMAND_W, SC_MAXIMIZE_W, 0);
1736 goto PosChangedEnd;
1737 }
1738
1739 //SvL: When a window is made visible, then we don't receive a
1740 // WM_VRNENABLED message (for some weird reason)
1741 if(pswp->fl & SWP_SHOW) {
1742 win32wnd->callVisibleRgnNotifyProc(TRUE);
1743 }
1744 else
1745 if(pswp->fl & SWP_HIDE) {
1746 win32wnd->callVisibleRgnNotifyProc(FALSE);
1747 }
1748
1749 if(pswp->fl & (SWP_MOVE | SWP_SIZE))
1750 {
1751 if(win32wnd->isChild())
1752 {
1753 if(win32wnd->getParent()) {
1754 hParent = win32wnd->getParent()->getOS2WindowHandle();
1755 }
1756 else goto PosChangedEnd; //parent has just been destroyed
1757 }
1758 }
1759
1760
1761 if(win32wnd->getParent()) {
1762 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
1763 hwnd);
1764 }
1765 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1766
1767 wp.hwnd = win32wnd->getWindowHandle();
1768 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1769 {
1770 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1771 dprintf2(("SWP_ZORDER: %x %x", pswp->hwndInsertBehind, (wndAfter) ? wndAfter->getWindowHandle() : 0));
1772 if(wndAfter) {
1773 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1774 RELEASE_WNDOBJ(wndAfter);
1775 }
1776 else wp.hwndInsertAfter = HWND_TOP_W;
1777 }
1778
1779 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0)
1780 {
1781 if(pswp->fl & SWP_RESTORE && win32wnd->getStyle() & WS_MINIMIZE_W) {
1782 dprintf(("Restoring minimized window %x", win32wnd->getWindowHandle()));
1783 win32wnd->ShowWindow(SW_RESTORE_W);
1784 }
1785 if(pswp->fl & SWP_SHOW) {
1786 WinShowWindow(win32wnd->getOS2WindowHandle(), 1);
1787 }
1788 else
1789 if(pswp->fl & SWP_HIDE) {
1790 WinShowWindow(win32wnd->getOS2WindowHandle(), 0);
1791 }
1792 if(pswp->fl & (SWP_SHOW|SWP_HIDE))
1793 {//TODO: necessary for more options? (activate?)
1794 if(win32wnd->CanReceiveSizeMsgs())
1795 win32wnd->MsgPosChanged((LPARAM)&wp);
1796 }
1797
1798 //MUST call the old frame window proc!
1799 goto RunDefFrameWndProc;
1800 }
1801
1802 if(pswp->fl & SWP_SHOW) {
1803 WinShowWindow(win32wnd->getOS2WindowHandle(), 1);
1804 }
1805 else
1806 if(pswp->fl & SWP_HIDE) {
1807 WinShowWindow(win32wnd->getOS2WindowHandle(), 0);
1808 }
1809
1810 if(flAfp & AWP_ACTIVATE)
1811 {
1812 FrameSetFocus(hwnd);
1813 }
1814
1815#ifndef USE_CALCVALIDRECT
1816 if((pswp->fl & (SWP_MOVE | SWP_SIZE)))
1817 {
1818 //CB: todo: use result for WM_CALCVALIDRECTS
1819 //Get old client rectangle (for invalidation of frame window parts later on)
1820 //Use new window height to calculate the client area
1821 mapWin32ToOS2Rect(pswp->cy, win32wnd->getClientRectPtr(), (PRECTLOS2)&rect);
1822
1823 //Note: Also updates the new window rectangle
1824 win32wnd->MsgFormatFrame(&wp);
1825
1826 if(win32wnd->isOwnDC()) {
1827 setPageXForm(win32wnd, (pDCData)GpiQueryDCData(win32wnd->getOwnDC()));
1828 }
1829
1830 if(win32wnd->CanReceiveSizeMsgs())
1831 win32wnd->MsgPosChanged((LPARAM)&wp);
1832
1833 if((pswp->fl & SWP_SIZE) && ((pswp->cx != pswpOld->cx) || (pswp->cy != pswpOld->cy)))
1834 {
1835 //redraw the frame (to prevent unnecessary client updates)
1836 BOOL redrawAll = FALSE;
1837
1838 dprintf2(("WM_WINDOWPOSCHANGED: redraw frame"));
1839 if (win32wnd->getWindowClass())
1840 {
1841 DWORD dwStyle = win32wnd->getWindowClass()->getClassLongA(GCL_STYLE_W);
1842
1843 if ((dwStyle & CS_HREDRAW_W) && (pswp->cx != pswpOld->cx))
1844 redrawAll = TRUE;
1845 else
1846 if ((dwStyle & CS_VREDRAW_W) && (pswp->cy != pswpOld->cy))
1847 redrawAll = TRUE;
1848 }
1849 else redrawAll = TRUE;
1850
1851 if(win32wnd->IsMixMaxStateChanging()) {
1852 dprintf(("WM_CALCVALIDRECT: window changed min/max/restore state, invalidate entire window"));
1853 redrawAll = TRUE;
1854 }
1855
1856 if (redrawAll)
1857 {
1858 //CB: redraw all children for now
1859 // -> problems with update region if we don't do it
1860 // todo: rewrite whole handling
1861 dprintf(("PMFRAME: WM_WINDOWPOSCHANGED invalidate all"));
1862 WinInvalidateRect(hwnd,NULL,TRUE);
1863 }
1864 else
1865 {
1866 HPS hps = WinGetPS(hwnd);
1867 RECTL frame,client,arcl[4];
1868
1869 WinQueryWindowRect(hwnd,&frame);
1870
1871 //top
1872 arcl[0].xLeft = 0;
1873 arcl[0].xRight = frame.xRight;
1874 arcl[0].yBottom = rect.yTop;
1875 arcl[0].yTop = frame.yTop;
1876 //right
1877 arcl[1].xLeft = rect.xRight;
1878 arcl[1].xRight = frame.xRight;
1879 arcl[1].yBottom = 0;
1880 arcl[1].yTop = frame.yTop;
1881 //left
1882 arcl[2].xLeft = 0;
1883 arcl[2].xRight = rect.xLeft;
1884 arcl[2].yBottom = 0;
1885 arcl[2].yTop = frame.yTop;
1886 //bottom
1887 arcl[3].xLeft = 0;
1888 arcl[3].xRight = frame.xRight;
1889 arcl[3].yBottom = 0;
1890 arcl[3].yTop = rect.yBottom;
1891
1892 HRGN hrgn = GpiCreateRegion(hps,4,(PRECTL)&arcl);
1893
1894 WinInvalidateRegion(hwnd,hrgn,FALSE);
1895 GpiDestroyRegion(hps,hrgn);
1896 WinReleasePS(hps);
1897 }
1898 }
1899 }
1900 else
1901 {
1902#endif //USE_CALCVALIDRECT
1903 if(win32wnd->CanReceiveSizeMsgs())
1904 win32wnd->MsgPosChanged((LPARAM)&wp);
1905#ifndef USE_CALCVALIDRECT
1906 }
1907#endif
1908 //PF This is the final step of PM restoration - should end up
1909 //in default handler.
1910 if (win32wnd->getOldStyle() & WS_MINIMIZE_W && pswp->fl & SWP_RESTORE)
1911 goto RunDefFrameWndProc;
1912
1913 //PF This is the final step of PM minimization - shoukd end up
1914 //in default handler
1915 if (win32wnd->getStyle() & WS_MINIMIZE_W && pswp->fl & SWP_MINIMIZE)
1916 goto RunDefFrameWndProc;
1917
1918PosChangedEnd:
1919 rc = (MRESULT)FALSE;
1920 break;
1921 }
1922
1923 case WM_CALCVALIDRECTS:
1924#ifdef USE_CALCVALIDRECT
1925 {
1926 PRECTL oldRect = (PRECTL)mp1, newRect = oldRect+1;
1927 PSWP pswp = (PSWP)mp2;
1928 SWP swpOld;
1929 WINDOWPOS wp;
1930 RECTL newClientRect, oldClientRect;
1931 ULONG nccalcret;
1932// UINT res = CVR_ALIGNLEFT | CVR_ALIGNTOP;
1933 UINT res = 0;
1934
1935 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
1936
1937 //Get old position info
1938 WinQueryWindowPos(hwnd, &swpOld);
1939
1940 if(win32wnd->getParent()) {
1941 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
1942 win32wnd->getParent()->getClientRectPtr()->left,
1943 win32wnd->getParent()->getClientRectPtr()->top,
1944 hwnd);
1945 }
1946 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), 0, 0, hwnd);
1947
1948 wp.hwnd = win32wnd->getWindowHandle();
1949 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1950 {
1951 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1952 if(wndAfter) {
1953 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1954 RELEASE_WNDOBJ(wndAfter);
1955 }
1956 else wp.hwndInsertAfter = HWND_TOP_W;
1957 }
1958
1959 //Get old client rectangle
1960 mapWin32ToOS2Rect(oldRect->yTop - oldRect->yBottom, win32wnd->getClientRectPtr(), (PRECTLOS2)&oldClientRect);
1961
1962 //Note: Also updates the new window rectangle
1963 nccalcret = win32wnd->MsgFormatFrame(&wp);
1964
1965 //Get new client rectangle
1966 mapWin32ToOS2Rect(pswp->cy, win32wnd->getClientRectPtr(), (PRECTLOS2)&newClientRect);
1967
1968 if(nccalcret == 0) {
1969 res = CVR_ALIGNTOP | CVR_ALIGNLEFT;
1970 }
1971 else {
1972 if(nccalcret & WVR_ALIGNTOP_W) {
1973 res |= CVR_ALIGNTOP;
1974 }
1975 else
1976 if(nccalcret & WVR_ALIGNBOTTOM_W) {
1977 res |= CVR_ALIGNBOTTOM;
1978 }
1979
1980 if(nccalcret & WVR_ALIGNLEFT_W) {
1981 res |= CVR_ALIGNLEFT;
1982 }
1983 else
1984 if(nccalcret & WVR_ALIGNRIGHT_W) {
1985 res |= CVR_ALIGNRIGHT;
1986 }
1987
1988 if(nccalcret & WVR_REDRAW_W) {//WVR_REDRAW_W = (WVR_HREDRAW | WVR_VREDRAW)
1989 res |= CVR_REDRAW;
1990 }
1991 else
1992 if(nccalcret & WVR_VALIDRECTS_W) {
1993 //TODO:
1994 //res = 0;
1995 }
1996 }
1997 if(win32wnd->IsMixMaxStateChanging()) {
1998 dprintf(("WM_CALCVALIDRECT: window changed min/max/restore state, invalidate entire window"));
1999 res |= CVR_REDRAW;
2000 }
2001 if(res == (CVR_ALIGNTOP|CVR_ALIGNLEFT)) {
2002 oldRect->xRight -= oldClientRect.xLeft;
2003 oldRect->yBottom += oldClientRect.yBottom;
2004 newRect->xRight -= newClientRect.xLeft;
2005 newRect->yBottom += newClientRect.yBottom;
2006 }
2007 rc = res;
2008 break;
2009 }
2010#else
2011 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
2012 rc = (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
2013 break;
2014#endif
2015
2016 case WM_CALCFRAMERECT:
2017 dprintf(("PMFRAME:WM_CALCFRAMERECT %x", win32wnd->getWindowHandle()));
2018 rc = (MRESULT)TRUE;
2019 break;
2020
2021 case WM_QUERYCTLTYPE:
2022 // This is a frame window
2023 dprintf(("PMFRAME:WM_QUERYCTLTYPE %x", win32wnd->getWindowHandle()));
2024 rc = (MRESULT)CCT_FRAME;
2025 break;
2026
2027#ifdef DEBUG
2028 case WM_QUERYFOCUSCHAIN:
2029 dprintf2(("PMFRAME:WM_QUERYFOCUSCHAIN %x fsCmd %x (%s) parent %x", win32wnd->getWindowHandle(), SHORT1FROMMP(mp1), DbgPrintQFCFlags(SHORT1FROMMP(mp1)), (mp2) ? OS2ToWin32Handle((DWORD)mp2) : 0));
2030
2031 RestoreOS2TIB();
2032 rc = pfnFrameWndProc(hwnd, msg, mp1, mp2);
2033 SetWin32TIB();
2034 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));
2035 break;
2036// goto RunDefFrameWndProc;
2037#endif
2038
2039 case WM_FOCUSCHANGE:
2040 {
2041 HWND hwndFocus = (HWND)mp1;
2042 HWND hwndLoseFocus, hwndGainFocus;
2043 USHORT usSetFocus = SHORT1FROMMP(mp2);
2044 USHORT fsFocusChange = SHORT2FROMMP(mp2);
2045
2046 //Save window that gains focus so we can determine which
2047 //process we lose activation to
2048 hwndFocusChange = (HWND)mp1;
2049
2050 dprintf(("PMFRAME:WM_FOCUSCHANGE %x %x (%x) %x %x", win32wnd->getWindowHandle(), OS2ToWin32Handle(hwndFocus), hwndFocus, usSetFocus, fsFocusChange));
2051 goto RunDefFrameWndProc;
2052 }
2053
2054#ifdef DEBUG
2055 case WM_SETFOCUS:
2056 {
2057 dprintf(("PMFRAME: WM_SETFOCUS %x %x %d -> %x", win32wnd->getWindowHandle(), hwnd, mp2, mp1));
2058 goto RunDefFrameWndProc;
2059 }
2060#endif
2061
2062 case WM_ACTIVATE:
2063 {
2064 HWND hwndTitle;
2065 USHORT flags = WinQueryWindowUShort(hwnd,QWS_FLAGS);
2066
2067 dprintf(("PMFRAME: WM_ACTIVATE %x %x %x", win32wnd->getWindowHandle(), mp1, OS2ToWin32Handle((DWORD)mp2)));
2068 if (win32wnd->IsWindowCreated())
2069 {
2070 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
2071 if(fOS2Look) {
2072 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
2073 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, mp1, 0);
2074 }
2075 if(SHORT1FROMMP(mp1) == 0) {
2076 //deactivate
2077 WinSendDlgItemMsg(hwnd, FID_CLIENT, WM_ACTIVATE, mp1, mp2);
2078 }
2079 PID pidThis, pidPartner, pidTemp;
2080 TID tidPartner;
2081 HENUM henum;
2082 HWND hwndEnum;
2083
2084 WinQueryWindowProcess(hwnd, &pidThis, NULL);
2085 WinQueryWindowProcess(hwndFocusChange, &pidPartner, &tidPartner);
2086
2087 if(pidThis != pidPartner) {
2088 //Gain or lose activation to window in other process
2089 //must send WM_ACTIVATEAPP to top-level windows
2090
2091 //Iterate over all child windows of the desktop
2092 henum = WinBeginEnumWindows(HWND_DESKTOP);
2093
2094 while(hwndEnum = WinGetNextWindow(henum))
2095 {
2096 WinQueryWindowProcess(hwndEnum, &pidTemp, NULL);
2097 if(pidTemp == pidThis)
2098 {
2099 SendMessageA(OS2ToWin32Handle(hwndEnum), WM_ACTIVATEAPP_W, (WPARAM)SHORT1FROMMP(mp1), (LPARAM)tidPartner);
2100 }
2101 }
2102 WinEndEnumWindows(henum);
2103 }
2104 if(SHORT1FROMMP(mp1)) {
2105 //activate
2106 WinSendDlgItemMsg(hwnd, FID_CLIENT, WM_ACTIVATE, mp1, mp2);
2107 }
2108
2109 //CB: show owner behind the dialog
2110 if (win32wnd->IsModalDialog())
2111 {
2112 if(win32wnd->getOwner()) {
2113 Win32BaseWindow *topOwner = Win32BaseWindow::GetWindowFromHandle(win32wnd->getOwner()->GetTopParent());
2114
2115 if (topOwner) {
2116 WinSetWindowPos(topOwner->getOS2FrameWindowHandle(),hwnd,0,0,0,0,SWP_ZORDER);
2117 RELEASE_WNDOBJ(topOwner);
2118 }
2119 }
2120 }
2121 }
2122 else
2123 {
2124 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
2125 }
2126 rc = 0;
2127 break;
2128 }
2129
2130 case WM_ENABLE:
2131 dprintf(("PMFRAME: WM_ENABLE %x", hwnd));
2132 win32wnd->MsgEnable(SHORT1FROMMP(mp1));
2133 break;
2134
2135 case WM_SHOW:
2136 dprintf(("PMFRAME: WM_SHOW %x %d", hwnd, mp1));
2137 //show client window
2138 WinShowWindow(win32wnd->getOS2WindowHandle(), (BOOL)mp1);
2139 break;
2140
2141 case WM_QUERYTRACKINFO:
2142 {
2143 PTRACKINFO trackInfo = (PTRACKINFO)mp2;
2144
2145 dprintf(("PMFRAME:WM_QUERYTRACKINFO %x", win32wnd->getWindowHandle()));
2146 trackInfo->cxBorder = 4;
2147 trackInfo->cyBorder = 4;
2148 win32wnd->AdjustTrackInfo((PPOINT)&trackInfo->ptlMinTrackSize,(PPOINT)&trackInfo->ptlMaxTrackSize);
2149 rc = (MRESULT)TRUE;
2150 break;
2151 }
2152
2153 case WM_QUERYBORDERSIZE:
2154 {
2155 PWPOINT size = (PWPOINT)mp1;
2156
2157 dprintf(("PMFRAME:WM_QUERYBORDERSIZE %x", win32wnd->getWindowHandle()));
2158
2159 size->x = 0;
2160 size->y = 0;
2161 rc = (MRESULT)TRUE;
2162 break;
2163 }
2164
2165#ifdef DEBUG
2166 case WM_QUERYFRAMEINFO:
2167 dprintf(("PMFRAME:WM_QUERYFRAMEINFO %x", win32wnd->getWindowHandle()));
2168 goto RunDefFrameWndProc;
2169#endif
2170
2171 case WM_FORMATFRAME:
2172 dprintf(("PMFRAME:WM_FORMATFRAME %x", win32wnd->getWindowHandle()));
2173 break;
2174
2175 case WM_ADJUSTFRAMEPOS:
2176 {
2177 PSWP pswp = (PSWP)mp1;
2178
2179 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));
2180 //hack alert: the PM frame control changes the z-order of a child window
2181 // if it receives focus after a window has been destroyed
2182 // We can't let this happen as this messes up assumptions
2183 // elsewhere (e.g. GetNextDlgGroupItem)
2184 // By returning 0 here, we prevent the default frame handler
2185 // from messing things up. (one example is a group of radio buttons)
2186 //NOTE: We really need to get rid of frame & client windows for each
2187 // win32 window
2188 if(pswp->fl == SWP_FOCUSACTIVATE && win32wnd->isChild()) {
2189 rc = 0;
2190 break;
2191 }
2192 //hack alert: as we return zero as border size (check handler) we need
2193 //to do adjustments here as well or PM will calculate it for us and
2194 //result will be illegal. Btw we do not honour PM border size settings
2195 //and never will. I was unable to figure out why only X coordinate
2196 //is being broken but not Y as well.
2197
2198 if ((pswp->fl & SWP_MAXIMIZE) == SWP_MAXIMIZE)
2199 {
2200 RECT rect;
2201 rect.left = rect.top = rect.right = rect.bottom = 0;
2202 win32wnd->AdjustMaximizedRect(&rect);
2203
2204 pswp->x += rect.left;
2205 }
2206 goto RunDefFrameWndProc;
2207 }
2208
2209#ifdef DEBUG
2210 case WM_OWNERPOSCHANGE:
2211 {
2212 PSWP pswp = (PSWP)mp1;
2213
2214 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));
2215 RestoreOS2TIB();
2216 rc = pfnFrameWndProc(hwnd, msg, mp1, mp2);
2217 SetWin32TIB();
2218 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));
2219 break;
2220 }
2221#endif
2222
2223 case WM_MINMAXFRAME:
2224 {
2225 PSWP swp = (PSWP)mp1;
2226
2227 if (!win32wnd->IsWindowCreated()) goto RunDefWndProc;
2228
2229 dprintf(("PMFRAME:WM_MINMAXFRAME %x",hwnd));
2230 if ((swp->fl & SWP_MAXIMIZE) == SWP_MAXIMIZE)
2231 {
2232 // MDI frame windows are not common PM windows so we need to
2233 // drop-out WHOLE chain of WM_X commands with SWP_MAXIMIZE flag
2234 // finally last WM_WINDOWPOSCHANGED will take care of maximization
2235
2236 if (win32wnd->getExStyle() & WS_EX_MDICHILD_W) {
2237 rc = 0;
2238 break;
2239 }
2240
2241 RECT rect;
2242 rect.left = rect.top = rect.right = rect.bottom = 0;
2243 win32wnd->AdjustMaximizedRect(&rect);
2244
2245 swp->x += rect.left;
2246 swp->cx += rect.right-rect.left;
2247 swp->y -= rect.bottom;
2248 swp->cy += rect.bottom-rect.top;
2249
2250 win32wnd->ShowWindow(SW_RESTORE_W);
2251 }
2252 else
2253 if ((swp->fl & SWP_MINIMIZE) == SWP_MINIMIZE)
2254 {
2255 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MAXIMIZE_W) | WS_MINIMIZE_W);
2256 }
2257 else
2258 if ((swp->fl & SWP_RESTORE) == SWP_RESTORE)
2259 {
2260 win32wnd->setStyle(win32wnd->getStyle() & ~(WS_MINIMIZE_W | WS_MAXIMIZE_W));
2261 }
2262 goto RunDefWndProc;
2263 }
2264
2265#ifdef DEBUG
2266 case WM_UPDATEFRAME:
2267 dprintf(("PMFRAME:WM_UPDATEFRAME %x", win32wnd->getWindowHandle()));
2268 goto RunDefFrameWndProc;
2269#endif
2270
2271 case WM_TRACKFRAME:
2272 dprintf(("PMFRAME: WM_TRACKFRAME %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
2273 if(fOS2Look) {//sent by titlebar control
2274 Frame_SysCommandSizeMove(win32wnd, SC_MOVE_W+HTCAPTION_W);
2275 }
2276 rc = 0;
2277 break;
2278
2279 case WM_SYSCOMMAND:
2280 dprintf(("PMFRAME: WM_SYSCOMMAND %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
2281 if (fOS2Look == OS2_APPEARANCE_SYSMENU && mp1 == (MPARAM)OSSC_SYSMENU)
2282 goto RunDefFrameWndProc;
2283
2284 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
2285 RELEASE_WNDOBJ(win32wnd);
2286 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
2287 }
2288 if(win32wnd)
2289 win32wnd->DispatchMsgA(pWinMsg);
2290 break;
2291
2292 case WM_IMEREQUEST:
2293 case WM_IMECONTROL:
2294 case WM_IMENOTIFY:
2295 if( pWinMsg->message )
2296 {
2297 dprintf(("Frame window received IME message"));
2298 win32wnd->DispatchMsgA( pWinMsg );
2299
2300 if(( pWinMsg->message = WM_IME_NOTIFY_W ) &&
2301 ( pWinMsg->wParam == IMN_SETOPENSTATUS_W ))
2302 {
2303 MSG m;
2304
2305 m.message = WM_IME_NOTIFY_W;
2306 m.wParam = IMN_SETCONVERSIONMODE_W;
2307 m.lParam = 0;
2308
2309 win32wnd->DispatchMsgA( &m );
2310 }
2311 }
2312 else
2313 goto RunDefWndProc;
2314 break;
2315
2316#ifdef DEBUG
2317 case WM_DDE_INITIATE:
2318 case WM_DDE_INITIATEACK:
2319 case WM_DDE_REQUEST:
2320 case WM_DDE_ACK:
2321 case WM_DDE_DATA:
2322 case WM_DDE_ADVISE:
2323 case WM_DDE_UNADVISE:
2324 case WM_DDE_POKE:
2325 case WM_DDE_EXECUTE:
2326 case WM_DDE_TERMINATE:
2327 dprintf(("PMFRAME: WM_DDE %x %x", msg, win32wnd->getWindowHandle()));
2328 break;
2329#endif
2330
2331 default:
2332 goto RunDefFrameWndProc;
2333 }
2334 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
2335 RestoreOS2TIB();
2336 ODIN_UnsetExceptionHandler(&exceptRegRec);
2337
2338#ifdef DEBUG
2339 dbg_ThreadPopCall();
2340#endif
2341 return (MRESULT)rc;
2342
2343RunDefFrameWndProc:
2344 dprintf2(("RunDefFrameWndProc"));
2345 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
2346 RestoreOS2TIB();
2347 ODIN_UnsetExceptionHandler(&exceptRegRec);
2348
2349#ifdef DEBUG
2350 dbg_ThreadPopCall();
2351#endif
2352 return pfnFrameWndProc(hwnd, msg, mp1, mp2);
2353
2354RunDefWndProc:
2355 dprintf2(("RunDefWndProc"));
2356 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
2357 RestoreOS2TIB();
2358 ODIN_UnsetExceptionHandler(&exceptRegRec);
2359
2360 //calling WinDefWindowProc here breaks Opera hotlist window (WM_ADJUSTWINDOWPOS)
2361// return pfnFrameWndProc(hwnd, msg, mp1, mp2);
2362
2363#ifdef DEBUG
2364 dbg_ThreadPopCall();
2365#endif
2366 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
2367}
2368//******************************************************************************
2369//******************************************************************************
2370MRESULT EXPENTRY Win32FakeWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
2371{
2372 PFNWP pfnOldWindowProc;
2373 Win32BaseWindow *win32wnd, *win32wndchild;
2374 TEB *teb;
2375 MRESULT rc = 0;
2376 EXCEPTIONREGISTRATIONRECORD exceptRegRec = {0,0};
2377
2378 //Restore our FS selector
2379 SetWin32TIB();
2380
2381 win32wnd = Win32FakeWindow::GetWindowFromOS2Handle(hwnd);
2382 if(win32wnd == NULL) {
2383 DebugInt3();
2384 goto RunDefWndProc;
2385 }
2386
2387 pfnOldWindowProc = (PFNWP)win32wnd->getOldPMWindowProc();
2388 if(pfnOldWindowProc == NULL) {
2389 DebugInt3();
2390 goto RunDefWndProc;
2391 }
2392
2393 RestoreOS2TIB();
2394 rc = pfnOldWindowProc(hwnd, msg, mp1, mp2);
2395
2396 ODIN_SetExceptionHandler(&exceptRegRec);
2397 SetWin32TIB();
2398 switch(msg) {
2399 case WM_WINDOWPOSCHANGED:
2400 {
2401 PSWP pswp = (PSWP)mp1,pswpOld = pswp+1;
2402 SWP swpOld = *(pswp + 1);
2403 WINDOWPOS wp;
2404
2405 if(win32wnd->getParent()) {
2406 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
2407 hwnd);
2408 }
2409 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
2410
2411 win32wnd->SetWindowPos(wp.hwndInsertAfter, wp.x, wp.y, wp.cx, wp.cy, wp.flags);
2412 break;
2413 }
2414
2415 }
2416 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
2417 RestoreOS2TIB();
2418 ODIN_UnsetExceptionHandler(&exceptRegRec);
2419 return rc;
2420
2421RunDefWndProc:
2422 RestoreOS2TIB();
2423 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
2424}
2425//******************************************************************************
2426// PMWinSubclassFakeWindow
2427//
2428// Subclass a fake window (converted PM window)
2429//
2430// Parameters
2431//
2432// HWND hwndOS2 - PM handle of fake window
2433//
2434// Returns
2435// NULL - Failure
2436// else - Old PM window procedure
2437//
2438//******************************************************************************
2439PVOID PMWinSubclassFakeWindow(HWND hwndOS2)
2440{
2441 return WinSubclassWindow(hwndOS2, Win32FakeWindowProc);
2442}
2443//******************************************************************************
2444//******************************************************************************
2445void FrameSetFocus(HWND hwnd)
2446{
2447 HWND hwndFocusSave = WinQueryWindowULong(hwnd, QWL_HWNDFOCUSSAVE);
2448 if(!WinIsWindow(hab, hwndFocusSave)) {
2449 hwndFocusSave = WinWindowFromID(hwnd, FID_CLIENT);
2450 WinSetWindowULong(hwnd, QWL_HWNDFOCUSSAVE, hwndFocusSave);
2451 }
2452 dprintf(("FrameSetFocus: hwndFocusSave %x %x", OS2ToWin32Handle(hwndFocusSave), hwndFocusSave));
2453 dprintf(("FrameSetFocus: cur focus=%x (%x) cur active=%x (%x)\n",
2454 WinQueryFocus(HWND_DESKTOP), OS2ToWin32Handle(WinQueryFocus(HWND_DESKTOP)),
2455 WinQueryActiveWindow(HWND_DESKTOP), OS2ToWin32Handle(WinQueryActiveWindow(HWND_DESKTOP))));
2456 WinSetFocus(HWND_DESKTOP, hwndFocusSave);
2457
2458 ULONG ulFrameFlags = WinQueryWindowUShort(hwnd, QWS_FLAGS);
2459 ulFrameFlags &= ~FF_NOACTIVATESWP;
2460 WinSetWindowUShort(hwnd, QWS_FLAGS, ulFrameFlags);
2461}
2462//******************************************************************************
2463//******************************************************************************
2464void FrameReplaceMenuItem(HWND hwndMenu, ULONG nIndex, ULONG idOld, ULONG idNew,
2465 HBITMAP hbmNew)
2466{
2467 MENUITEM mi;
2468
2469 if (!hwndMenu)
2470 return;
2471
2472 WinEnableWindowUpdate(hwndMenu, FALSE);
2473
2474 if (WinSendMsg(hwndMenu, MM_QUERYITEM, MPFROM2SHORT(idOld, TRUE), MPFROMP(&mi)))
2475 {
2476 WinSendMsg(hwndMenu, MM_REMOVEITEM, (MPARAM)idOld, 0);
2477 mi.afStyle = MIS_BITMAP | MIS_SYSCOMMAND;
2478 mi.afAttribute = 0;
2479 mi.hwndSubMenu = 0;
2480 mi.id = idNew;
2481 mi.hItem = (ULONG)hbmNew;
2482 WinSendMsg(hwndMenu, MM_INSERTITEM, (MPARAM)&mi, 0);
2483 }
2484 else
2485 dprintf(("WARNING: FrameReplaceMenuItem control %x not found",idOld));
2486
2487 WinEnableWindowUpdate(hwndMenu, TRUE);
2488
2489 WinInvalidateRect(hwndMenu, NULL, TRUE);
2490}
2491//******************************************************************************
2492//******************************************************************************
2493void RecalcVisibleRegion(Win32BaseWindow *win32wnd)
2494{
2495 //Workaround for PM/GPI bug when moving/sizing a window with open DCs
2496 //
2497 //Windows applictions often get a DC and keep it open for the duration
2498 //of the application. When the DC's window is moved (full window dragging on)
2499 //PM/GPI doesn't seem to update the DC properly/in time.
2500 //This can result is visible distortions on the screen.
2501
2502 //We need to reset our DC (transformation & y-inversion) (#945)
2503 //Debugging showed that querying the visible region of a DC will cure
2504 //this problem (GPI probably recalculates the visible region). (#334)
2505
2506 int nrdcs = 0;
2507 HDC hdcWindow[MAX_OPENDCS];
2508
2509 if(win32wnd->queryOpenDCs(hdcWindow, MAX_OPENDCS, &nrdcs))
2510 {
2511 for(int i=0;i<nrdcs;i++)
2512 {
2513 dprintf(("Recalc visible region of DC %x for window %x", hdcWindow[i], win32wnd->getWindowHandle()));
2514
2515 pDCData pHps = (pDCData)GpiQueryDCData (hdcWindow[i]);
2516
2517 if(pHps) setPageXForm (win32wnd, pHps);
2518 else DebugInt3();
2519 }
2520 }
2521 //Workaround END
2522}
2523//******************************************************************************
2524//******************************************************************************
2525static char *PMDragExtractFiles(PDRAGINFO pDragInfo, ULONG *pcItems, ULONG *pulBytes)
2526{
2527 PDRAGITEM pDragItem;
2528 int i, cItems;
2529 BOOL ret;
2530 char szFileName[CCHMAXPATH];
2531 char szContainerName[CCHMAXPATH];
2532 ULONG ulBytes;
2533 char *pszCurFile = NULL;
2534
2535 /* Get access to the DRAGINFO data structure */
2536 if(!DrgAccessDraginfo(pDragInfo)) {
2537 return NULL;
2538 }
2539
2540 cItems = DrgQueryDragitemCount(pDragInfo);
2541
2542 //compute memory required to hold all filenames
2543 int bufsize = 0;
2544 for (i = 0; i < cItems; i++) {
2545 pDragItem = DrgQueryDragitemPtr(pDragInfo, i);
2546
2547 bufsize += DrgQueryStrNameLen(pDragItem->hstrContainerName) + DrgQueryStrNameLen(pDragItem->hstrSourceName);
2548 bufsize++; //0 terminator
2549 bufsize++; //+ potential missing backslash
2550 }
2551 bufsize++; //extra 0 terminator
2552 char *pszFiles = (char *)malloc(bufsize);
2553 if(pszFiles == NULL) {
2554 dprintf(("Out of memory!!"));
2555 DebugInt3();
2556 goto failure;
2557 }
2558 memset(pszFiles, 0, bufsize);
2559
2560 pszCurFile = pszFiles;
2561
2562 //copy all filenames
2563 for (i = 0; i < cItems; i++) {
2564 char *pszTemp = pszCurFile;
2565
2566 pDragItem = DrgQueryDragitemPtr(pDragInfo, i);
2567
2568 ulBytes = DrgQueryStrNameLen(pDragItem->hstrContainerName);
2569 ulBytes = DrgQueryStrName(pDragItem->hstrContainerName,
2570 ulBytes, pszCurFile);
2571 if(pszCurFile[ulBytes-1] != '\\') {
2572 pszCurFile[ulBytes] = '\\';
2573 pszCurFile++;
2574 }
2575 pszCurFile += ulBytes;
2576
2577 ulBytes = DrgQueryStrNameLen(pDragItem->hstrSourceName);
2578 ulBytes = DrgQueryStrName(pDragItem->hstrSourceName,
2579 ulBytes+1, pszCurFile);
2580 pszCurFile += ulBytes + 1; //+ terminator
2581
2582 dprintf(("dropped file %s", pszTemp));
2583 }
2584
2585 /* Release the draginfo data structure */
2586 DrgFreeDraginfo(pDragInfo);
2587
2588 *pulBytes = bufsize;
2589 *pcItems = cItems;
2590
2591 return pszFiles;
2592
2593failure:
2594 /* Release the draginfo data structure */
2595 DrgFreeDraginfo(pDragInfo);
2596 if(pszFiles) {
2597 free(pszFiles);
2598 }
2599 return NULL;
2600}
2601//******************************************************************************
2602//******************************************************************************
2603static BOOL PMDragValidate(PDRAGINFO pDragInfo)
2604{
2605 PDRAGITEM pDragItem;
2606 ULONG ulBytes;
2607 int i, cItems;
2608 BOOL ret;
2609 char szFileName[CCHMAXPATH];
2610 char szContainerName[CCHMAXPATH];
2611 USHORT usOp = DO_MOVE;
2612
2613 /* Get access to the DRAGINFO data structure */
2614 if(!DrgAccessDraginfo(pDragInfo)) {
2615 return FALSE;
2616 }
2617
2618 /* Can we accept this drop? */
2619 switch (pDragInfo->usOperation) {
2620 /* Return DOR_NODROPOP if current operation */
2621 /* is link or unknown */
2622 case DO_LINK:
2623 case DO_COPY:
2624 case DO_UNKNOWN:
2625 goto failure;
2626
2627 /* Our default operation is Move */
2628 case DO_MOVE:
2629 case DO_DEFAULT:
2630 pDragItem = DrgQueryDragitemPtr(pDragInfo, 0);
2631 ulBytes = DrgQueryStrName(pDragItem->hstrContainerName,
2632 sizeof(szContainerName),
2633 szContainerName);
2634 ulBytes = DrgQueryStrName(pDragItem->hstrSourceName,
2635 sizeof(szFileName),
2636 szFileName);
2637 if (!ulBytes) {
2638 goto failure;
2639 }
2640
2641 dprintf(("dropped file %s%s", szContainerName, szFileName));
2642 break;
2643 }
2644
2645 cItems = DrgQueryDragitemCount(pDragInfo);
2646
2647 /* Now, we need to look at each item in turn */
2648 for (i = 0; i < cItems; i++) {
2649 pDragItem = DrgQueryDragitemPtr(pDragInfo, i);
2650
2651 /* Make sure we can move for a Move request */
2652 if (!((pDragItem->fsSupportedOps & DO_MOVEABLE) &&
2653 (usOp == (USHORT)DO_MOVE)))
2654 {
2655 dprintf(("item %d not accepted", i));
2656 goto failure;
2657 }
2658 }
2659 /* Release the draginfo data structure */
2660 DrgFreeDraginfo(pDragInfo);
2661 return TRUE;
2662
2663failure:
2664 DrgFreeDraginfo(pDragInfo);
2665 return FALSE;
2666}
2667
2668//******************************************************************************
2669// Override std class names we use in Odin (necessary for keyboard hook)
2670//******************************************************************************
2671void WIN32API SetCustomStdClassName(LPSTR pszStdClassName)
2672{
2673 strcpy(WIN32_STDCLASS, pszStdClassName);
2674}
2675//******************************************************************************
2676//******************************************************************************
2677char *WIN32API QueryCustomStdClassName()
2678{
2679 return WIN32_STDCLASS;
2680}
2681//******************************************************************************
2682//******************************************************************************
2683
2684#ifdef DEBUG_LOGGING
2685static char *DbgGetStringSWPFlags(ULONG flags)
2686{
2687 static char szSWPFlags[512];
2688
2689 szSWPFlags[0] = 0;
2690
2691 if(flags & SWP_SIZE) {
2692 strcat(szSWPFlags, "SWP_SIZE ");
2693 }
2694 if(flags & SWP_MOVE) {
2695 strcat(szSWPFlags, "SWP_MOVE ");
2696 }
2697 if(flags & SWP_ZORDER) {
2698 strcat(szSWPFlags, "SWP_ZORDER ");
2699 }
2700 if(flags & SWP_SHOW) {
2701 strcat(szSWPFlags, "SWP_SHOW ");
2702 }
2703 if(flags & SWP_HIDE) {
2704 strcat(szSWPFlags, "SWP_HIDE ");
2705 }
2706 if(flags & SWP_NOREDRAW) {
2707 strcat(szSWPFlags, "SWP_NOREDRAW ");
2708 }
2709 if(flags & SWP_NOADJUST) {
2710 strcat(szSWPFlags, "SWP_NOADJUST ");
2711 }
2712 if(flags & SWP_ACTIVATE) {
2713 strcat(szSWPFlags, "SWP_ACTIVATE ");
2714 }
2715 if(flags & SWP_DEACTIVATE) {
2716 strcat(szSWPFlags, "SWP_DEACTIVATE ");
2717 }
2718 if(flags & SWP_EXTSTATECHANGE) {
2719 strcat(szSWPFlags, "SWP_EXTSTATECHANGE ");
2720 }
2721 if(flags & SWP_MINIMIZE) {
2722 strcat(szSWPFlags, "SWP_MINIMIZE ");
2723 }
2724 if(flags & SWP_MAXIMIZE) {
2725 strcat(szSWPFlags, "SWP_MAXIMIZE ");
2726 }
2727 if(flags & SWP_RESTORE) {
2728 strcat(szSWPFlags, "SWP_RESTORE ");
2729 }
2730 if(flags & SWP_FOCUSACTIVATE) {
2731 strcat(szSWPFlags, "SWP_FOCUSACTIVATE ");
2732 }
2733 if(flags & SWP_FOCUSDEACTIVATE) {
2734 strcat(szSWPFlags, "SWP_FOCUSDEACTIVATE ");
2735 }
2736 if(flags & SWP_NOAUTOCLOSE) {
2737 strcat(szSWPFlags, "SWP_NOAUTOCLOSE ");
2738 }
2739 return szSWPFlags;
2740}
2741static char *DbgPrintQFCFlags(ULONG flags)
2742{
2743 static char szQFCFlags[64];
2744
2745 szQFCFlags[0] = 0;
2746
2747 if(flags & QFC_NEXTINCHAIN) {
2748 strcat(szQFCFlags, "QFC_NEXTINCHAIN");
2749 }
2750 else
2751 if(flags & QFC_ACTIVE) {
2752 strcat(szQFCFlags, "QFC_ACTIVE");
2753 }
2754 else
2755 if(flags & QFC_FRAME) {
2756 strcat(szQFCFlags, "QFC_FRAME");
2757 }
2758 else
2759 if(flags & QFC_SELECTACTIVE) {
2760 strcat(szQFCFlags, "QFC_SELECTACTIVE");
2761 }
2762 else
2763 if(flags & QFC_PARTOFCHAIN) {
2764 strcat(szQFCFlags, "QFC_PARTOFCHAIN");
2765 }
2766
2767 return szQFCFlags;
2768}
2769#endif
2770
Note: See TracBrowser for help on using the repository browser.