156b46a28e7e09a511dbd6ff22144d20ed6509ee
[reactos.git] / win32ss / user / user32 / windows / winpos.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS user32.dll
4 * FILE: win32ss/user/user32/windows/winpos.c
5 * PURPOSE: Window management
6 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * UPDATE HISTORY:
8 * 06-06-2001 CSH Created
9 */
10
11 #include <user32.h>
12
13 WINE_DEFAULT_DEBUG_CHANNEL(user32);
14
15 void mirror_rect( const RECT *window_rect, RECT *rect )
16 {
17 int width = window_rect->right - window_rect->left;
18 int tmp = rect->left;
19 rect->left = width - rect->right;
20 rect->right = width - tmp;
21 }
22
23 /* FUNCTIONS *****************************************************************/
24
25 #define EMPTYPOINT(pt) ((pt).x == -1 && (pt).y == -1)
26
27 UINT WINAPI
28 WinPosGetMinMaxInfo(HWND hwnd, POINT* maxSize, POINT* maxPos,
29 POINT* minTrack, POINT* maxTrack)
30 {
31 MINMAXINFO MinMax;
32 HMONITOR monitor;
33 INT xinc, yinc;
34 LONG style = GetWindowLongW( hwnd, GWL_STYLE );
35 LONG adjustedStyle;
36 LONG exstyle = GetWindowLongW( hwnd, GWL_EXSTYLE );
37 RECT rc;
38 WND *win;
39
40 /* Compute default values */
41
42 GetWindowRect(hwnd, &rc);
43 MinMax.ptReserved.x = rc.left;
44 MinMax.ptReserved.y = rc.top;
45
46 if ((style & WS_CAPTION) == WS_CAPTION)
47 adjustedStyle = style & ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
48 else
49 adjustedStyle = style;
50
51 GetClientRect(GetAncestor(hwnd,GA_PARENT), &rc);
52 AdjustWindowRectEx(&rc, adjustedStyle, ((style & WS_POPUP) && GetMenu(hwnd)), exstyle);
53
54 xinc = -rc.left;
55 yinc = -rc.top;
56
57 MinMax.ptMaxSize.x = rc.right - rc.left;
58 MinMax.ptMaxSize.y = rc.bottom - rc.top;
59 if (style & (WS_DLGFRAME | WS_BORDER))
60 {
61 MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
62 MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
63 }
64 else
65 {
66 MinMax.ptMinTrackSize.x = 2 * xinc;
67 MinMax.ptMinTrackSize.y = 2 * yinc;
68 }
69 MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXMAXTRACK);
70 MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYMAXTRACK);
71 MinMax.ptMaxPosition.x = -xinc;
72 MinMax.ptMaxPosition.y = -yinc;
73
74 if ((win = ValidateHwnd( hwnd )) )//&& win != WND_DESKTOP && win != WND_OTHER_PROCESS)
75 {
76 if (!EMPTYPOINT(win->InternalPos.MaxPos)) MinMax.ptMaxPosition = win->InternalPos.MaxPos;
77 }
78
79 SendMessageW( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
80
81 /* if the app didn't change the values, adapt them for the current monitor */
82
83 if ((monitor = MonitorFromWindow( hwnd, MONITOR_DEFAULTTOPRIMARY )))
84 {
85 RECT rc_work;
86 MONITORINFO mon_info;
87
88 mon_info.cbSize = sizeof(mon_info);
89 GetMonitorInfoW( monitor, &mon_info );
90
91 rc_work = mon_info.rcMonitor;
92
93 if (style & WS_MAXIMIZEBOX)
94 {
95 if ((style & WS_CAPTION) == WS_CAPTION || !(style & (WS_CHILD | WS_POPUP)))
96 rc_work = mon_info.rcWork;
97 }
98
99 if (MinMax.ptMaxSize.x == GetSystemMetrics(SM_CXSCREEN) + 2 * xinc &&
100 MinMax.ptMaxSize.y == GetSystemMetrics(SM_CYSCREEN) + 2 * yinc)
101 {
102 MinMax.ptMaxSize.x = (rc_work.right - rc_work.left) + 2 * xinc;
103 MinMax.ptMaxSize.y = (rc_work.bottom - rc_work.top) + 2 * yinc;
104 }
105 if (MinMax.ptMaxPosition.x == -xinc && MinMax.ptMaxPosition.y == -yinc)
106 {
107 MinMax.ptMaxPosition.x = rc_work.left - xinc;
108 MinMax.ptMaxPosition.y = rc_work.top - yinc;
109 }
110 }
111
112 /* Some sanity checks */
113
114 TRACE("%d %d / %d %d / %d %d / %d %d\n",
115 MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
116 MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
117 MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
118 MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
119 MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
120 MinMax.ptMinTrackSize.x );
121 MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
122 MinMax.ptMinTrackSize.y );
123
124 if (maxSize) *maxSize = MinMax.ptMaxSize;
125 if (maxPos) *maxPos = MinMax.ptMaxPosition;
126 if (minTrack) *minTrack = MinMax.ptMinTrackSize;
127 if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
128
129 return 0; //FIXME: what does it return?
130 }
131
132
133 /*
134 * @implemented
135 */
136 HWND WINAPI
137 GetActiveWindow(VOID)
138 {
139 return (HWND)NtUserGetThreadState(THREADSTATE_ACTIVEWINDOW);
140 }
141
142
143 /*
144 * @unimplemented
145 */
146 UINT WINAPI
147 ArrangeIconicWindows(HWND hWnd)
148 {
149 return NtUserxArrangeIconicWindows( hWnd );
150 }
151
152 /*
153 * @implemented
154 */
155 HWND WINAPI
156 WindowFromPoint(POINT Point)
157 {
158 //TODO: Determine what the actual parameters to
159 // NtUserWindowFromPoint are.
160 return NtUserWindowFromPoint(Point.x, Point.y);
161 }
162
163 /*
164 * @implemented
165 */
166 int WINAPI
167 MapWindowPoints(HWND hWndFrom, HWND hWndTo, LPPOINT lpPoints, UINT cPoints)
168 {
169 PWND FromWnd = NULL, ToWnd = NULL;
170 BOOL mirror_from, mirror_to;
171 POINT Delta;
172 UINT i;
173 int Change = 1;
174
175 if (hWndFrom)
176 {
177 FromWnd = ValidateHwnd(hWndFrom);
178 if (!FromWnd)
179 return 0;
180 }
181 if (hWndTo)
182 {
183 ToWnd = ValidateHwnd(hWndTo);
184 if (!ToWnd)
185 return 0;
186 }
187
188 /* Note: Desktop Top and Left is always 0! */
189 Delta.x = Delta.y = 0;
190 mirror_from = mirror_to = FALSE;
191
192 if (FromWnd && hWndFrom != GetDesktopWindow()) // FromWnd->fnid != FNID_DESKTOP)
193 {
194 if (FromWnd->ExStyle & WS_EX_LAYOUTRTL)
195 {
196 mirror_from = TRUE;
197 Change = -Change;
198 Delta.x = -FromWnd->rcClient.right;
199 }
200 else
201 Delta.x = FromWnd->rcClient.left;
202 Delta.y = FromWnd->rcClient.top;
203 }
204
205 if (ToWnd && hWndTo != GetDesktopWindow()) // ToWnd->fnid != FNID_DESKTOP)
206 {
207 if (ToWnd->ExStyle & WS_EX_LAYOUTRTL)
208 {
209 mirror_to = TRUE;
210 Change = -Change;
211 Delta.x += Change * ToWnd->rcClient.right;
212 }
213 else
214 Delta.x -= Change * ToWnd->rcClient.left;
215 Delta.y -= ToWnd->rcClient.top;
216 }
217
218 for (i = 0; i != cPoints; i++)
219 {
220 lpPoints[i].x += Delta.x;
221 lpPoints[i].x *= Change;
222 lpPoints[i].y += Delta.y;
223 }
224
225 if ((mirror_from || mirror_to) && cPoints == 2) /* special case for rectangle */
226 {
227 int tmp = min(lpPoints[0].x, lpPoints[1].x);
228 lpPoints[1].x = max(lpPoints[0].x, lpPoints[1].x);
229 lpPoints[0].x = tmp;
230 }
231
232 return MAKELONG(LOWORD(Delta.x), LOWORD(Delta.y));
233 }
234
235 /*
236 * @implemented
237 */
238 BOOL WINAPI
239 ScreenToClient(HWND hWnd, LPPOINT lpPoint)
240 {
241 PWND Wnd;
242 /* Note: Desktop Top and Left is always 0! */
243 Wnd = ValidateHwnd(hWnd);
244 if (!Wnd)
245 return FALSE;
246
247 if (hWnd != GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
248 {
249 if (Wnd->ExStyle & WS_EX_LAYOUTRTL)
250 lpPoint->x = Wnd->rcClient.right - lpPoint->x;
251 else
252 lpPoint->x -= Wnd->rcClient.left;
253 lpPoint->y -= Wnd->rcClient.top;
254 }
255 return TRUE;
256 }
257
258 /*
259 * @implemented
260 */
261 BOOL WINAPI
262 ClientToScreen(HWND hWnd, LPPOINT lpPoint)
263 {
264 PWND Wnd;
265 /* Note: Desktop Top and Left is always 0! */
266 Wnd = ValidateHwnd(hWnd);
267 if (!Wnd)
268 return FALSE;
269
270 if ( hWnd != GetDesktopWindow()) // Wnd->fnid != FNID_DESKTOP )
271 {
272 if (Wnd->ExStyle & WS_EX_LAYOUTRTL)
273 lpPoint->x = Wnd->rcClient.right - lpPoint->x;
274 else
275 lpPoint->x += Wnd->rcClient.left;
276 lpPoint->y += Wnd->rcClient.top;
277 }
278 return TRUE;
279 }