source: trunk/src/user32/pmframe.cpp@ 2483

Last change on this file since 2483 was 2483, checked in by cbratschi, 26 years ago

WM_CONTEXTMENU, sysmenu changes

File size: 15.4 KB
Line 
1/* $Id: pmframe.cpp,v 1.38 2000-01-20 16:48:55 cbratschi Exp $ */
2/*
3 * Win32 Frame Managment Code for OS/2
4 *
5 * Copyright 1999 by Christoph Bratschi (cbratschi@datacomm.ch)
6 *
7 *
8 * Project Odin Software License can be found in LICENSE.TXT
9 *
10 */
11
12#define INCL_WIN
13#define INCL_GPI
14
15#include <os2.h> /* PM header file */
16#include <os2wrap.h>
17#include <stdlib.h>
18#include <string.h>
19#include "win32type.h"
20#include <misc.h>
21#include <win32wbase.h>
22#include "wprocess.h"
23#include "pmframe.h"
24#include "oslibutil.h"
25#include "oslibwin.h"
26#include "caret.h"
27#include "oslibmsg.h"
28
29#define PMFRAMELOG
30
31//******************************************************************************
32//******************************************************************************
33VOID FrameTrackFrame(Win32BaseWindow *win32wnd,DWORD flags)
34{
35 WinSendMsg(win32wnd->getOS2FrameWindowHandle(),WM_TRACKFRAME,(MPARAM)flags,(MPARAM)0);
36}
37//******************************************************************************
38//******************************************************************************
39VOID FrameUpdateChildPositions(HWND hwnd)
40{
41 HENUM henum;
42 HWND hchild;
43 RECTL rectl;
44
45 henum = WinBeginEnumWindows(hwnd);
46 while ((hchild = WinGetNextWindow(henum)) != NULLHANDLE)
47 {
48 Win32BaseWindow *child = Win32BaseWindow::GetWindowFromOS2FrameHandle(hchild);
49
50 if (child)
51 {
52 WinQueryWindowRect(child->getOS2FrameWindowHandle(),&rectl);
53 mapOS2ToWin32Rect(child->getOS2FrameWindowHandle(),OSLIB_HWND_DESKTOP,(PRECTLOS2)&rectl,child->getWindowRect());
54 FrameUpdateChildPositions(child->getOS2WindowHandle());
55 }
56 }
57 WinEndEnumWindows(henum);
58}
59//******************************************************************************
60//Win32 frame message handler
61//******************************************************************************
62MRESULT EXPENTRY Win32FrameProc(HWND hwnd,ULONG msg,MPARAM mp1,MPARAM mp2)
63{
64 Win32BaseWindow *win32wnd;
65 PFNWP OldFrameProc;
66 MRESULT rc;
67 THDB *thdb;
68 MSG *pWinMsg,winMsg;
69
70 SetWin32TIB();
71
72 thdb = GetThreadTHDB();
73 win32wnd = Win32BaseWindow::GetWindowFromOS2FrameHandle(hwnd);
74
75 if (!thdb || (win32wnd == NULL) || !win32wnd->getOldFrameProc())
76 {
77 dprintf(("Invalid win32wnd pointer for frame %x!!", hwnd));
78 goto RunDefWndProc;
79 }
80
81 if((thdb->msgstate & 1) == 0)
82 {//message that was sent directly to our window proc handler; translate it here
83 QMSG qmsg;
84
85 qmsg.msg = msg;
86 qmsg.hwnd = hwnd;
87 qmsg.mp1 = mp1;
88 qmsg.mp2 = mp2;
89 qmsg.time = WinQueryMsgTime(thdb->hab);
90 WinQueryMsgPos(thdb->hab, &qmsg.ptl);
91 qmsg.reserved = 0;
92
93 if(OS2ToWinMsgTranslate((PVOID)thdb, &qmsg, &winMsg, FALSE, MSG_REMOVE) == FALSE)
94 {//message was not translated
95 memset(&winMsg, 0, sizeof(MSG));
96 }
97 pWinMsg = &winMsg;
98 }
99 else {
100 pWinMsg = &thdb->msg;
101 thdb->msgstate++;
102 }
103
104 OldFrameProc = (PFNWP)win32wnd->getOldFrameProc();
105
106 switch(msg)
107 {
108 case WM_FORMATFRAME:
109 break;
110
111 case WM_MINMAXFRAME:
112 {
113 PSWP swp = (PSWP)mp1;
114
115 if (!win32wnd->IsWindowCreated()) goto RunDefFrameProc;
116 dprintf(("PMFRAME: WM_MINMAXFRAME %x",hwnd));
117 if ((swp->fl & SWP_MAXIMIZE) == SWP_MAXIMIZE)
118 {
119 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MINIMIZE_W) | WS_MAXIMIZE_W);
120
121 RECT rect;
122
123 rect.left = rect.top = rect.right = rect.bottom = 0;
124 win32wnd->AdjustMaximizedRect(&rect);
125 swp->x += rect.left;
126 swp->cx += rect.right-rect.left;
127 swp->y -= rect.bottom;
128 swp->cy += rect.bottom-rect.top;
129 }
130 else if ((swp->fl & SWP_MINIMIZE) == SWP_MINIMIZE)
131 {
132 win32wnd->setStyle((win32wnd->getStyle() & ~WS_MAXIMIZE_W) | WS_MINIMIZE_W);
133 }
134 else if ((swp->fl & SWP_RESTORE) == SWP_RESTORE)
135 {
136 win32wnd->setStyle(win32wnd->getStyle() & ~(WS_MINIMIZE_W | WS_MAXIMIZE_W));
137 }
138 goto RunDefFrameProc;
139 }
140
141 case WM_QUERYTRACKINFO:
142 {
143 //CB: todo: use minmaxinfo
144 goto RunDefFrameProc;
145 }
146
147 case WM_QUERYBORDERSIZE:
148 {
149 PWPOINT size = (PWPOINT)mp1;
150
151 size->x = 0;
152 size->y = 0;
153 RestoreOS2TIB();
154 return (MRESULT)TRUE;
155 }
156
157 case WM_BUTTON1DOWN:
158 case WM_BUTTON1UP:
159 case WM_BUTTON1DBLCLK:
160 case WM_BUTTON2DOWN:
161 case WM_BUTTON2UP:
162 case WM_BUTTON2DBLCLK:
163 case WM_BUTTON3DOWN:
164 case WM_BUTTON3UP:
165 case WM_BUTTON3DBLCLK:
166 {
167 if (win32wnd->IsWindowCreated())
168 {
169 win32wnd->MsgButton(pWinMsg);
170 RestoreOS2TIB();
171 }
172 return (MRESULT)TRUE;
173 }
174
175 case WM_BUTTON2MOTIONSTART:
176 case WM_BUTTON2MOTIONEND:
177 case WM_BUTTON2CLICK:
178 case WM_BUTTON1MOTIONSTART:
179 case WM_BUTTON1MOTIONEND:
180 case WM_BUTTON1CLICK:
181 case WM_BUTTON3MOTIONSTART:
182 case WM_BUTTON3MOTIONEND:
183 case WM_BUTTON3CLICK:
184 RestoreOS2TIB();
185 return (MRESULT)TRUE;
186
187 case WM_MOUSEMOVE:
188 {
189 //OS/2 Window coordinates -> Win32 Window coordinates
190 if (win32wnd->IsWindowCreated())
191 win32wnd->MsgMouseMove(pWinMsg);
192 RestoreOS2TIB();
193 return (MRESULT)TRUE;
194 }
195
196 case WM_PAINT:
197 {
198 dprintf(("PMFRAME: WM_PAINT"));
199 if (win32wnd->getStyle() & WS_MINIMIZE_W)
200 goto RunDefFrameProc;
201 if (win32wnd->IsWindowCreated())
202 win32wnd->MsgNCPaint();
203 goto RunDefWndProc;
204 }
205
206 case WM_SIZE:
207 dprintf(("PMFRAME: WM_SIZE"));
208 goto RunDefFrameProc;
209
210 case WM_ADJUSTWINDOWPOS:
211 {
212 PSWP pswp = (PSWP)mp1;
213 SWP swpOld;
214 WINDOWPOS wp;
215 HWND hParent = NULLHANDLE, hwndAfter;
216
217 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));
218
219 //CB: show dialog in front of owner
220 if (win32wnd->IsModalDialogOwner())
221 {
222 pswp->fl |= SWP_ZORDER;
223 pswp->hwndInsertBehind = win32wnd->getOS2HwndModalDialog();
224 if (pswp->fl & SWP_ACTIVATE)
225 {
226 pswp->fl &= ~SWP_ACTIVATE;
227 WinSetWindowPos(win32wnd->getOS2HwndModalDialog(),0,0,0,0,0,SWP_ACTIVATE);
228 }
229 }
230
231 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0)
232 goto RunDefFrameProc;
233
234 if(!win32wnd->CanReceiveSizeMsgs())
235 break;
236
237 WinQueryWindowPos(hwnd, &swpOld);
238 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
239 if (win32wnd->isChild()) {
240 if(win32wnd->getParent()) {
241 hParent = win32wnd->getParent()->getOS2WindowHandle();
242 }
243 else goto RunDefFrameProc;
244 }
245 }
246 hwndAfter = pswp->hwndInsertBehind;
247 OSLibMapSWPtoWINDOWPOSFrame(pswp, &wp, &swpOld, hParent, hwnd);
248
249 wp.hwnd = win32wnd->getWindowHandle();
250 if ((pswp->fl & SWP_ZORDER) && (pswp->hwndInsertBehind > HWND_BOTTOM))
251 {
252 Win32BaseWindow *wndAfter = Win32BaseWindow::GetWindowFromOS2Handle(pswp->hwndInsertBehind);
253 if(wndAfter) wp.hwndInsertAfter = wndAfter->getWindowHandle();
254 }
255
256 //CB: problems with profmine titlebar tracking
257 if(win32wnd->MsgPosChanging((LPARAM)&wp) == 0)
258 {//app or default window handler changed wp
259 dprintf(("PMFRAME: WM_ADJUSTWINDOWPOS, app changed windowpos struct"));
260 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
261
262 OSLibMapWINDOWPOStoSWPFrame(&wp, pswp, &swpOld, hParent, hwnd);
263 dprintf(("%x (%d,%d), (%d,%d)", pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
264 pswp->fl |= SWP_NOADJUST;
265 pswp->hwndInsertBehind = hwndAfter;
266 pswp->hwnd = hwnd;
267
268 RestoreOS2TIB();
269 return (MRESULT)0xf;
270 }
271 goto RunDefFrameProc;
272 }
273
274 case WM_WINDOWPOSCHANGED:
275 {
276 PSWP pswp = (PSWP)mp1,pswpOld = pswp+1;
277 SWP swpOld = *(pswp + 1);
278 WINDOWPOS wp;
279 HWND hParent = NULLHANDLE;
280 RECTL rect;
281 SWP swpClient = {0};
282
283 dprintf(("PMFRAME: WM_WINDOWPOSCHANGED (%x) %x %x (%d,%d) (%d,%d)", mp2, win32wnd->getWindowHandle(), pswp->fl, pswp->x, pswp->y, pswp->cx, pswp->cy));
284
285 if ((pswp->fl & (SWP_SIZE | SWP_MOVE | SWP_ZORDER)) == 0)
286 {
287 goto RunDefFrameProc;
288 }
289
290 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
291 if (win32wnd->isChild()) {
292 if(win32wnd->getParent()) {
293 hParent = win32wnd->getParent()->getOS2WindowHandle();
294 }
295 else goto PosChangedEnd; //parent has just been destroyed
296 }
297 }
298
299 OSLibMapSWPtoWINDOWPOSFrame(pswp, &wp, &swpOld, hParent, hwnd);
300
301 if(pswp->fl & SWP_ACTIVATE)
302 {
303 WinSendMsg(hwnd, WM_ACTIVATE, (MPARAM)TRUE, (MPARAM)hwnd);
304 }
305
306 if((pswp->fl & (SWP_MOVE | SWP_SIZE)) && !(win32wnd->getStyle() & WS_MINIMIZE_W))
307 {
308 //Note: Also updates the new window rectangle
309 win32wnd->MsgFormatFrame(&wp);
310
311 //CB: todo: use result for WM_CALCVALIDRECTS
312 mapWin32ToOS2Rect(win32wnd->getOS2FrameWindowHandle(), win32wnd->getClientRectPtr(), (PRECTLOS2)&rect);
313
314 swpClient.hwnd = win32wnd->getOS2WindowHandle();
315 swpClient.hwndInsertBehind = 0;
316 swpClient.x = rect.xLeft;
317 swpClient.y = rect.yBottom;
318 swpClient.cx = rect.xRight-rect.xLeft;
319 swpClient.cy = rect.yTop-rect.yBottom;
320 //TODO: Get rid of SWP_SHOW; needed for winhlp32 button bar for now
321 swpClient.fl = (pswp->fl & ~SWP_ZORDER) | SWP_MOVE | SWP_SHOW;
322 WinSetMultWindowPos(thdb->hab, &swpClient, 1);
323
324 //update child positions: rectWindow is in window coordinates
325 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
326 FrameUpdateChildPositions(win32wnd->getOS2WindowHandle());
327 }
328
329 if(win32wnd->CanReceiveSizeMsgs())
330 win32wnd->MsgPosChanged((LPARAM)&wp);
331
332 if ((pswp->fl & SWP_SIZE) && ((pswp->cx != pswpOld->cx) || (pswp->cy != pswpOld->cy)))
333 {
334 //redraw the frame (to prevent unnecessary client updates)
335 BOOL redrawAll = FALSE;
336
337 if (win32wnd->getWindowClass())
338 {
339 DWORD dwStyle = win32wnd->getWindowClass()->getClassLongA(GCL_STYLE_W);
340
341 if ((dwStyle & CS_HREDRAW_W) && (pswp->cx != pswpOld->cx))
342 redrawAll = TRUE;
343 else if ((dwStyle & CS_VREDRAW_W) && (pswp->cy != pswpOld->cy))
344 redrawAll = TRUE;
345 } else redrawAll = TRUE;
346
347 if (redrawAll)
348 {
349 WinInvalidateRect(hwnd,NULL,TRUE);
350 }
351 else
352 {
353 HPS hps = WinGetPS(hwnd);
354 RECTL frame,client,arcl[4];
355
356 WinQueryWindowRect(hwnd,&frame);
357 //top
358 arcl[0].xLeft = 0;
359 arcl[0].xRight = frame.xRight;
360 arcl[0].yBottom = rect.yTop;
361 arcl[0].yTop = frame.yTop;
362 //right
363 arcl[1].xLeft = rect.xRight;
364 arcl[1].xRight = frame.xRight;
365 arcl[1].yBottom = 0;
366 arcl[1].yTop = frame.yTop;
367 //left
368 arcl[2].xLeft = 0;
369 arcl[2].xRight = rect.xLeft;
370 arcl[2].yBottom = 0;
371 arcl[2].yTop = frame.yTop;
372 //bottom
373 arcl[3].xLeft = 0;
374 arcl[3].xRight = frame.xRight;
375 arcl[3].yBottom = 0;
376 arcl[3].yTop = rect.yBottom;
377
378 HRGN hrgn = GpiCreateRegion(hps,3,(PRECTL)&arcl);
379
380 WinInvalidateRegion(hwnd,hrgn,FALSE);
381 GpiDestroyRegion(hps,hrgn);
382 WinReleasePS(hps);
383 }
384 }
385 }
386 else
387 {
388 //update child positions: rectWindow is in window coordinates
389 if(pswp->fl & (SWP_MOVE | SWP_SIZE)) {
390 FrameUpdateChildPositions(win32wnd->getOS2WindowHandle());
391 }
392
393 if(win32wnd->CanReceiveSizeMsgs())
394 win32wnd->MsgPosChanged((LPARAM)&wp);
395 }
396
397PosChangedEnd:
398 RestoreOS2TIB();
399 return (MRESULT)FALSE;
400 }
401
402 case WM_ERASEBACKGROUND:
403 break;
404
405 case WM_CALCVALIDRECTS:
406 {
407 //don't redraw here or PM redraw the whole frame (done in WM_WINDOWPOSCHANGED)
408 RestoreOS2TIB();
409 return (MRESULT)(CVR_ALIGNLEFT | CVR_ALIGNTOP);
410 }
411
412 case WM_ACTIVATE:
413 {
414 HWND hwndTitle;
415 USHORT flags = WinQueryWindowUShort(hwnd,QWS_FLAGS);
416
417 dprintf(("PMFRAME: WM_ACTIVATE %x %x", hwnd, mp2));
418 if (win32wnd->IsWindowCreated())
419 {
420 WinSendMsg(WinWindowFromID(hwnd,FID_CLIENT),WM_ACTIVATE,mp1,mp2);
421 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
422
423 //CB: show owner behind the dialog
424 if (win32wnd->IsModalDialog())
425 {
426 Win32BaseWindow *topOwner = win32wnd->getOwner()->GetTopParent();
427
428 if (topOwner) WinSetWindowPos(topOwner->getOS2FrameWindowHandle(),hwnd,0,0,0,0,SWP_ZORDER);
429 }
430 }
431 else
432 {
433 WinSetWindowUShort(hwnd,QWS_FLAGS,mp1 ? (flags | FF_ACTIVE):(flags & ~FF_ACTIVE));
434 }
435 if(win32wnd->IsWindowCreated())
436 win32wnd->DispatchMsgA(pWinMsg);
437
438 RestoreOS2TIB();
439 return 0;
440 }
441
442 case WM_DESTROY:
443 dprintf(("PMFRAME: WM_DESTROY %x",hwnd));
444 WinSubclassWindow(hwnd,OldFrameProc);
445 win32wnd->setOldFrameProc(NULL);
446 goto RunDefFrameProc;
447
448 default:
449 RestoreOS2TIB();
450 return OldFrameProc(hwnd,msg,mp1,mp2);
451 }
452
453 RestoreOS2TIB();
454 return (MRESULT)FALSE;
455
456RunDefFrameProc:
457 RestoreOS2TIB();
458 return OldFrameProc(hwnd,msg,mp1,mp2);
459
460RunDefWndProc:
461 RestoreOS2TIB();
462 return WinDefWindowProc(hwnd,msg,mp1,mp2);
463}
464//******************************************************************************
465//******************************************************************************
466PVOID FrameSubclassFrameWindow(Win32BaseWindow *win32wnd)
467{
468 return WinSubclassWindow(win32wnd->getOS2FrameWindowHandle(),PFNWP(Win32FrameProc));
469}
470//******************************************************************************
471//******************************************************************************
472VOID FrameUpdateClient(Win32BaseWindow *win32wnd)
473{
474 RECT rectOld, rectNew;
475 RECTL rect;
476 SWP swpClient = {0};
477
478 rectOld = *win32wnd->getClientRectPtr();
479 win32wnd->MsgFormatFrame(NULL);
480 rectNew = *win32wnd->getClientRectPtr();
481 if(WinEqualRect(0, (PRECTL)&rectOld, (PRECTL)&rectNew) == 1) {
482 WinInvalidateRect(win32wnd->getOS2FrameWindowHandle(), NULL, FALSE);
483 return;
484 }
485 //CB: todo: use result for WM_CALCVALIDRECTS
486 mapWin32ToOS2Rect(win32wnd->getOS2FrameWindowHandle(), win32wnd->getClientRectPtr(), (PRECTLOS2)&rect);
487
488
489 swpClient.hwnd = win32wnd->getOS2WindowHandle();
490 swpClient.hwndInsertBehind = 0;
491 swpClient.x = rect.xLeft;
492 swpClient.y = rect.yBottom;
493 swpClient.cx = rect.xRight-rect.xLeft;
494 swpClient.cy = rect.yTop-rect.yBottom;
495 swpClient.fl = SWP_MOVE | SWP_SIZE;
496 WinSetMultWindowPos(GetThreadHAB(), &swpClient, 1);
497}
498//******************************************************************************
499//******************************************************************************
Note: See TracBrowser for help on using the repository browser.