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