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