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

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

WM_ACTIVATEAPP fix

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