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

Last change on this file since 21529 was 21529, checked in by dmik, 15 years ago

Fixed completely broken national (non-Latin1) character input in Odin. There were two problems:
1) When translating OS2 WM_CHAR to Win32 WM_CHAR in UNICODE mode, ANSI->UNICODE conversion of the character was not done.
2) When hosting windows on threads created with CreateThread(), characters in WM_CHAR were wrongly converted from OS/2 codepage to ANSI codepage while they already were in ANSI due to the message queue begin switched to it at thread startup.
3) The main thread's message queue is now also switched to ANSI at startup so the conversion from step 2) should normally not take place now.

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