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

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

sendmessage + hook updates + misc fixes

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