source: trunk/src/user32/win32wbasepos.cpp@ 2013

Last change on this file since 2013 was 1490, checked in by sandervl, 26 years ago

misc changes

File size: 15.1 KB
Line 
1/* $Id: win32wbasepos.cpp,v 1.6 1999-10-28 12:00:35 sandervl Exp $ */
2/*
3 * Win32 Window Base Class for OS/2 (nonclient/position methods)
4 *
5 * Copyright 1998-1999 Sander van Leeuwen (sandervl@xs4all.nl)
6 * Copyright 1999 Daniela Engert (dani@ngrt.de)
7 *
8 * Parts based on Wine Windows code (windows\win.c, windows\nonclient.c)
9 *
10 * Copyright 1993, 1994 Alexandre Julliard
11 *
12 * TODO: Not thread/process safe
13 *
14 * Wine code based on build 990815
15 *
16 * Project Odin Software License can be found in LICENSE.TXT
17 *
18 */
19#include <os2win.h>
20#include <win.h>
21#include <stdlib.h>
22#include <string.h>
23#include <stdarg.h>
24#include <assert.h>
25#include <misc.h>
26#include <win32wbase.h>
27#include <winres.h>
28#include <spy.h>
29#include "wndmsg.h"
30#include "hooks.h"
31#include "oslibwin.h"
32#include "oslibutil.h"
33#include "oslibgdi.h"
34#include "oslibres.h"
35#include "oslibmenu.h"
36#include "oslibdos.h"
37#include "syscolor.h"
38#include "win32wndhandle.h"
39#include "dc.h"
40#include "pmframe.h"
41#include "win32wdesktop.h"
42
43 /* Some useful macros */
44#define HAS_DLGFRAME(style,exStyle) \
45 (((exStyle) & WS_EX_DLGMODALFRAME) || \
46 (((style) & WS_DLGFRAME) && !((style) & WS_THICKFRAME)))
47
48#define HAS_THICKFRAME(style,exStyle) \
49 (((style) & WS_THICKFRAME) && \
50 !((exStyle) & WS_EX_DLGMODALFRAME))
51
52#define HAS_THINFRAME(style) \
53 (((style) & WS_BORDER) || !((style) & (WS_CHILD | WS_POPUP)))
54
55#define HAS_BIGFRAME(style,exStyle) \
56 (((style) & (WS_THICKFRAME | WS_DLGFRAME)) || \
57 ((exStyle) & WS_EX_DLGMODALFRAME))
58
59#define HAS_ANYFRAME(style,exStyle) \
60 (((style) & (WS_THICKFRAME | WS_DLGFRAME | WS_BORDER)) || \
61 ((exStyle) & WS_EX_DLGMODALFRAME) || \
62 !((style) & (WS_CHILD | WS_POPUP)))
63
64#define HAS_3DFRAME(exStyle) \
65 ((exStyle & WS_EX_CLIENTEDGE) || (exStyle & WS_EX_STATICEDGE) || (exStyle & WS_EX_WINDOWEDGE))
66
67#define HAS_BORDER(style, exStyle) \
68 ((style & WS_BORDER) || HAS_THICKFRAME(style) || HAS_DLGFRAME(style,exStyle))
69
70#define IS_OVERLAPPED(style) \
71 !(style & (WS_CHILD | WS_POPUP))
72
73#define HAS_MENU() (!(getStyle() & WS_CHILD) && (GetMenu() != 0))
74
75#if 0
76/***********************************************************************
77 * WINPOS_MinMaximize
78 *
79 * Fill in lpRect and return additional flags to be used with SetWindowPos().
80 * This function assumes that 'cmd' is different from the current window
81 * state.
82 */
83UINT Win32BaseWindow::MinMaximize(UINT cmd, LPRECT lpRect )
84{
85 UINT swpFlags = 0;
86 POINT pt, size;
87 LPINTERNALPOS lpPos;
88
89 size.x = rectWindow.left; size.y = rectWindow.top;
90 lpPos = WINPOS_InitInternalPos( wndPtr, size, &rectWindow );
91
92 if (lpPos && !HOOK_CallHooks16(WH_CBT, HCBT_MINMAX, hwndSelf, cmd))
93 {
94 if( dwStyle & WS_MINIMIZE )
95 {
96 if( !SendMessageA(WM_QUERYOPEN, 0, 0L ) )
97 return (SWP_NOSIZE | SWP_NOMOVE);
98 swpFlags |= SWP_NOCOPYBITS;
99 }
100 switch( cmd )
101 {
102 case SW_MINIMIZE:
103 if( dwStyle & WS_MAXIMIZE)
104 {
105 flags |= WIN_RESTORE_MAX;
106 dwStyle &= ~WS_MAXIMIZE;
107 }
108 else
109 flags &= ~WIN_RESTORE_MAX;
110 dwStyle |= WS_MINIMIZE;
111
112#if 0
113 if( flags & WIN_NATIVE )
114 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, TRUE ) )
115 swpFlags |= MINMAX_NOSWP;
116#endif
117
118 lpPos->ptIconPos = WINPOS_FindIconPos( wndPtr, lpPos->ptIconPos );
119
120 SetRect(lpRect, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
121 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
122 swpFlags |= SWP_NOCOPYBITS;
123 break;
124
125 case SW_MAXIMIZE:
126 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL );
127
128 if( dwStyle & WS_MINIMIZE )
129 {
130 if( flags & WIN_NATIVE )
131 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
132 swpFlags |= MINMAX_NOSWP;
133
134 WINPOS_ShowIconTitle( wndPtr, FALSE );
135 dwStyle &= ~WS_MINIMIZE;
136 }
137 dwStyle |= WS_MAXIMIZE;
138
139 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
140 size.x, size.y );
141 break;
142
143 case SW_RESTORE:
144 if( dwStyle & WS_MINIMIZE )
145 {
146 if( flags & WIN_NATIVE )
147 if( pDriver->pSetHostAttr( wndPtr, HAK_ICONICSTATE, FALSE ) )
148 swpFlags |= MINMAX_NOSWP;
149
150 dwStyle &= ~WS_MINIMIZE;
151 WINPOS_ShowIconTitle( wndPtr, FALSE );
152
153 if( flags & WIN_RESTORE_MAX)
154 {
155 /* Restore to maximized position */
156 CONV_POINT16TO32( &lpPos->ptMaxPos, &pt );
157 WINPOS_GetMinMaxInfo( wndPtr, &size, &pt, NULL, NULL);
158 CONV_POINT32TO16( &pt, &lpPos->ptMaxPos );
159 dwStyle |= WS_MAXIMIZE;
160 SetRect16( lpRect, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y, size.x, size.y );
161 break;
162 }
163 }
164 else
165 if( !(dwStyle & WS_MAXIMIZE) ) return (UINT16)(-1);
166 else dwStyle &= ~WS_MAXIMIZE;
167
168 /* Restore to normal position */
169
170 *lpRect = lpPos->rectNormal;
171 lpRect->right -= lpRect->left;
172 lpRect->bottom -= lpRect->top;
173
174 break;
175 }
176 } else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
177 return swpFlags;
178}
179#endif
180/*******************************************************************
181 * GetMinMaxInfo
182 *
183 * Get the minimized and maximized information for a window.
184 */
185void Win32BaseWindow::GetMinMaxInfo(POINT *maxSize, POINT *maxPos,
186 POINT *minTrack, POINT *maxTrack )
187{
188 MINMAXINFO MinMax;
189 INT xinc, yinc;
190
191 /* Compute default values */
192
193 MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
194 MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
195 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
196 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
197 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
198 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
199
200 if (flags & WIN_MANAGED) xinc = yinc = 0;
201 else if (HAS_DLGFRAME( dwStyle, dwExStyle ))
202 {
203 xinc = GetSystemMetrics(SM_CXDLGFRAME);
204 yinc = GetSystemMetrics(SM_CYDLGFRAME);
205 }
206 else
207 {
208 xinc = yinc = 0;
209 if (HAS_THICKFRAME(dwStyle, dwExStyle))
210 {
211 xinc += GetSystemMetrics(SM_CXFRAME);
212 yinc += GetSystemMetrics(SM_CYFRAME);
213 }
214 if (dwStyle & WS_BORDER)
215 {
216 xinc += GetSystemMetrics(SM_CXBORDER);
217 yinc += GetSystemMetrics(SM_CYBORDER);
218 }
219 }
220 MinMax.ptMaxSize.x += 2 * xinc;
221 MinMax.ptMaxSize.y += 2 * yinc;
222
223#if 0
224 lpPos = (LPINTERNALPOS)GetPropA( hwndSelf, atomInternalPos );
225 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
226 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
227 else
228 {
229#endif
230 MinMax.ptMaxPosition.x = -xinc;
231 MinMax.ptMaxPosition.y = -yinc;
232// }
233
234 SendMessageA(WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
235
236 /* Some sanity checks */
237
238 dprintf(("GetMinMaxInfo: %ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
239 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
240 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
241 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
242 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y));
243 MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
244 MinMax.ptMinTrackSize.x );
245 MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
246 MinMax.ptMinTrackSize.y );
247
248 if (maxSize) *maxSize = MinMax.ptMaxSize;
249 if (maxPos) *maxPos = MinMax.ptMaxPosition;
250 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
251 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
252}
253/***********************************************************************
254 * WINPOS_SendNCCalcSize
255 *
256 * Send a WM_NCCALCSIZE message to a window.
257 * All parameters are read-only except newClientRect.
258 * oldWindowRect, oldClientRect and winpos must be non-NULL only
259 * when calcValidRect is TRUE.
260 */
261LONG Win32BaseWindow::SendNCCalcSize(BOOL calcValidRect, RECT *newWindowRect,
262 RECT *oldWindowRect,
263 RECT *oldClientRect, WINDOWPOS *winpos,
264 RECT *newClientRect )
265{
266 NCCALCSIZE_PARAMS params;
267 WINDOWPOS winposCopy;
268 LONG result;
269
270 params.rgrc[0] = *newWindowRect;
271 if (calcValidRect)
272 {
273 winposCopy = *winpos;
274 params.rgrc[1] = *oldWindowRect;
275 params.rgrc[2] = *oldClientRect;
276 params.lppos = &winposCopy;
277 }
278 result = SendMessageA(WM_NCCALCSIZE, calcValidRect,
279 (LPARAM)&params );
280 *newClientRect = params.rgrc[0];
281 return result;
282}
283//******************************************************************************
284//******************************************************************************
285LONG Win32BaseWindow::NCHandleCalcSize(WPARAM wParam, NCCALCSIZE_PARAMS *ncsize)
286{
287 LONG result = 0;
288
289 if (getStyle() & CS_VREDRAW) result |= WVR_VREDRAW;
290 if (getStyle() & CS_HREDRAW) result |= WVR_HREDRAW;
291
292//TODO: Wine calculates new size of client area even when window is iconic (client edges)
293 if(!(getStyle() & (WS_MINIMIZE | WS_ICONIC)))
294 {
295 dprintf(("NCHandleCalcSize %x (%d,%d) (%d,%d)", getWindowHandle(), ncsize->rgrc[0].left, ncsize->rgrc[0].top, ncsize->rgrc[0].right, ncsize->rgrc[0].bottom));
296 OSLibWinCalcFrameRect(getOS2FrameWindowHandle(), &ncsize->rgrc[0], TRUE); //frame -> client
297 dprintf(("NCHandleCalcSize Adjusted client rect (%d,%d) (%d,%d)", ncsize->rgrc[0].left, ncsize->rgrc[0].top, ncsize->rgrc[0].right, ncsize->rgrc[0].bottom));
298
299 OffsetRect(&ncsize->rgrc[0], -ncsize->rgrc[0].left, -ncsize->rgrc[0].top);
300 }
301#if 0
302//TODO: Docs say app should return 0 when fCalcValidRects == 0; Wine doesn't do this
303 if(wParam == 0) //fCalcValidRects
304 return 0;
305#endif
306 return result;
307}
308/***********************************************************************
309 * WIN_WindowNeedsWMBorder
310 *
311 * This method defines the rules for a window to have a WM border,
312 * caption... It is used for consitency purposes.
313 */
314BOOL Win32BaseWindow::WindowNeedsWMBorder( DWORD style, DWORD exStyle )
315{
316// if (!(style & WS_CHILD) && Options.managed &&
317 if (!(style & WS_CHILD) &&
318 (((style & WS_CAPTION) == WS_CAPTION) ||
319 (style & WS_THICKFRAME)))
320 return TRUE;
321 return FALSE;
322}
323/******************************************************************************
324 * NC_AdjustRectOuter95
325 *
326 * Computes the size of the "outside" parts of the window based on the
327 * parameters of the client area.
328 *
329 + PARAMS
330 * LPRECT16 rect
331 * DWORD style
332 * BOOL32 menu
333 * DWORD exStyle
334 *
335 * NOTES
336 * "Outer" parts of a window means the whole window frame, caption and
337 * menu bar. It does not include "inner" parts of the frame like client
338 * edge, static edge or scroll bars.
339 *
340 * Revision history
341 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
342 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
343 *
344 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
345 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
346 * NC_AdjustRectInner95 and added handling of Win95 styles.
347 *
348 * 28-Jul-1999 Ove Kåven (ovek@arcticnet.no)
349 * Streamlined window style checks.
350 *
351 *****************************************************************************/
352void Win32BaseWindow::NC_AdjustRectOuter(LPRECT rect, DWORD style, BOOL menu, DWORD exStyle)
353{
354 if(style & WS_ICONIC) return;
355
356 /* Decide if the window will be managed (see CreateWindowEx) */
357// if (!WindowNeedsWMBorder(style, exStyle))
358// {
359 if (HAS_THICKFRAME( style, exStyle ))
360 InflateRect( rect, GetSystemMetrics(SM_CXFRAME), GetSystemMetrics(SM_CYFRAME) );
361 else
362 if (HAS_DLGFRAME( style, exStyle ))
363 InflateRect(rect, GetSystemMetrics(SM_CXDLGFRAME), GetSystemMetrics(SM_CYDLGFRAME) );
364 else
365 if (HAS_THINFRAME( style ))
366 InflateRect( rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
367
368 if ((style & WS_CAPTION) == WS_CAPTION)
369 {
370 if (exStyle & WS_EX_TOOLWINDOW)
371 rect->top -= GetSystemMetrics(SM_CYSMCAPTION);
372 else
373 rect->top -= GetSystemMetrics(SM_CYCAPTION);
374 }
375// }
376
377 if (menu)
378 rect->top -= GetSystemMetrics(SM_CYMENU);
379}
380/******************************************************************************
381 * NC_AdjustRectInner95
382 *
383 * Computes the size of the "inside" part of the window based on the
384 * parameters of the client area.
385 *
386 + PARAMS
387 * LPRECT16 rect
388 * DWORD style
389 * DWORD exStyle
390 *
391 * NOTES
392 * "Inner" part of a window means the window frame inside of the flat
393 * window frame. It includes the client edge, the static edge and the
394 * scroll bars.
395 *
396 * Revision history
397 * 05-Jul-1997 Dave Cuthbert (dacut@ece.cmu.edu)
398 * Original (NC_AdjustRect95) cut & paste from NC_AdjustRect
399 *
400 * 20-Jun-1998 Eric Kohl (ekohl@abo.rhein-zeitung.de)
401 * Split NC_AdjustRect95 into NC_AdjustRectOuter95 and
402 * NC_AdjustRectInner95 and added handling of Win95 styles.
403 *
404 *****************************************************************************/
405void Win32BaseWindow::NC_AdjustRectInner(LPRECT rect, DWORD style, DWORD exStyle)
406{
407 if(style & WS_ICONIC) return;
408
409 if (exStyle & WS_EX_CLIENTEDGE)
410 InflateRect(rect, GetSystemMetrics(SM_CXEDGE), GetSystemMetrics(SM_CYEDGE));
411
412 if (exStyle & WS_EX_STATICEDGE)
413 InflateRect(rect, GetSystemMetrics(SM_CXBORDER), GetSystemMetrics(SM_CYBORDER));
414
415 if (style & WS_VSCROLL) rect->right += GetSystemMetrics(SM_CXVSCROLL);
416 if (style & WS_HSCROLL) rect->bottom += GetSystemMetrics(SM_CYHSCROLL);
417}
418/***********************************************************************
419 * WINPOS_HandleWindowPosChanging16
420 *
421 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
422 */
423LONG Win32BaseWindow::HandleWindowPosChanging(WINDOWPOS *winpos)
424{
425 POINT maxSize, minTrack;
426 int rc = 1;
427
428 if (winpos->flags & SWP_NOSIZE)
429 return 1;
430
431 if ((getStyle() & WS_THICKFRAME) ||
432 ((getStyle() & (WS_POPUP | WS_CHILD)) == 0))
433 {
434 GetMinMaxInfo(&maxSize, NULL, &minTrack, NULL );
435 if (maxSize.x < winpos->cx) {
436 winpos->cx = maxSize.x;
437 rc = 0;
438 }
439 if (maxSize.y < winpos->cy) {
440 winpos->cy = maxSize.y;
441 rc = 0;
442 }
443 if (!(getStyle() & WS_MINIMIZE))
444 {
445 if (winpos->cx < minTrack.x ) {
446 winpos->cx = minTrack.x;
447 rc = 0;
448 }
449 if (winpos->cy < minTrack.y ) {
450 winpos->cy = minTrack.y;
451 rc = 0;
452 }
453 }
454 }
455 return rc;
456}
457//******************************************************************************
458//******************************************************************************
459
Note: See TracBrowser for help on using the repository browser.