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

Last change on this file since 7195 was 7195, checked in by sandervl, 24 years ago

double click fix + double click on system menu now works

File size: 54.4 KB
Line 
1/* $Id: pmwindow.cpp,v 1.157 2001-10-24 15:41:54 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_WINTRACKRECT
19
20#include <os2wrap.h>
21#include <stdlib.h>
22#include <string.h>
23#include <win32type.h>
24#include <win32api.h>
25#include <winconst.h>
26#include <winuser32.h>
27#include <wprocess.h>
28#include <misc.h>
29#include <win32wbase.h>
30#include <win32dlg.h>
31#include "win32wdesktop.h"
32#include "pmwindow.h"
33#include "oslibwin.h"
34#include "oslibutil.h"
35#include "oslibgdi.h"
36#include "oslibmsg.h"
37#define INCLUDED_BY_DC
38#include "dc.h"
39#include <thread.h>
40#include <wprocess.h>
41#include "caret.h"
42#include "timer.h"
43#include <codepage.h>
44#include "syscolor.h"
45#include "options.h"
46#include "menu.h"
47
48#define DBG_LOCALLOG DBG_pmwindow
49#include "dbglocal.h"
50
51//define this to use the new code for WM_CALCVALIDRECT handling
52//#define USE_CALCVALIDRECT
53
54HMQ hmq = 0; /* Message queue handle */
55HAB hab = 0;
56RECTL desktopRectl = {0};
57ULONG ScreenWidth = 0;
58ULONG ScreenHeight = 0;
59ULONG ScreenBitsPerPel = 0;
60BOOL fOS2Look = FALSE;
61HBITMAP hbmFrameMenu[3] = {0};
62
63static PFNWP pfnFrameWndProc = NULL;
64
65MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
66MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2);
67void FrameReplaceMenuItem(HWND hwndMenu, ULONG nIndex, ULONG idOld, ULONG idNew,
68 HBITMAP hbmNew);
69void FrameSetFocus(HWND hwnd);
70
71VOID APIENTRY DspInitSystemDriverName(PSZ pszDriverName, ULONG lenDriverName);
72
73//******************************************************************************
74//Initialize PM; create hab, message queue and register special Win32 window classes
75//******************************************************************************
76BOOL InitPM()
77{
78 hab = WinInitialize(0);
79 dprintf(("Winitialize returned %x", hab));
80 hmq = WinCreateMsgQueue(hab, 0);
81
82 if(!hab || !hmq)
83 {
84 UINT error;
85 //CB: only fail on real error
86 error = WinGetLastError(hab) & 0xFFFF; //error code
87 if (!hab || (error != PMERR_MSG_QUEUE_ALREADY_EXISTS))
88 {
89 dprintf(("WinInitialize or WinCreateMsgQueue failed %x %x", hab, hmq));
90 dprintf((" Error = %x",error));
91 return(FALSE);
92 }
93 else
94 {
95 if(!hab) {
96 hab = WinQueryAnchorBlock(HWND_DESKTOP);
97 dprintf(("WinQueryAnchorBlock returned %x", hab));
98 }
99 if(!hmq) {
100 PTIB ptib;
101 PPIB ppib;
102
103 DosGetInfoBlocks(&ptib, &ppib);
104
105 hmq = WinQueueFromID(hab, ppib->pib_ulpid, ptib->tib_ptib2->tib2_ultid);
106 }
107 }
108 }
109 SetThreadHAB(hab);
110 dprintf(("InitPM: hmq = %x", hmq));
111 SetThreadMessageQueue(hmq);
112
113 BOOL rc = WinSetCp(hmq, GetDisplayCodepage());
114 dprintf(("InitPM: WinSetCP was %sOK", rc ? "" : "not "));
115
116 if(!WinRegisterClass( /* Register window class */
117 hab, /* Anchor block handle */
118 (PSZ)WIN32_STDCLASS, /* Window class name */
119 (PFNWP)Win32WindowProc, /* Address of window procedure */
120 0,
121 NROF_WIN32WNDBYTES))
122 {
123 dprintf(("WinRegisterClass Win32BaseWindow failed"));
124 return(FALSE);
125 }
126
127 CLASSINFO FrameClassInfo;
128 if(!WinQueryClassInfo (hab, WC_FRAME, &FrameClassInfo)) {
129 dprintf (("WinQueryClassInfo WC_FRAME failed"));
130 return (FALSE);
131 }
132 pfnFrameWndProc = FrameClassInfo.pfnWindowProc;
133
134 dprintf(("WC_FRAME style %x", FrameClassInfo.flClassStyle));
135
136 if(!WinRegisterClass( /* Register window class */
137 hab, /* Anchor block handle */
138 (PSZ)WIN32_STDFRAMECLASS, /* Window class name */
139 (PFNWP)Win32FrameWindowProc, /* Address of window procedure */
140 CS_FRAME,
141 FrameClassInfo.cbWindowData))
142 {
143 dprintf(("WinRegisterClass Win32BaseWindow failed %x", WinGetLastError(hab)));
144 return(FALSE);
145 }
146
147 WinQueryWindowRect(HWND_DESKTOP, &desktopRectl);
148 ScreenWidth = desktopRectl.xRight;
149 ScreenHeight = desktopRectl.yTop;
150
151 HDC hdc; /* Device-context handle */
152 /* context data structure */
153 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
154 NULL, NULL, NULL};
155
156 /* create memory device context */
157 hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
158
159 fOS2Look = PROFILE_GetOdinIniBool(ODINSYSTEM_SECTION, "OS2Look", FALSE);
160 if(fOS2Look)
161 {
162 CHAR szDisplay[30];
163 HMODULE hModDisplay;
164
165 SYSCOLOR_Init(FALSE); //use OS/2 colors
166
167 DspInitSystemDriverName(szDisplay, sizeof(szDisplay));
168 DosQueryModuleHandle(szDisplay, &hModDisplay);
169
170 hbmFrameMenu[0] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MINBUTTON, 0, 0);
171 hbmFrameMenu[1] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MAXBUTTON, 0, 0);
172 hbmFrameMenu[2] = GpiLoadBitmap(hdc, hModDisplay, SBMP_RESTOREBUTTON, 0, 0);
173 }
174
175 DevQueryCaps(hdc, CAPS_COLOR_BITCOUNT, 1, (PLONG)&ScreenBitsPerPel);
176 DevCloseDC(hdc);
177
178 dprintf(("InitPM: Desktop (%d,%d) bpp %d", ScreenWidth, ScreenHeight, ScreenBitsPerPel));
179 return TRUE;
180} /* End of main */
181//******************************************************************************
182//menu.cpp
183BOOL MENU_Init();
184//******************************************************************************
185void WIN32API SetWindowAppearance(int fLooks)
186{
187 if(fLooks == OS2_APPEARANCE || fLooks == OS2_APPEARANCE_SYSMENU)
188 {
189 CHAR szDisplay[30];
190 HMODULE hModDisplay;
191
192 SYSCOLOR_Init(FALSE); //use OS/2 colors
193
194 if(hbmFrameMenu[0] == 0)
195 {
196 CHAR szDisplay[30];
197 HMODULE hModDisplay;
198 HDC hdc; /* Device-context handle */
199 DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL, NULL,
200 NULL, NULL, NULL};
201
202 /* create memory device context */
203 hdc = DevOpenDC(hab, OD_MEMORY, "*", 5L, (PDEVOPENDATA)&dop, NULLHANDLE);
204
205 DspInitSystemDriverName(szDisplay, sizeof(szDisplay));
206 DosQueryModuleHandle(szDisplay, &hModDisplay);
207
208 hbmFrameMenu[0] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MINBUTTON, 0, 0);
209 hbmFrameMenu[1] = GpiLoadBitmap(hdc, hModDisplay, SBMP_MAXBUTTON, 0, 0);
210 hbmFrameMenu[2] = GpiLoadBitmap(hdc, hModDisplay, SBMP_RESTOREBUTTON, 0, 0);
211 DevCloseDC(hdc);
212 }
213 }
214 fOS2Look = fLooks;
215 MENU_Init();
216}
217//******************************************************************************
218//Win32 window message handler
219//******************************************************************************
220MRESULT EXPENTRY Win32WindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
221{
222 Win32BaseWindow *win32wnd;
223 TEB *teb;
224 MSG winMsg, *pWinMsg;
225 MRESULT rc = 0;
226 POSTMSG_PACKET *postmsg;
227 OSLIBPOINT point, ClientPoint;
228
229 //Restore our FS selector
230 SetWin32TIB();
231
232 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- BEGIN
233 teb = GetThreadTEB();
234 win32wnd = Win32BaseWindow::GetWindowFromOS2Handle(hwnd);
235
236//// dprintf(("window %x msg %x", (win32wnd) ? win32wnd->getWindowHandle() : 0, msg));
237
238 if(!teb || (msg != WM_CREATE && win32wnd == NULL)) {
239 dprintf(("OS2: Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
240 goto RunDefWndProc;
241 }
242//// if(teb->o.odin.fIgnoreMsgs) {
243//// goto RunDefWndProc;
244//// }
245
246 if((teb->o.odin.msgstate & 1) == 0)
247 {//message that was sent directly to our window proc handler; translate it here
248 QMSG qmsg;
249
250 qmsg.msg = msg;
251 qmsg.hwnd = hwnd;
252 qmsg.mp1 = mp1;
253 qmsg.mp2 = mp2;
254 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
255 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
256 qmsg.reserved = 0;
257
258 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
259 {//message was not translated
260 memset(&winMsg, 0, sizeof(MSG));
261 }
262 pWinMsg = &winMsg;
263 }
264 else {
265 pWinMsg = &teb->o.odin.msg;
266 teb->o.odin.msgstate++;
267 }
268 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- END
269
270 if(msg >= WIN32APP_POSTMSG) {
271 //probably win32 app user message
272 dprintf2(("Posted message %x->%x", msg, msg-WIN32APP_POSTMSG));
273 if((ULONG)mp1 == WIN32MSG_MAGICA) {
274 rc = (MRESULT)win32wnd->DispatchMsgA(pWinMsg);
275 }
276 else
277 if((ULONG)mp1 == WIN32MSG_MAGICW) {
278 rc = (MRESULT)win32wnd->DispatchMsgW(pWinMsg);
279 }
280 else {//broadcasted message
281 rc = (MRESULT)win32wnd->DispatchMsgA(pWinMsg);
282 }
283 RELEASE_WNDOBJ(win32wnd);
284 RestoreOS2TIB();
285 return rc;
286 }
287
288 switch( msg )
289 {
290 //OS/2 msgs
291 case WM_CREATE:
292 {
293 if(teb->o.odin.newWindow == 0)
294 goto createfail;
295
296 //Processing is done in after WinCreateWindow returns
297 dprintf(("OS2: WM_CREATE %x", hwnd));
298 win32wnd = (Win32BaseWindow *)teb->o.odin.newWindow;
299 win32wnd->addRef();
300 teb->o.odin.newWindow = 0;
301 if(win32wnd->MsgCreate(hwnd) == FALSE)
302 {
303 rc = (MRESULT)TRUE; //discontinue window creation
304 break;
305 }
306 createfail:
307 rc = (MRESULT)FALSE;
308 break;
309 }
310
311 case WM_QUIT:
312 dprintf(("OS2: WM_QUIT %x", hwnd));
313 win32wnd->MsgQuit();
314 break;
315
316 case WM_CLOSE:
317 dprintf(("OS2: WM_CLOSE %x", hwnd));
318 win32wnd->MsgClose();
319 break;
320
321 case WM_DESTROY:
322 dprintf(("OS2: WM_DESTROY %x", hwnd));
323 win32wnd->MsgDestroy();
324 WinSetVisibleRegionNotify(hwnd, FALSE);
325 goto RunDefWndProc;
326
327 case WM_ENABLE:
328 dprintf(("OS2: WM_ENABLE %x", hwnd));
329 break;
330
331 case WM_SHOW:
332 dprintf(("OS2: WM_SHOW %x %d", hwnd, mp1));
333 win32wnd->MsgShow((ULONG)mp1);
334 break;
335
336 case WM_ACTIVATE:
337 {
338 ULONG flags = WinQueryWindowULong(hwnd, OFFSET_WIN32FLAGS);
339
340 dprintf(("OS2: WM_ACTIVATE %x %x %x", hwnd, mp1, mp2));
341 WinSetWindowULong(hwnd, OFFSET_WIN32FLAGS, SHORT1FROMMP(mp1) ? (flags | WINDOWFLAG_ACTIVE):(flags & ~WINDOWFLAG_ACTIVE));
342 if(win32wnd->IsWindowCreated())
343 {
344 win32wnd->MsgActivate((LOWORD(pWinMsg->wParam) == WA_ACTIVE_W) ? 1 : 0, HIWORD(pWinMsg->wParam), pWinMsg->lParam, (HWND)mp2);
345 }
346 break;
347 }
348
349 case WM_SIZE:
350 {
351 dprintf(("OS2: WM_SIZE (%d,%d) (%d,%d)", SHORT1FROMMP(mp2), SHORT2FROMMP(mp2), SHORT1FROMMP(mp1), SHORT2FROMMP(mp1)));
352 win32wnd->SetVisibleRegionChanged(TRUE);
353 goto RunDefWndProc;
354 }
355
356
357 case WM_VRNENABLED:
358 dprintf(("OS2: WM_VRNENABLED %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
359 //Always call handler; even if mp1 is 0. If we don't do this, the
360 //DivX 4 player will never be allowed to draw after putting another window
361 //on top of it.
362 win32wnd->callVisibleRgnNotifyProc(TRUE);
363 if(!win32wnd->isComingToTop() && ((win32wnd->getExStyle() & WS_EX_TOPMOST_W) == WS_EX_TOPMOST_W))
364 {
365 HWND hwndrelated;
366 Win32BaseWindow *topwindow;
367
368 win32wnd->setComingToTop(TRUE);
369
370 hwndrelated = WinQueryWindow(hwnd, QW_PREV);
371 dprintf(("WM_VRNENABLED hwndrelated = %x (hwnd=%x)", hwndrelated, hwnd));
372 topwindow = Win32BaseWindow::GetWindowFromOS2Handle(hwndrelated);
373 if(topwindow == NULL || ((win32wnd->getExStyle() & WS_EX_TOPMOST_W) == 0)) {
374 //put window at the top of z order
375 WinSetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_ZORDER );
376 }
377 if(topwindow) RELEASE_WNDOBJ(topwindow);
378
379 win32wnd->setComingToTop(FALSE);
380 break;
381 }
382 goto RunDefWndProc;
383
384 case WM_VRNDISABLED:
385 dprintf(("OS2: WM_VRNDISABLED %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
386 //visible region is about to change or WinLockWindowUpdate called
387 //suspend window drawing
388 win32wnd->callVisibleRgnNotifyProc(FALSE);
389 goto RunDefWndProc;
390
391 case WIN32APP_SETFOCUSMSG:
392 //PM doesn't allow SetFocus calls during WM_SETFOCUS message processing;
393 //must delay this function call
394 //mp1 = win32 window handle
395 //mp2 = top parent if activation required
396 dprintf(("USER32: Delayed SetFocus %x %x %x call!", teb->o.odin.hwndFocus, mp1, mp2));
397 if(teb->o.odin.hwndFocus) {
398 RELEASE_WNDOBJ(win32wnd);
399 win32wnd = Win32BaseWindow::GetWindowFromHandle(teb->o.odin.hwndFocus);
400 if(win32wnd) {
401 if(mp2) {
402 SetActiveWindow((HWND)mp2);
403 }
404 if(!IsWindow(win32wnd->getWindowHandle())) break; //abort if window destroyed
405 WinFocusChange(HWND_DESKTOP, win32wnd->getOS2WindowHandle(), FC_NOSETACTIVE);
406 }
407 else DebugInt3();
408 }
409 break;
410
411 case WM_SETFOCUS:
412 {
413 HWND hwndFocus = (HWND)mp1;
414
415 dprintf(("OS2: WM_SETFOCUS %x %x (%x) %d", win32wnd->getWindowHandle(), mp1, OS2ToWin32Handle(hwndFocus), mp2));
416
417 //PM doesn't allow SetFocus calls during WM_SETFOCUS message processing;
418 //must delay this function call
419
420 teb->o.odin.fWM_SETFOCUS = TRUE;
421 teb->o.odin.hwndFocus = 0;
422 if(WinQueryWindowULong(hwndFocus, OFFSET_WIN32PM_MAGIC) != WIN32PM_MAGIC)
423 {
424 //another (non-win32) application's window
425 //set to NULL (allowed according to win32 SDK) to avoid problems
426 hwndFocus = NULL;
427 }
428 if((ULONG)mp2 == TRUE) {
429 HWND hwndFocusWin32 = OS2ToWin32Handle(hwndFocus);
430 recreateCaret (hwndFocusWin32);
431 win32wnd->MsgSetFocus(hwndFocusWin32);
432 }
433 else win32wnd->MsgKillFocus(OS2ToWin32Handle(hwndFocus));
434 teb->o.odin.fWM_SETFOCUS = FALSE;
435
436 break;
437 }
438
439 //**************************************************************************
440 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
441 //**************************************************************************
442
443 case WM_BUTTON1DOWN:
444 case WM_BUTTON1UP:
445 case WM_BUTTON1DBLCLK:
446 case WM_BUTTON2DOWN:
447 case WM_BUTTON2UP:
448 case WM_BUTTON2DBLCLK:
449 case WM_BUTTON3DOWN:
450 case WM_BUTTON3UP:
451 case WM_BUTTON3DBLCLK:
452 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
453 RELEASE_WNDOBJ(win32wnd);
454 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
455 }
456 if(win32wnd)
457 win32wnd->MsgButton(pWinMsg);
458
459 rc = (MRESULT)TRUE;
460 break;
461
462 case WM_BUTTON2MOTIONSTART:
463 case WM_BUTTON2MOTIONEND:
464 case WM_BUTTON2CLICK:
465 case WM_BUTTON1MOTIONSTART:
466 case WM_BUTTON1MOTIONEND:
467 case WM_BUTTON1CLICK:
468 case WM_BUTTON3MOTIONSTART:
469 case WM_BUTTON3MOTIONEND:
470 case WM_BUTTON3CLICK:
471 rc = (MRESULT)TRUE;
472 break;
473
474 case WM_MOUSEMOVE:
475 {
476 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
477 RELEASE_WNDOBJ(win32wnd);
478 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
479 }
480 if(win32wnd)
481 win32wnd->MsgMouseMove(pWinMsg);
482 break;
483 }
484
485 case WM_CONTROL:
486 goto RunDefWndProc;
487
488 case WM_COMMAND:
489 dprintf(("OS2: WM_COMMAND %x %x %x", hwnd, mp1, mp2));
490 win32wnd->DispatchMsgA(pWinMsg);
491 break;
492
493 case WM_SYSCOMMAND:
494 dprintf(("OS2: WM_SYSCOMMAND %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
495 win32wnd->DispatchMsgA(pWinMsg);
496 break;
497
498 case WM_RENDERFMT:
499 case WM_RENDERALLFMTS:
500 case WM_DESTROYCLIPBOARD:
501 win32wnd->DispatchMsgA(pWinMsg);
502 break;
503
504 case WM_CHAR:
505 dprintf(("OS2: WM_CHAR %x %x %x, %x %x", win32wnd->getWindowHandle(), mp1, mp2, pWinMsg->wParam, pWinMsg->lParam));
506 win32wnd->MsgChar(pWinMsg);
507 break;
508
509 case WM_TIMER:
510 dprintf(("OS2: WM_TIMER %x %x time %x", win32wnd->getWindowHandle(), pWinMsg->wParam, GetTickCount()));
511 win32wnd->DispatchMsgA(pWinMsg);
512 goto RunDefWndProc;
513
514 case WM_SETWINDOWPARAMS:
515 {
516 WNDPARAMS *wndParams = (WNDPARAMS *)mp1;
517
518 dprintf(("OS2: WM_SETWINDOWPARAMS %x", hwnd));
519 if(wndParams->fsStatus & WPM_TEXT) {
520 win32wnd->MsgSetText(wndParams->pszText, wndParams->cchText);
521 }
522 goto RunDefWndProc;
523 }
524
525 case WM_QUERYWINDOWPARAMS:
526 {
527 PWNDPARAMS wndpars = (PWNDPARAMS)mp1;
528 ULONG textlen;
529 PSZ wintext;
530
531 if(wndpars->fsStatus & (WPM_CCHTEXT | WPM_TEXT))
532 {
533 if(wndpars->fsStatus & WPM_TEXT)
534 win32wnd->MsgGetText(wndpars->pszText, wndpars->cchText);
535 if(wndpars->fsStatus & WPM_CCHTEXT)
536 wndpars->cchText = win32wnd->MsgGetTextLength();
537
538 wndpars->fsStatus = 0;
539 wndpars->cbCtlData = 0;
540 wndpars->cbPresParams = 0;
541 rc = (MRESULT)TRUE;
542 break;
543 }
544 goto RunDefWndProc;
545 }
546
547 case WM_PAINT:
548 {
549 RECTL rectl;
550 BOOL rc;
551
552 rc = WinQueryUpdateRect(hwnd, &rectl);
553 dprintf(("OS2: WM_PAINT %x (%d,%d) (%d,%d) rc=%d", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop, rc));
554
555 if(rc && win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
556 rectl.yBottom != rectl.yTop))
557 {
558 win32wnd->DispatchMsgA(pWinMsg);
559 }
560 else goto RunDefWndProc;
561 break;
562 }
563
564 case WM_ERASEBACKGROUND:
565 {
566 dprintf(("OS2: WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
567 rc = (MRESULT)FALSE;
568 break;
569 }
570
571 case WM_CALCVALIDRECTS:
572 dprintf(("OS2: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
573 rc = (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
574 break;
575
576 case WM_REALIZEPALETTE:
577 {
578 dprintf(("OS2: WM_REALIZEPALETTE"));
579 goto RunDefWndProc;
580 }
581
582 case WM_HSCROLL:
583 case WM_VSCROLL:
584 dprintf(("OS2: %s %x %x %x", (msg == WM_HSCROLL) ? "WM_HSCROLL" : "WM_VSCROLL", win32wnd->getWindowHandle(), mp1, mp2));
585 win32wnd->DispatchMsgA(pWinMsg);
586 break;
587
588 case WM_DDE_INITIATE:
589 case WM_DDE_INITIATEACK:
590 case WM_DDE_REQUEST:
591 case WM_DDE_ACK:
592 case WM_DDE_DATA:
593 case WM_DDE_ADVISE:
594 case WM_DDE_UNADVISE:
595 case WM_DDE_POKE:
596 case WM_DDE_EXECUTE:
597 case WM_DDE_TERMINATE:
598 dprintf(("OS2: WM_DDE %x %x", msg, win32wnd->getWindowHandle()));
599 goto RunDefWndProc;
600
601 case WM_INITMENU:
602 case WM_MENUSELECT:
603 case WM_MENUEND:
604 case WM_NEXTMENU:
605 case WM_SYSCOLORCHANGE:
606 case WM_SYSVALUECHANGED:
607 case WM_SETSELECTION:
608 case WM_PPAINT:
609 case WM_PSETFOCUS:
610 case WM_PSYSCOLORCHANGE:
611 case WM_PSIZE:
612 case WM_PACTIVATE:
613 case WM_PCONTROL:
614 case WM_HELP:
615 case WM_APPTERMINATENOTIFY:
616 case WM_PRESPARAMCHANGED:
617 case WM_DRAWITEM:
618 case WM_MEASUREITEM:
619 case WM_CONTROLPOINTER:
620 case WM_QUERYDLGCODE:
621 case WM_SUBSTITUTESTRING:
622 case WM_MATCHMNEMONIC:
623 case WM_SAVEAPPLICATION:
624 case WM_SEMANTICEVENT:
625 default:
626 dprintf2(("OS2: RunDefWndProc hwnd %x msg %x mp1 %x mp2 %x", hwnd, msg, mp1, mp2));
627 goto RunDefWndProc;
628 }
629 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
630 RestoreOS2TIB();
631 return (MRESULT)rc;
632
633RunDefWndProc:
634// dprintf(("OS2: RunDefWndProc msg %x for %x", msg, hwnd));
635 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
636 RestoreOS2TIB();
637 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
638} /* End of Win32WindowProc */
639//******************************************************************************
640//******************************************************************************
641MRESULT EXPENTRY Win32FrameWindowProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
642{
643 POSTMSG_PACKET *postmsg;
644 OSLIBPOINT point, ClientPoint;
645 Win32BaseWindow *win32wnd;
646 TEB *teb;
647 MRESULT rc = 0;
648 MSG winMsg, *pWinMsg;
649
650 //Restore our FS selector
651 SetWin32TIB();
652
653 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- BEGIN
654 teb = GetThreadTEB();
655 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwnd);
656
657 if(!teb || (msg != WM_CREATE && win32wnd == NULL)) {
658 dprintf(("PMFRAME: Invalid win32wnd pointer for window %x msg %x", hwnd, msg));
659 goto RunDefFrameWndProc;
660 }
661//// if(teb->o.odin.fIgnoreMsgs) {
662//// goto RunDefWndProc;
663//// }
664
665 if((teb->o.odin.msgstate & 1) == 0)
666 {//message that was sent directly to our window proc handler; translate it here
667 QMSG qmsg;
668
669 qmsg.msg = msg;
670 qmsg.hwnd = hwnd;
671 qmsg.mp1 = mp1;
672 qmsg.mp2 = mp2;
673 qmsg.time = WinQueryMsgTime(teb->o.odin.hab);
674 WinQueryMsgPos(teb->o.odin.hab, &qmsg.ptl);
675 qmsg.reserved = 0;
676
677 if(OS2ToWinMsgTranslate((PVOID)teb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
678 {//message was not translated
679 memset(&winMsg, 0, sizeof(MSG));
680 }
681 pWinMsg = &winMsg;
682 }
683 else {
684 pWinMsg = &teb->o.odin.msg;
685 teb->o.odin.msgstate++;
686 }
687 //NOTE-------------->>>>>> If this is changed, also change Win32WindowProc!! <<<<<<<<<<<-------------------- END
688
689 switch( msg )
690 {
691 case WM_CREATE:
692 {
693 //WM_CREATE handled during client window creation
694 dprintf(("PMFRAME: WM_CREATE %x", hwnd));
695 goto RunDefFrameWndProc;
696 }
697
698 case WM_PAINT:
699 {
700 RECTL rectl;
701
702 HPS hps = WinBeginPaint(hwnd, NULL, &rectl);
703 dprintf(("PMFRAME: WM_PAINT %x (%d,%d) (%d,%d)", win32wnd->getWindowHandle(), rectl.xLeft, rectl.yBottom, rectl.xRight, rectl.yTop));
704
705 if(win32wnd->IsWindowCreated() && (rectl.xLeft != rectl.xRight &&
706 rectl.yBottom != rectl.yTop))
707 {
708 PRECT pClient = win32wnd->getClientRectPtr();
709 PRECT pWindow = win32wnd->getWindowRect();
710
711 if(!(pClient->left == 0 && pClient->top == 0 &&
712 win32wnd->getClientHeight() == win32wnd->getWindowHeight() &&
713 win32wnd->getClientWidth() == win32wnd->getWindowWidth()))
714 {
715 RECT rectUpdate;
716
717 mapOS2ToWin32Rect(win32wnd->getWindowHeight(), (PRECTLOS2)&rectl, &rectUpdate);
718 win32wnd->MsgNCPaint(&rectUpdate);
719 }
720 }
721 WinEndPaint(hps);
722 break;
723 }
724
725 case WM_ERASEBACKGROUND:
726 {
727 dprintf(("PMFRAME:WM_ERASEBACKGROUND %x", win32wnd->getWindowHandle()));
728 rc = (MRESULT)FALSE;
729 break;
730 }
731
732 //**************************************************************************
733 //Mouse messages (OS/2 Window coordinates -> Win32 coordinates relative to screen
734 //**************************************************************************
735
736 case WM_BUTTON1DOWN:
737 case WM_BUTTON1UP:
738 case WM_BUTTON1DBLCLK:
739 case WM_BUTTON2DOWN:
740 case WM_BUTTON2UP:
741 case WM_BUTTON2DBLCLK:
742 case WM_BUTTON3DOWN:
743 case WM_BUTTON3UP:
744 case WM_BUTTON3DBLCLK:
745 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
746 RELEASE_WNDOBJ(win32wnd);
747 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
748 }
749 if(win32wnd)
750 win32wnd->MsgButton(pWinMsg);
751
752 rc = (MRESULT)TRUE;
753 break;
754
755 case WM_BUTTON2MOTIONSTART:
756 case WM_BUTTON2MOTIONEND:
757 case WM_BUTTON2CLICK:
758 case WM_BUTTON1MOTIONSTART:
759 case WM_BUTTON1MOTIONEND:
760 case WM_BUTTON1CLICK:
761 case WM_BUTTON3MOTIONSTART:
762 case WM_BUTTON3MOTIONEND:
763 case WM_BUTTON3CLICK:
764 rc = (MRESULT)TRUE;
765 break;
766
767 case WM_MOUSEMOVE:
768 {
769 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
770 RELEASE_WNDOBJ(win32wnd);
771 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
772 }
773 if(win32wnd)
774 win32wnd->MsgMouseMove(pWinMsg);
775 break;
776 }
777
778 case WM_ADJUSTWINDOWPOS:
779 {
780 PSWP pswp = (PSWP)mp1;
781 SWP swpOld;
782 WINDOWPOS wp,wpOld;
783 ULONG ulFlags;
784 ULONG ret = 0;
785 HWND hParent = NULLHANDLE, hwndAfter;
786
787 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));
788
789 ulFlags = pswp->fl;
790
791 if(win32wnd->IsParentChanging()) {
792 rc = 0;
793 break;
794 }
795
796 if(pswp->fl & SWP_NOADJUST) {
797 //ignore weird messages (TODO: why are they sent?)
798 dprintf(("WARNING: WM_ADJUSTWINDOWPOS with SWP_NOADJUST flag!!"));
799 break;
800 }
801 //CB: show dialog in front of owner
802 if (win32wnd->IsModalDialogOwner())
803 {
804 dprintf(("win32wnd->IsModalDialogOwner %x", win32wnd->getWindowHandle()));
805 pswp->fl |= SWP_ZORDER;
806 pswp->hwndInsertBehind = win32wnd->getOS2HwndModalDialog();
807 if (pswp->fl & SWP_ACTIVATE)
808 {
809 pswp->fl &= ~SWP_ACTIVATE;
810 WinSetWindowPos(win32wnd->getOS2HwndModalDialog(),0,0,0,0,0,SWP_ACTIVATE);
811 }
812 }
813
814 if(!win32wnd->CanReceiveSizeMsgs())
815 break;
816
817 WinQueryWindowPos(hwnd, &swpOld);
818 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
819 if (win32wnd->isChild()) {
820 if(win32wnd->getParent()) {
821 hParent = win32wnd->getParent()->getOS2WindowHandle();
822 }
823 else goto RunDefFrameWndProc;
824 }
825 }
826 hwndAfter = pswp->hwndInsertBehind;
827 if(win32wnd->getParent()) {
828 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(), hwnd);
829 }
830 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
831
832 wp.hwnd = win32wnd->getWindowHandle();
833 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
834 {
835 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
836 dprintf2(("SWP_ZORDER: %x %x", pswp->hwndInsertBehind, (wndAfter) ? wndAfter->getWindowHandle() : 0));
837 if(wndAfter) {
838 wp.hwndInsertAfter = wndAfter->getWindowHandle();
839 RELEASE_WNDOBJ(wndAfter);
840 }
841 else wp.hwndInsertAfter = HWND_TOP_W;
842 }
843
844 wpOld = wp;
845 win32wnd->MsgPosChanging((LPARAM)&wp);
846
847 if(win32wnd->getOldStyle() != win32wnd->getStyle())
848 {
849 OSLibSetWindowStyle(win32wnd->getOS2FrameWindowHandle(), win32wnd->getOS2WindowHandle(), win32wnd->getStyle(), win32wnd->getExStyle());
850 if(fOS2Look) {
851 DWORD dwOldStyle = win32wnd->getOldStyle();
852 DWORD dwStyle = win32wnd->getStyle();
853
854 if((dwOldStyle & WS_MINIMIZE_W) && !(dwStyle & WS_MINIMIZE_W)) {
855 //SC_RESTORE -> SC_MINIMIZE
856 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), 0, SC_RESTORE, SC_MINIMIZE, hbmFrameMenu[0]);
857 }
858 else
859 if((dwOldStyle & WS_MAXIMIZE_W) && !(dwStyle & WS_MAXIMIZE_W)) {
860 //SC_RESTORE -> SC_MAXIMIZE
861 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_RESTORE, SC_MAXIMIZE, hbmFrameMenu[1]);
862 }
863 else
864 if(!(dwOldStyle & WS_MINIMIZE_W) && (dwStyle & WS_MINIMIZE_W)) {
865 //SC_MINIMIZE -> SC_RESTORE
866 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), 0, SC_MINIMIZE, SC_RESTORE, hbmFrameMenu[2]);
867 }
868 else
869 if(!(dwOldStyle & WS_MAXIMIZE_W) && (dwStyle & WS_MAXIMIZE_W)) {
870 //SC_MAXIMIZE -> SC_RESTORE
871 FrameReplaceMenuItem(WinWindowFromID(hwnd, FID_MINMAX), MIT_END, SC_MAXIMIZE, SC_RESTORE, hbmFrameMenu[2]);
872 }
873 }
874 }
875
876 if ((wp.hwndInsertAfter != wpOld.hwndInsertAfter) ||
877 (wp.x != wpOld.x) || (wp.y != wpOld.y) || (wp.cx != wpOld.cx) || (wp.cy != wpOld.cy) || (wp.flags != wpOld.flags))
878 {
879 ULONG flags = pswp->fl; //make a backup copy; OSLibMapWINDOWPOStoSWP will modify it
880
881 dprintf(("PMFRAME:WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
882 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
883
884 if(win32wnd->getParent()) {
885 OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, win32wnd->getParent()->getClientHeight(),
886 hwnd);
887 }
888 else OSLibMapWINDOWPOStoSWP(&wp, pswp, &swpOld, OSLibQueryScreenHeight(), hwnd);
889
890 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
891
892 //OSLibMapWINDOWPOStoSWP can add flags, but we must not let it remove flags!
893 if(pswp->fl & SWP_SIZE)
894 flags |= SWP_SIZE;
895
896 if(pswp->fl & SWP_MOVE)
897 flags |= SWP_MOVE;
898
899 pswp->fl = flags; //restore flags
900
901 pswp->fl |= SWP_NOADJUST;
902 pswp->hwndInsertBehind = hwndAfter;
903 pswp->hwnd = hwnd;
904
905 ret = 0xf;
906 }
907adjustend:
908 //The next part needs to be done for top-level windows only
909 if(!((win32wnd->getStyle() & (WS_POPUP_W|WS_CHILD_W)) == WS_CHILD_W))
910 {
911 //Setting these flags is necessary to avoid activation/focus problems
912 if(ulFlags & SWP_DEACTIVATE) {
913 ret |= AWP_DEACTIVATE;
914 }
915 if(ulFlags & SWP_ACTIVATE)
916 {
917 if(ulFlags & SWP_ZORDER) {
918 dprintf(("Set FF_NOACTIVATESWP"));
919 ULONG ulFrameFlags = WinQueryWindowUShort(hwnd, QWS_FLAGS);
920 WinSetWindowUShort(hwnd, QWS_FLAGS, ulFrameFlags | FF_NOACTIVATESWP);
921 }
922
923 if(!(ulFlags & SWP_SHOW))
924 {
925 ret |= AWP_ACTIVATE;
926 }
927 else
928 {
929 FrameSetFocus(hwnd);
930 }
931 }
932 }
933 else {
934 if(ulFlags & (SWP_ACTIVATE|SWP_FOCUSACTIVATE))
935 {
936 win32wnd->MsgChildActivate(TRUE);
937 if(fOS2Look) {
938 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
939 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, (MPARAM)1, 0);
940 }
941 }
942 else
943 if(ulFlags & (SWP_DEACTIVATE|SWP_FOCUSDEACTIVATE))
944 {
945 win32wnd->MsgChildActivate(FALSE);
946 if(fOS2Look) {
947 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
948 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, 0, 0);
949 }
950 }
951 }
952 dprintf(("WM_ADJUSTWINDOWPOS ret %x flags %x", ret, WinQueryWindowUShort(hwnd, QWS_FLAGS)));
953 rc = (MRESULT)ret;
954 break;
955 }
956
957 case WM_WINDOWPOSCHANGED:
958 {
959 PSWP pswp = (PSWP)mp1,pswpOld = pswp+1;
960 SWP swpOld = *(pswp + 1);
961 WINDOWPOS wp;
962 ULONG flAfp = (ULONG)mp2;
963 HWND hParent = NULLHANDLE;
964 RECTL rect;
965
966 dprintf(("PMFRAME:WM_WINDOWPOSCHANGED (%x) %x %x (%d,%d) (%d,%d)", mp2, win32wnd->getWindowHandle(), pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
967 if(win32wnd->IsParentChanging()) {
968 goto PosChangedEnd;
969 }
970
971 //SvL: When a window is made visible, then we don't receive a
972 // WM_VRNENABLED message (for some weird reason)
973 if(pswp->fl & SWP_SHOW) {
974 win32wnd->callVisibleRgnNotifyProc(TRUE);
975 }
976 else
977 if(pswp->fl & SWP_HIDE) {
978 win32wnd->callVisibleRgnNotifyProc(FALSE);
979 }
980
981 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0)
982 {
983 if(pswp->fl & SWP_RESTORE && win32wnd->getStyle() & WS_MINIMIZE_W) {
984 dprintf(("Restoring minimized window %x", win32wnd->getWindowHandle()));
985 win32wnd->ShowWindow(SW_RESTORE_W);
986 }
987 if(pswp->fl & SWP_SHOW) {
988 WinShowWindow(win32wnd->getOS2WindowHandle(), 1);
989 }
990 else
991 if(pswp->fl & SWP_HIDE) {
992 WinShowWindow(win32wnd->getOS2WindowHandle(), 0);
993 }
994 //MUST call the old frame window proc!
995 goto RunDefFrameWndProc;
996 }
997
998 if(pswp->fl & (SWP_MOVE | SWP_SIZE))
999 {
1000 if(win32wnd->isChild())
1001 {
1002 if(win32wnd->getParent()) {
1003 hParent = win32wnd->getParent()->getOS2WindowHandle();
1004 }
1005 else goto PosChangedEnd; //parent has just been destroyed
1006 }
1007 }
1008
1009
1010 if(win32wnd->getParent()) {
1011 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
1012 hwnd);
1013 }
1014 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), hwnd);
1015
1016 wp.hwnd = win32wnd->getWindowHandle();
1017 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1018 {
1019 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1020 dprintf2(("SWP_ZORDER: %x %x", pswp->hwndInsertBehind, (wndAfter) ? wndAfter->getWindowHandle() : 0));
1021 if(wndAfter) {
1022 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1023 RELEASE_WNDOBJ(wndAfter);
1024 }
1025 else wp.hwndInsertAfter = HWND_TOP_W;
1026 }
1027
1028 if(pswp->fl & SWP_SHOW) {
1029 WinShowWindow(win32wnd->getOS2WindowHandle(), 1);
1030 }
1031 else
1032 if(pswp->fl & SWP_HIDE) {
1033 WinShowWindow(win32wnd->getOS2WindowHandle(), 0);
1034 }
1035
1036 if(flAfp & AWP_ACTIVATE)
1037 {
1038 FrameSetFocus(hwnd);
1039 }
1040
1041#ifndef USE_CALCVALIDRECT
1042 if((pswp->fl & (SWP_MOVE | SWP_SIZE)))
1043 {
1044 //CB: todo: use result for WM_CALCVALIDRECTS
1045 //Get old client rectangle (for invalidation of frame window parts later on)
1046 //Use new window height to calculate the client area
1047 mapWin32ToOS2Rect(pswp->cy, win32wnd->getClientRectPtr(), (PRECTLOS2)&rect);
1048
1049 //Note: Also updates the new window rectangle
1050 win32wnd->MsgFormatFrame(&wp);
1051
1052 if(win32wnd->isOwnDC()) {
1053 setPageXForm(win32wnd, (pDCData)GpiQueryDCData(win32wnd->getOwnDC()));
1054 }
1055
1056 if(win32wnd->CanReceiveSizeMsgs())
1057 win32wnd->MsgPosChanged((LPARAM)&wp);
1058
1059 if((pswp->fl & SWP_SIZE) && ((pswp->cx != pswpOld->cx) || (pswp->cy != pswpOld->cy)))
1060 {
1061 //redraw the frame (to prevent unnecessary client updates)
1062 BOOL redrawAll = FALSE;
1063
1064 dprintf2(("WM_WINDOWPOSCHANGED: redraw frame"));
1065 if (win32wnd->getWindowClass())
1066 {
1067 DWORD dwStyle = win32wnd->getWindowClass()->getClassLongA(GCL_STYLE_W);
1068
1069 if ((dwStyle & CS_HREDRAW_W) && (pswp->cx != pswpOld->cx))
1070 redrawAll = TRUE;
1071 else
1072 if ((dwStyle & CS_VREDRAW_W) && (pswp->cy != pswpOld->cy))
1073 redrawAll = TRUE;
1074 }
1075 else redrawAll = TRUE;
1076
1077 if(win32wnd->IsMixMaxStateChanging()) {
1078 dprintf(("WM_CALCVALIDRECT: window changed min/max/restore state, invalidate entire window"));
1079 redrawAll = TRUE;
1080 }
1081
1082 if (redrawAll)
1083 {
1084 //CB: redraw all children for now
1085 // -> problems with update region if we don't do it
1086 // todo: rewrite whole handling
1087 WinInvalidateRect(hwnd,NULL,TRUE);
1088 }
1089 else
1090 {
1091 HPS hps = WinGetPS(hwnd);
1092 RECTL frame,client,arcl[4];
1093
1094 WinQueryWindowRect(hwnd,&frame);
1095
1096 //top
1097 arcl[0].xLeft = 0;
1098 arcl[0].xRight = frame.xRight;
1099 arcl[0].yBottom = rect.yTop;
1100 arcl[0].yTop = frame.yTop;
1101 //right
1102 arcl[1].xLeft = rect.xRight;
1103 arcl[1].xRight = frame.xRight;
1104 arcl[1].yBottom = 0;
1105 arcl[1].yTop = frame.yTop;
1106 //left
1107 arcl[2].xLeft = 0;
1108 arcl[2].xRight = rect.xLeft;
1109 arcl[2].yBottom = 0;
1110 arcl[2].yTop = frame.yTop;
1111 //bottom
1112 arcl[3].xLeft = 0;
1113 arcl[3].xRight = frame.xRight;
1114 arcl[3].yBottom = 0;
1115 arcl[3].yTop = rect.yBottom;
1116
1117 HRGN hrgn = GpiCreateRegion(hps,4,(PRECTL)&arcl);
1118
1119 WinInvalidateRegion(hwnd,hrgn,FALSE);
1120 GpiDestroyRegion(hps,hrgn);
1121 WinReleasePS(hps);
1122 }
1123 }
1124 }
1125 else
1126 {
1127#endif //USE_CALCVALIDRECT
1128 if(win32wnd->CanReceiveSizeMsgs())
1129 win32wnd->MsgPosChanged((LPARAM)&wp);
1130#ifndef USE_CALCVALIDRECT
1131 }
1132#endif
1133
1134PosChangedEnd:
1135 rc = (MRESULT)FALSE;
1136 break;
1137 }
1138
1139 case WM_CALCVALIDRECTS:
1140#ifdef USE_CALCVALIDRECT
1141 {
1142 PRECTL oldRect = (PRECTL)mp1, newRect = oldRect+1;
1143 PSWP pswp = (PSWP)mp2;
1144 SWP swpOld;
1145 WINDOWPOS wp;
1146 RECTL newClientRect, oldClientRect;
1147 ULONG nccalcret;
1148// UINT res = CVR_ALIGNLEFT | CVR_ALIGNTOP;
1149 UINT res = 0;
1150
1151 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
1152
1153 //Get old position info
1154 WinQueryWindowPos(hwnd, &swpOld);
1155
1156 if(win32wnd->getParent()) {
1157 OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, win32wnd->getParent()->getClientHeight(),
1158 win32wnd->getParent()->getClientRectPtr()->left,
1159 win32wnd->getParent()->getClientRectPtr()->top,
1160 hwnd);
1161 }
1162 else OSLibMapSWPtoWINDOWPOS(pswp, &wp, &swpOld, OSLibQueryScreenHeight(), 0, 0, hwnd);
1163
1164 wp.hwnd = win32wnd->getWindowHandle();
1165 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
1166 {
1167 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
1168 if(wndAfter) {
1169 wp.hwndInsertAfter = wndAfter->getWindowHandle();
1170 RELEASE_WNDOBJ(wndAfter);
1171 }
1172 else wp.hwndInsertAfter = HWND_TOP_W;
1173 }
1174
1175 //Get old client rectangle
1176 mapWin32ToOS2Rect(oldRect->yTop - oldRect->yBottom, win32wnd->getClientRectPtr(), (PRECTLOS2)&oldClientRect);
1177
1178 //Note: Also updates the new window rectangle
1179 nccalcret = win32wnd->MsgFormatFrame(&wp);
1180
1181 //Get new client rectangle
1182 mapWin32ToOS2Rect(pswp->cy, win32wnd->getClientRectPtr(), (PRECTLOS2)&newClientRect);
1183
1184 if(nccalcret == 0) {
1185 res = CVR_ALIGNTOP | CVR_ALIGNLEFT;
1186 }
1187 else {
1188 if(nccalcret & WVR_ALIGNTOP_W) {
1189 res |= CVR_ALIGNTOP;
1190 }
1191 else
1192 if(nccalcret & WVR_ALIGNBOTTOM_W) {
1193 res |= CVR_ALIGNBOTTOM;
1194 }
1195
1196 if(nccalcret & WVR_ALIGNLEFT_W) {
1197 res |= CVR_ALIGNLEFT;
1198 }
1199 else
1200 if(nccalcret & WVR_ALIGNRIGHT_W) {
1201 res |= CVR_ALIGNRIGHT;
1202 }
1203
1204 if(nccalcret & WVR_REDRAW_W) {//WVR_REDRAW_W = (WVR_HREDRAW | WVR_VREDRAW)
1205 res |= CVR_REDRAW;
1206 }
1207 else
1208 if(nccalcret & WVR_VALIDRECTS_W) {
1209 //TODO:
1210 //res = 0;
1211 }
1212 }
1213 if(win32wnd->IsMixMaxStateChanging()) {
1214 dprintf(("WM_CALCVALIDRECT: window changed min/max/restore state, invalidate entire window"));
1215 res |= CVR_REDRAW;
1216 }
1217 if(res == (CVR_ALIGNTOP|CVR_ALIGNLEFT)) {
1218 oldRect->xRight -= oldClientRect.xLeft;
1219 oldRect->yBottom += oldClientRect.yBottom;
1220 newRect->xRight -= newClientRect.xLeft;
1221 newRect->yBottom += newClientRect.yBottom;
1222 }
1223 rc = res;
1224 break;
1225 }
1226#else
1227 dprintf(("PMWINDOW: WM_CALCVALIDRECTS %x", win32wnd->getWindowHandle()));
1228 rc = (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
1229 break;
1230#endif
1231
1232 case WM_CALCFRAMERECT:
1233 dprintf(("PMFRAME:WM_CALCFRAMERECT %x", win32wnd->getWindowHandle()));
1234 rc = (MRESULT)TRUE;
1235 break;
1236
1237 case WM_QUERYCTLTYPE:
1238 // This is a frame window
1239 dprintf(("PMFRAME:WM_QUERYCTLTYPE %x", win32wnd->getWindowHandle()));
1240 rc = (MRESULT)CCT_FRAME;
1241 break;
1242
1243#ifdef DEBUG
1244 case WM_QUERYFOCUSCHAIN:
1245 dprintf2(("PMFRAME:WM_QUERYFOCUSCHAIN %x fsCmd %x parent %x", win32wnd->getWindowHandle(), SHORT1FROMMP(mp1), (mp2) ? OS2ToWin32Handle((DWORD)mp2) : 0));
1246
1247 RestoreOS2TIB();
1248 rc = pfnFrameWndProc(hwnd, msg, mp1, mp2);
1249 SetWin32TIB();
1250 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));
1251 break;
1252// goto RunDefFrameWndProc;
1253#endif
1254
1255#ifdef DEBUG
1256 case WM_FOCUSCHANGE:
1257 {
1258 HWND hwndFocus = (HWND)mp1;
1259 HWND hwndLoseFocus, hwndGainFocus;
1260 USHORT usSetFocus = SHORT1FROMMP(mp2);
1261 USHORT fsFocusChange = SHORT2FROMMP(mp2);
1262
1263 dprintf(("PMFRAME:WM_FOCUSCHANGE %x %x (%x) %x %x", win32wnd->getWindowHandle(), OS2ToWin32Handle(hwndFocus), hwndFocus, usSetFocus, fsFocusChange));
1264 goto RunDefFrameWndProc;
1265 }
1266
1267 case WM_SETFOCUS:
1268 {
1269 dprintf(("PMFRAME: WM_SETFOCUS %x %x", win32wnd->getWindowHandle(), hwnd));
1270 goto RunDefFrameWndProc;
1271 }
1272#endif
1273
1274 case WM_ACTIVATE:
1275 {
1276 HWND hwndTitle;
1277 USHORT flags = WinQueryWindowUShort(hwnd,QWS_FLAGS);
1278
1279 dprintf(("PMFRAME: WM_ACTIVATE %x %x %x", win32wnd->getWindowHandle(), mp1, OS2ToWin32Handle((DWORD)mp2)));
1280 if (win32wnd->IsWindowCreated())
1281 {
1282 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
1283 if(fOS2Look) {
1284 dprintf(("TBM_QUERYHILITE returned %d", WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_QUERYHILITE, 0, 0)));
1285 WinSendDlgItemMsg(hwnd, FID_TITLEBAR, TBM_SETHILITE, mp1, 0);
1286 }
1287 WinSendDlgItemMsg(hwnd, FID_CLIENT, WM_ACTIVATE, mp1, mp2);
1288
1289 //CB: show owner behind the dialog
1290 if (win32wnd->IsModalDialog())
1291 {
1292 if(win32wnd->getOwner()) {
1293 Win32BaseWindow *topOwner = Win32BaseWindow::GetWindowFromHandle(win32wnd->getOwner()->GetTopParent());
1294
1295 if (topOwner) {
1296 WinSetWindowPos(topOwner->getOS2FrameWindowHandle(),hwnd,0,0,0,0,SWP_ZORDER);
1297 RELEASE_WNDOBJ(topOwner);
1298 }
1299 }
1300 }
1301 }
1302 else
1303 {
1304 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
1305 }
1306 rc = 0;
1307 break;
1308 }
1309
1310 case WM_ENABLE:
1311 dprintf(("PMFRAME: WM_ENABLE %x", hwnd));
1312 win32wnd->MsgEnable(SHORT1FROMMP(mp1));
1313 break;
1314
1315 case WM_SHOW:
1316 dprintf(("PMFRAME: WM_SHOW %x %d", hwnd, mp1));
1317 //show client window
1318 WinShowWindow(win32wnd->getOS2WindowHandle(), (BOOL)mp1);
1319 break;
1320
1321 case WM_QUERYTRACKINFO:
1322 {
1323 PTRACKINFO trackInfo = (PTRACKINFO)mp2;
1324
1325 dprintf(("PMFRAME:WM_QUERYTRACKINFO %x", win32wnd->getWindowHandle()));
1326 trackInfo->cxBorder = 4;
1327 trackInfo->cyBorder = 4;
1328 win32wnd->AdjustTrackInfo((PPOINT)&trackInfo->ptlMinTrackSize,(PPOINT)&trackInfo->ptlMaxTrackSize);
1329 rc = (MRESULT)TRUE;
1330 break;
1331 }
1332
1333 case WM_QUERYBORDERSIZE:
1334 {
1335 PWPOINT size = (PWPOINT)mp1;
1336
1337 dprintf(("PMFRAME:WM_QUERYBORDERSIZE %x", win32wnd->getWindowHandle()));
1338
1339 size->x = 0;
1340 size->y = 0;
1341 rc = (MRESULT)TRUE;
1342 break;
1343 }
1344
1345#ifdef DEBUG
1346 case WM_QUERYFRAMEINFO:
1347 dprintf(("PMFRAME:WM_QUERYFRAMEINFO %x", win32wnd->getWindowHandle()));
1348 goto RunDefFrameWndProc;
1349#endif
1350
1351 case WM_FORMATFRAME:
1352 dprintf(("PMFRAME:WM_FORMATFRAME %x", win32wnd->getWindowHandle()));
1353 break;
1354
1355#ifdef DEBUG
1356 case WM_ADJUSTFRAMEPOS:
1357 {
1358 PSWP pswp = (PSWP)mp1;
1359
1360 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));
1361 goto RunDefFrameWndProc;
1362 }
1363
1364 case WM_OWNERPOSCHANGE:
1365 {
1366 PSWP pswp = (PSWP)mp1;
1367
1368 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));
1369 goto RunDefFrameWndProc;
1370 }
1371#endif
1372
1373 case WM_MINMAXFRAME:
1374 {
1375 PSWP swp = (PSWP)mp1;
1376
1377 if (!win32wnd->IsWindowCreated()) goto RunDefWndProc;
1378
1379 dprintf(("PMFRAME:WM_MINMAXFRAME %x",hwnd));
1380 if ((swp->fl & SWP_MAXIMIZE) == SWP_MAXIMIZE)
1381 {
1382 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MINIMIZE_W) | WS_MAXIMIZE_W);
1383
1384 RECT rect;
1385
1386 rect.left = rect.top = rect.right = rect.bottom = 0;
1387 win32wnd->AdjustMaximizedRect(&rect);
1388 swp->x += rect.left;
1389 swp->cx += rect.right-rect.left;
1390 swp->y -= rect.bottom;
1391 swp->cy += rect.bottom-rect.top;
1392 }
1393 else
1394 if ((swp->fl & SWP_MINIMIZE) == SWP_MINIMIZE)
1395 {
1396 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MAXIMIZE_W) | WS_MINIMIZE_W);
1397 }
1398 else
1399 if ((swp->fl & SWP_RESTORE) == SWP_RESTORE)
1400 {
1401 win32wnd->setStyle(win32wnd->getStyle() & ~(WS_MINIMIZE_W | WS_MAXIMIZE_W));
1402 }
1403 goto RunDefWndProc;
1404 }
1405
1406#ifdef DEBUG
1407 case WM_UPDATEFRAME:
1408 dprintf(("PMFRAME:WM_UPDATEFRAME %x", win32wnd->getWindowHandle()));
1409 goto RunDefFrameWndProc;
1410#endif
1411
1412 case WM_TRACKFRAME:
1413 dprintf(("PMFRAME: WM_TRACKFRAME %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
1414 if(fOS2Look) {//sent by titlebar control
1415#ifdef CUSTOM_TRACKFRAME
1416 Frame_SysCommandSizeMove(win32wnd, SC_MOVE_W+HTCAPTION_W);
1417#else
1418 FrameTrackFrame(win32wnd, TF_MOVE);
1419#endif
1420 }
1421 rc = 0;
1422 break;
1423
1424 case WM_SYSCOMMAND:
1425 dprintf(("PMFRAME: WM_SYSCOMMAND %x %x %x", win32wnd->getWindowHandle(), mp1, mp2));
1426 if(win32wnd->getWindowHandle() != pWinMsg->hwnd) {
1427 RELEASE_WNDOBJ(win32wnd);
1428 win32wnd = Win32BaseWindow::GetWindowFromHandle(pWinMsg->hwnd);
1429 }
1430 if(win32wnd)
1431 win32wnd->DispatchMsgA(pWinMsg);
1432 break;
1433
1434#ifdef DEBUG
1435 case WM_DDE_INITIATE:
1436 case WM_DDE_INITIATEACK:
1437 case WM_DDE_REQUEST:
1438 case WM_DDE_ACK:
1439 case WM_DDE_DATA:
1440 case WM_DDE_ADVISE:
1441 case WM_DDE_UNADVISE:
1442 case WM_DDE_POKE:
1443 case WM_DDE_EXECUTE:
1444 case WM_DDE_TERMINATE:
1445 dprintf(("PMFRAME: WM_DDE %x %x", msg, win32wnd->getWindowHandle()));
1446 break;
1447#endif
1448
1449 default:
1450 goto RunDefFrameWndProc;
1451 }
1452 RestoreOS2TIB();
1453 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1454 return (MRESULT)rc;
1455
1456RunDefFrameWndProc:
1457 dprintf2(("RunDefFrameWndProc"));
1458 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1459 RestoreOS2TIB();
1460 return pfnFrameWndProc(hwnd, msg, mp1, mp2);
1461
1462RunDefWndProc:
1463 dprintf2(("RunDefWndProc"));
1464 if(win32wnd) RELEASE_WNDOBJ(win32wnd);
1465 RestoreOS2TIB();
1466 //calling WinDefWindowProc here breaks Opera hotlist window (WM_ADJUSTWINDOWPOS)
1467// return pfnFrameWndProc(hwnd, msg, mp1, mp2);
1468 return WinDefWindowProc( hwnd, msg, mp1, mp2 );
1469}
1470//******************************************************************************
1471//******************************************************************************
1472void FrameSetFocus(HWND hwnd)
1473{
1474 HWND hwndFocusSave = WinQueryWindowULong(hwnd, QWL_HWNDFOCUSSAVE);
1475 if(!WinIsWindow(hab, hwndFocusSave)) {
1476 hwndFocusSave = WinWindowFromID(hwnd, FID_CLIENT);
1477 WinSetWindowULong(hwnd, QWL_HWNDFOCUSSAVE, hwndFocusSave);
1478 }
1479 dprintf(("FrameSetFocus: hwndFocusSave %x %x", OS2ToWin32Handle(hwndFocusSave), hwndFocusSave));
1480 WinSetFocus(HWND_DESKTOP, hwndFocusSave);
1481
1482 ULONG ulFrameFlags = WinQueryWindowUShort(hwnd, QWS_FLAGS);
1483 ulFrameFlags &= ~FF_NOACTIVATESWP;
1484 WinSetWindowUShort(hwnd, QWS_FLAGS, ulFrameFlags);
1485}
1486#ifndef CUSTOM_TRACKFRAME
1487//******************************************************************************
1488//TODO: Quickly moving a window two times doesn't force a repaint (1st time)
1489//
1490//
1491BOOL (APIENTRY *WinTrackWindow)(HWND hwndTrack, PTRACKINFO pti) = NULL;
1492//
1493//******************************************************************************
1494VOID FrameTrackFrame(Win32BaseWindow *win32wnd,DWORD flags)
1495{
1496 TRACKINFO track;
1497 RECTL rcl;
1498 PRECT pWindowRect, pClientRect;
1499 HWND hwndTracking;
1500 LONG parentHeight, parentWidth;
1501 static BOOL fInit = FALSE;
1502 APIRET rc;
1503 BOOL ret;
1504 HWND hwnd = win32wnd->getWindowHandle();
1505
1506 if(!fInit) {
1507 HMODULE hModule;
1508 char buf[CCHMAXPATH];
1509 rc = DosLoadModule(buf, sizeof(buf), "PMMERGE", &hModule);
1510 rc = DosQueryProcAddr(hModule, 5466, NULL, (PFN *)&WinTrackWindow);
1511 if(rc) WinTrackWindow = NULL;
1512 fInit = TRUE;
1513 }
1514 dprintf(("FrameTrackFrame: %x %x", hwnd, flags));
1515 track.cxBorder = 4;
1516 track.cyBorder = 4; /* 4 pel wide lines used for rectangle */
1517 track.cxGrid = 1;
1518 track.cyGrid = 1; /* smooth tracking with mouse */
1519 track.cxKeyboard = 8;
1520 track.cyKeyboard = 8; /* faster tracking using cursor keys */
1521
1522 pWindowRect = win32wnd->getWindowRect();
1523 if(win32wnd->getParent()) {
1524 parentHeight = win32wnd->getParent()->getClientHeight();
1525 parentWidth = win32wnd->getParent()->getClientWidth();
1526 hwndTracking = win32wnd->getParent()->getOS2WindowHandle();
1527 }
1528 else {
1529 parentHeight = OSLibQueryScreenHeight();
1530 parentWidth = OSLibQueryScreenWidth();
1531 hwndTracking = HWND_DESKTOP;
1532 }
1533
1534 mapWin32ToOS2Rect(parentHeight, pWindowRect, (PRECTLOS2)&track.rclTrack);
1535 rcl = track.rclTrack;
1536 WinQueryWindowRect(hwndTracking, &track.rclBoundary);
1537
1538 track.ptlMinTrackSize.x = 10;
1539 track.ptlMinTrackSize.y = 10; /* set smallest allowed size of rectangle */
1540 track.ptlMaxTrackSize.x = parentWidth;
1541 track.ptlMaxTrackSize.y = parentHeight; /* set largest allowed size of rectangle */
1542
1543 win32wnd->AdjustTrackInfo((PPOINT)&track.ptlMinTrackSize, (PPOINT)&track.ptlMaxTrackSize);
1544
1545 track.fs = flags;
1546
1547 BOOL fDynamicDrag = WinQuerySysValue(HWND_DESKTOP, SVOS_DYNAMICDRAG);
1548
1549 //TODO: send WM_QUERYDRAGICON to fetch icon (not really necessary)
1550
1551 SendMessageA( hwnd, WM_ENTERSIZEMOVE_W, 0, 0);
1552
1553 SEL sel = RestoreOS2FS();
1554 if(fDynamicDrag && WinTrackWindow) {
1555 ret = WinTrackWindow(win32wnd->getOS2FrameWindowHandle(), &track);
1556 }
1557 else ret = WinTrackRect(hwndTracking, NULL, &track);
1558 SetFS(sel);
1559
1560//TODO:
1561// if (HOOK_CallHooksA( WH_CBT_W, HCBT_MOVESIZE_W, (WPARAM)hwnd, (LPARAM)&sizingRect )) moved = FALSE;
1562
1563 SendMessageA( hwnd, WM_EXITSIZEMOVE_W, 0, 0 );
1564 SendMessageA( hwnd, WM_SETVISIBLE_W, !IsIconic(hwnd), 0L);
1565
1566 if(ret) {
1567 /* if successful copy final position back */
1568 if(!WinEqualRect(0, &rcl, &track.rclTrack)) {
1569 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));
1570 if(flags == TF_MOVE) {
1571 WinSetWindowPos(win32wnd->getOS2FrameWindowHandle(),
1572 0, track.rclTrack.xLeft, track.rclTrack.yBottom,
1573 0, 0, SWP_MOVE);
1574 }
1575 else {
1576 WinSetWindowPos(win32wnd->getOS2FrameWindowHandle(),
1577 0, track.rclTrack.xLeft, track.rclTrack.yBottom,
1578 track.rclTrack.xRight - track.rclTrack.xLeft,
1579 track.rclTrack.yTop - track.rclTrack.yBottom,
1580 SWP_SIZE|SWP_MOVE);
1581 }
1582 }
1583 return;
1584 }
1585 return;
1586}
1587#endif
1588//******************************************************************************
1589//******************************************************************************
1590void FrameReplaceMenuItem(HWND hwndMenu, ULONG nIndex, ULONG idOld, ULONG idNew,
1591 HBITMAP hbmNew)
1592{
1593 MENUITEM mi;
1594
1595 if (!hwndMenu)
1596 return;
1597
1598 WinEnableWindowUpdate(hwndMenu, FALSE);
1599
1600 if (WinSendMsg(hwndMenu, MM_QUERYITEM, MPFROM2SHORT(idOld, TRUE), MPFROMP(&mi)))
1601 {
1602 WinSendMsg(hwndMenu, MM_REMOVEITEM, (MPARAM)idOld, 0);
1603 mi.afStyle = MIS_BITMAP | MIS_SYSCOMMAND;
1604 mi.afAttribute = 0;
1605 mi.hwndSubMenu = 0;
1606 mi.id = idNew;
1607 mi.hItem = (ULONG)hbmNew;
1608 WinSendMsg(hwndMenu, MM_INSERTITEM, (MPARAM)&mi, 0);
1609 }
1610 WinEnableWindowUpdate(hwndMenu, TRUE);
1611
1612 WinInvalidateRect(hwndMenu, NULL, TRUE);
1613}
1614//******************************************************************************
1615//******************************************************************************
Note: See TracBrowser for help on using the repository browser.