xref: /reactos/win32ss/user/user32/windows/winpos.c (revision c2c66aff)
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 /* 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 }
283