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

Last change on this file since 4945 was 4945, checked in by sandervl, 25 years ago

listbox, combobox and notifyframe fixes

File size: 8.9 KB
Line 
1/* $Id: win32wbasepos.cpp,v 1.18 2001-01-14 17:15: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 <spy.h>
28#include "wndmsg.h"
29#include "oslibwin.h"
30#include "oslibutil.h"
31#include "oslibgdi.h"
32#include "oslibres.h"
33#include "oslibdos.h"
34#include "syscolor.h"
35#include "win32wndhandle.h"
36#include "dc.h"
37#include "pmframe.h"
38#include "win32wdesktop.h"
39#include <win\hook.h>
40
41#define DBG_LOCALLOG DBG_win32wbasepos
42#include "dbglocal.h"
43
44/*******************************************************************
45 * GetMinMaxInfo
46 *
47 * Get the minimized and maximized information for a window.
48 */
49void Win32BaseWindow::GetMinMaxInfo(POINT *maxSize, POINT *maxPos,
50 POINT *minTrack, POINT *maxTrack )
51{
52 MINMAXINFO MinMax;
53 INT xinc, yinc;
54
55 /* Compute default values */
56
57 MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
58 MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
59 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
60 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
61 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN);
62 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN);
63
64 if (HAS_DLGFRAME( dwStyle, dwExStyle ))
65 {
66 xinc = GetSystemMetrics(SM_CXDLGFRAME);
67 yinc = GetSystemMetrics(SM_CYDLGFRAME);
68 }
69 else
70 {
71 xinc = yinc = 0;
72 if (HAS_THICKFRAME(dwStyle, dwExStyle))
73 {
74 xinc += GetSystemMetrics(SM_CXFRAME);
75 yinc += GetSystemMetrics(SM_CYFRAME);
76 }
77 //SvL: Wine has no 'else', but I'm seeing different behaviour in NT
78 // and it doesn't make much sense either as a window can have
79 // only one kind of border (see drawing code)
80 else
81 if (dwStyle & WS_BORDER)
82 {
83 xinc += GetSystemMetrics(SM_CXBORDER);
84 yinc += GetSystemMetrics(SM_CYBORDER);
85 }
86 }
87 MinMax.ptMaxSize.x += 2 * xinc;
88 MinMax.ptMaxSize.y += 2 * yinc;
89
90#if 0
91 lpPos = (LPINTERNALPOS)GetPropA( hwndSelf, atomInternalPos );
92 if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
93 CONV_POINT16TO32( &lpPos->ptMaxPos, &MinMax.ptMaxPosition );
94 else
95 {
96#endif
97 MinMax.ptMaxPosition.x = -xinc;
98 MinMax.ptMaxPosition.y = -yinc;
99// }
100
101 SendInternalMessageA(WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
102
103 /* Some sanity checks */
104
105 dprintf(("GetMinMaxInfo: %ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
106 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
107 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
108 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
109 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y));
110 MinMax.ptMaxTrackSize.x = MAX( MinMax.ptMaxTrackSize.x,
111 MinMax.ptMinTrackSize.x );
112 MinMax.ptMaxTrackSize.y = MAX( MinMax.ptMaxTrackSize.y,
113 MinMax.ptMinTrackSize.y );
114
115 if (maxSize) *maxSize = MinMax.ptMaxSize;
116 if (maxPos) *maxPos = MinMax.ptMaxPosition;
117 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
118 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
119}
120/***********************************************************************
121 * WINPOS_SendNCCalcSize
122 *
123 * Send a WM_NCCALCSIZE message to a window.
124 * All parameters are read-only except newClientRect.
125 * oldWindowRect, oldClientRect and winpos must be non-NULL only
126 * when calcValidRect is TRUE.
127 */
128LONG Win32BaseWindow::SendNCCalcSize(BOOL calcValidRect, RECT *newWindowRect,
129 RECT *oldWindowRect,
130 RECT *oldClientRect, WINDOWPOS *winpos,
131 RECT *newClientRect )
132{
133 NCCALCSIZE_PARAMS params;
134 WINDOWPOS winposCopy;
135 LONG result = 0;
136
137 /* Send WM_NCCALCSIZE message to get new client area */
138 if((winpos->flags & (SWP_FRAMECHANGED | SWP_NOSIZE)) != SWP_NOSIZE )
139 {
140 params.rgrc[0] = *newWindowRect;
141 if(calcValidRect)
142 {
143 winposCopy = *winpos;
144 params.rgrc[1] = *oldWindowRect;
145 params.rgrc[2] = *oldClientRect;
146 //client rectangel must be in parent coordinates
147 OffsetRect(&params.rgrc[2], rectWindow.left, rectWindow.top);
148
149 params.lppos = &winposCopy;
150 }
151 result = SendInternalMessageA(WM_NCCALCSIZE, calcValidRect, (LPARAM)&params );
152
153 /* If the application send back garbage, ignore it */
154 if(params.rgrc[0].left <= params.rgrc[0].right && params.rgrc[0].top <= params.rgrc[0].bottom)
155 {
156 *newClientRect = params.rgrc[0];
157 //client rectangle now in parent coordinates; convert to 'frame' coordinates
158 OffsetRect(newClientRect, -rectWindow.left, -rectWindow.top);
159 }
160
161 /* FIXME: WVR_ALIGNxxx */
162 if(newClientRect->left != rectClient.left || newClientRect->top != rectClient.top)
163 winpos->flags &= ~SWP_NOCLIENTMOVE;
164
165 if((newClientRect->right - newClientRect->left != rectClient.right - rectClient.left) ||
166 (newClientRect->bottom - newClientRect->top != rectClient.bottom - rectClient.top))
167 winpos->flags &= ~SWP_NOCLIENTSIZE;
168
169 }
170 else
171 if(!(winpos->flags & SWP_NOMOVE) &&
172 (newClientRect->left != rectClient.left || newClientRect->top != rectClient.top)) {
173 winpos->flags &= ~SWP_NOCLIENTMOVE;
174 }
175 return result;
176}
177/***********************************************************************
178 * WINPOS_HandleWindowPosChanging
179 *
180 * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
181 */
182LONG Win32BaseWindow::HandleWindowPosChanging(WINDOWPOS *winpos)
183{
184 POINT maxSize;
185 if (winpos->flags & SWP_NOSIZE) return 0;
186
187 if ((dwStyle & WS_THICKFRAME) ||
188 ((dwStyle & (WS_POPUP | WS_CHILD)) == 0))
189 {
190 GetMinMaxInfo( &maxSize, NULL, NULL, NULL );
191 winpos->cx = MIN( winpos->cx, maxSize.x );
192 winpos->cy = MIN( winpos->cy, maxSize.y );
193 }
194 return 0;
195}
196/******************************************************************************
197 * WINPOS_MinMaximize
198 *
199 * Fill in lpRect and return additional flags to be used with SetWindowPos().
200 * This function assumes that 'cmd' is different from the current window
201 * state.
202 */
203UINT Win32BaseWindow::MinMaximize(UINT cmd, LPRECT lpRect)
204{
205 UINT swpFlags = 0;
206 POINT size;
207
208 size.x = rectWindow.left;
209 size.y = rectWindow.top;
210
211 if(IsRectEmpty(&windowpos.rcNormalPosition)) {
212 CopyRect(&windowpos.rcNormalPosition, &rectWindow);
213 }
214 if(!HOOK_CallHooksA(WH_CBT, HCBT_MINMAX, getWindowHandle(), cmd))
215 {
216 if(getStyle() & WS_MINIMIZE )
217 {
218 if(!SendInternalMessageA(WM_QUERYOPEN, 0, 0L))
219 return (SWP_NOSIZE | SWP_NOMOVE);
220 }
221 switch( cmd )
222 {
223 case SW_MINIMIZE:
224 if( getStyle() & WS_MAXIMIZE)
225 {
226 setFlags(getFlags() | WIN_RESTORE_MAX);
227 setStyle(getStyle() & ~WS_MAXIMIZE);
228 }
229 else setFlags(getFlags() & ~WIN_RESTORE_MAX);
230
231 setStyle(getStyle() | WS_MINIMIZE);
232
233 SetRect(lpRect, windowpos.ptMinPosition.x, windowpos.ptMinPosition.y,
234 GetSystemMetrics(SM_CXICON), GetSystemMetrics(SM_CYICON) );
235 break;
236
237 case SW_MAXIMIZE:
238 GetMinMaxInfo(&size, &windowpos.ptMaxPosition, NULL, NULL );
239
240 if(getStyle() & WS_MINIMIZE )
241 {
242 setStyle(getStyle() & ~WS_MINIMIZE);
243 }
244 setStyle(getStyle() | WS_MAXIMIZE);
245
246 SetRect(lpRect, windowpos.ptMaxPosition.x, windowpos.ptMaxPosition.y,
247 size.x, size.y );
248 break;
249
250 case SW_RESTORE:
251 if(getStyle() & WS_MINIMIZE)
252 {
253 setStyle(getStyle() & ~WS_MINIMIZE);
254
255 if( getFlags() & WIN_RESTORE_MAX)
256 {
257 /* Restore to maximized position */
258 GetMinMaxInfo(&size, &windowpos.ptMaxPosition, NULL, NULL);
259 setStyle(getStyle() | WS_MAXIMIZE);
260 SetRect(lpRect, windowpos.ptMaxPosition.x, windowpos.ptMaxPosition.y, size.x, size.y);
261 break;
262 }
263 }
264 else
265 if( !(getStyle() & WS_MAXIMIZE) )
266 return 0;
267 else setStyle(getStyle() & ~WS_MAXIMIZE);
268
269 /* Restore to normal position */
270
271 *lpRect = windowpos.rcNormalPosition;
272 lpRect->right -= lpRect->left;
273 lpRect->bottom -= lpRect->top;
274 break;
275 }
276 }
277 else swpFlags |= SWP_NOSIZE | SWP_NOMOVE;
278
279 return swpFlags;
280}
281//******************************************************************************
282//******************************************************************************
Note: See TracBrowser for help on using the repository browser.