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

Last change on this file since 8735 was 8735, checked in by sandervl, 23 years ago

drag & drop fix; added SetDragDrop; enabled drag & drop

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