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

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

.

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