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

Last change on this file since 7216 was 7216, checked in by phaller, 24 years ago

AltGr fix

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