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