Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 1 | /* |
| 2 | * Window position related functions. |
| 3 | * |
| 4 | * Copyright 1993 Alexandre Julliard |
| 5 | */ |
| 6 | |
| 7 | static char Copyright[] = "Copyright Alexandre Julliard, 1993"; |
| 8 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 9 | #include "sysmetrics.h" |
| 10 | #include "user.h" |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 11 | #include "win.h" |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 12 | #include "message.h" |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 13 | #include "winpos.h" |
| 14 | #include "stddebug.h" |
| 15 | /* #define DEBUG_WIN /* */ |
| 16 | /* #undef DEBUG_WIN /* */ |
| 17 | #include "debug.h" |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 18 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 19 | static HWND hwndActive = 0; /* Currently active window */ |
| 20 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 21 | |
| 22 | /*********************************************************************** |
| 23 | * GetWindowRect (USER.32) |
| 24 | */ |
| 25 | void GetWindowRect( HWND hwnd, LPRECT rect ) |
| 26 | { |
| 27 | WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| 28 | if (!wndPtr) return; |
| 29 | |
| 30 | *rect = wndPtr->rectWindow; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame] | 31 | if (wndPtr->dwStyle & WS_CHILD) |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 32 | MapWindowPoints( wndPtr->hwndParent, 0, (POINT *)rect, 2 ); |
| 33 | } |
| 34 | |
| 35 | |
| 36 | /*********************************************************************** |
| 37 | * GetClientRect (USER.33) |
| 38 | */ |
| 39 | void GetClientRect( HWND hwnd, LPRECT rect ) |
| 40 | { |
| 41 | WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| 42 | |
| 43 | rect->left = rect->top = rect->right = rect->bottom = 0; |
| 44 | if (wndPtr) |
| 45 | { |
| 46 | rect->right = wndPtr->rectClient.right - wndPtr->rectClient.left; |
| 47 | rect->bottom = wndPtr->rectClient.bottom - wndPtr->rectClient.top; |
| 48 | } |
| 49 | } |
| 50 | |
| 51 | |
| 52 | /******************************************************************* |
| 53 | * ClientToScreen (USER.28) |
| 54 | */ |
| 55 | void ClientToScreen( HWND hwnd, LPPOINT lppnt ) |
| 56 | { |
| 57 | MapWindowPoints( hwnd, 0, lppnt, 1 ); |
| 58 | } |
| 59 | |
| 60 | |
| 61 | /******************************************************************* |
| 62 | * ScreenToClient (USER.29) |
| 63 | */ |
| 64 | void ScreenToClient( HWND hwnd, LPPOINT lppnt ) |
| 65 | { |
| 66 | MapWindowPoints( 0, hwnd, lppnt, 1 ); |
| 67 | } |
| 68 | |
| 69 | |
| 70 | /******************************************************************* |
Alexandre Julliard | 86a8d0f | 1994-01-18 23:04:40 +0000 | [diff] [blame] | 71 | * WindowFromPoint (USER.30) |
| 72 | */ |
| 73 | HWND WindowFromPoint( POINT pt ) |
| 74 | { |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 75 | HWND hwndRet = 0; |
| 76 | HWND hwnd = GetDesktopWindow(); |
| 77 | |
| 78 | while(hwnd) |
Alexandre Julliard | 86a8d0f | 1994-01-18 23:04:40 +0000 | [diff] [blame] | 79 | { |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 80 | /* If point is in window, and window is visible, */ |
| 81 | /* not disabled and not transparent, then explore */ |
| 82 | /* its children. Otherwise, go to the next window. */ |
| 83 | |
| 84 | WND *wndPtr = WIN_FindWndPtr( hwnd ); |
| 85 | if ((pt.x >= wndPtr->rectWindow.left) && |
| 86 | (pt.x < wndPtr->rectWindow.right) && |
| 87 | (pt.y >= wndPtr->rectWindow.top) && |
| 88 | (pt.y < wndPtr->rectWindow.bottom) && |
| 89 | !(wndPtr->dwStyle & WS_DISABLED) && |
| 90 | (wndPtr->dwStyle & WS_VISIBLE) && |
| 91 | !(wndPtr->dwExStyle & WS_EX_TRANSPARENT)) |
| 92 | { |
| 93 | pt.x -= wndPtr->rectClient.left; |
| 94 | pt.y -= wndPtr->rectClient.top; |
| 95 | hwndRet = hwnd; |
| 96 | hwnd = wndPtr->hwndChild; |
| 97 | } |
| 98 | else hwnd = wndPtr->hwndNext; |
Alexandre Julliard | 86a8d0f | 1994-01-18 23:04:40 +0000 | [diff] [blame] | 99 | } |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 100 | return hwndRet; |
Alexandre Julliard | 86a8d0f | 1994-01-18 23:04:40 +0000 | [diff] [blame] | 101 | } |
| 102 | |
| 103 | |
| 104 | /******************************************************************* |
| 105 | * ChildWindowFromPoint (USER.191) |
| 106 | */ |
| 107 | HWND ChildWindowFromPoint( HWND hwndParent, POINT pt ) |
| 108 | { |
| 109 | RECT rect; |
| 110 | HWND hwnd; |
| 111 | |
| 112 | GetWindowRect( hwndParent, &rect ); |
| 113 | if (!PtInRect( &rect, pt )) return 0; |
| 114 | hwnd = GetTopWindow( hwndParent ); |
| 115 | while (hwnd) |
| 116 | { |
| 117 | GetWindowRect( hwnd, &rect ); |
| 118 | if (PtInRect( &rect, pt )) return hwnd; |
| 119 | hwnd = GetWindow( hwnd, GW_HWNDNEXT ); |
| 120 | } |
Alexandre Julliard | 8d24ae6 | 1994-04-05 21:42:43 +0000 | [diff] [blame] | 121 | return hwndParent; |
Alexandre Julliard | 86a8d0f | 1994-01-18 23:04:40 +0000 | [diff] [blame] | 122 | } |
| 123 | |
| 124 | |
| 125 | /******************************************************************* |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 126 | * MapWindowPoints (USER.258) |
| 127 | */ |
| 128 | void MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, WORD count ) |
| 129 | { |
| 130 | WND * wndPtr; |
| 131 | POINT * curpt; |
| 132 | POINT origin = { 0, 0 }; |
| 133 | WORD i; |
| 134 | |
| 135 | /* Translate source window origin to screen coords */ |
| 136 | while(hwndFrom) |
| 137 | { |
| 138 | wndPtr = WIN_FindWndPtr( hwndFrom ); |
| 139 | origin.x += wndPtr->rectClient.left; |
| 140 | origin.y += wndPtr->rectClient.top; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame] | 141 | hwndFrom = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 142 | } |
| 143 | |
| 144 | /* Translate origin to destination window coords */ |
| 145 | while(hwndTo) |
| 146 | { |
| 147 | wndPtr = WIN_FindWndPtr( hwndTo ); |
| 148 | origin.x -= wndPtr->rectClient.left; |
| 149 | origin.y -= wndPtr->rectClient.top; |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame] | 150 | hwndTo = (wndPtr->dwStyle & WS_CHILD) ? wndPtr->hwndParent : 0; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 151 | } |
| 152 | |
| 153 | /* Translate points */ |
| 154 | for (i = 0, curpt = lppt; i < count; i++, curpt++) |
| 155 | { |
| 156 | curpt->x += origin.x; |
| 157 | curpt->y += origin.y; |
| 158 | } |
| 159 | } |
| 160 | |
| 161 | |
| 162 | /*********************************************************************** |
| 163 | * IsIconic (USER.31) |
| 164 | */ |
| 165 | BOOL IsIconic(HWND hWnd) |
| 166 | { |
| 167 | WND * wndPtr = WIN_FindWndPtr(hWnd); |
| 168 | if (wndPtr == NULL) return FALSE; |
| 169 | return (wndPtr->dwStyle & WS_MINIMIZE) != 0; |
| 170 | } |
| 171 | |
| 172 | |
| 173 | /*********************************************************************** |
| 174 | * IsZoomed (USER.272) |
| 175 | */ |
| 176 | BOOL IsZoomed(HWND hWnd) |
| 177 | { |
| 178 | WND * wndPtr = WIN_FindWndPtr(hWnd); |
| 179 | if (wndPtr == NULL) return FALSE; |
| 180 | return (wndPtr->dwStyle & WS_MAXIMIZE) != 0; |
| 181 | } |
| 182 | |
| 183 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 184 | /******************************************************************* |
| 185 | * GetActiveWindow (USER.60) |
| 186 | */ |
| 187 | HWND GetActiveWindow() |
| 188 | { |
| 189 | return hwndActive; |
| 190 | } |
| 191 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 192 | /******************************************************************* |
| 193 | * SetActiveWindow (USER.59) |
| 194 | */ |
| 195 | HWND SetActiveWindow( HWND hwnd ) |
| 196 | { |
| 197 | HWND prev = hwndActive; |
| 198 | WND *wndPtr = WIN_FindWndPtr( hwnd ); |
| 199 | if (!wndPtr || (wndPtr->dwStyle & WS_CHILD)) return 0; |
| 200 | SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); |
| 201 | return prev; |
| 202 | } |
| 203 | |
| 204 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 205 | /*********************************************************************** |
Alexandre Julliard | 86a8d0f | 1994-01-18 23:04:40 +0000 | [diff] [blame] | 206 | * BringWindowToTop (USER.45) |
| 207 | */ |
| 208 | BOOL BringWindowToTop( HWND hwnd ) |
| 209 | { |
| 210 | return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE ); |
| 211 | } |
| 212 | |
| 213 | |
| 214 | /*********************************************************************** |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 215 | * MoveWindow (USER.56) |
| 216 | */ |
| 217 | BOOL MoveWindow( HWND hwnd, short x, short y, short cx, short cy, BOOL repaint) |
| 218 | { |
| 219 | int flags = SWP_NOZORDER | SWP_NOACTIVATE; |
| 220 | if (!repaint) flags |= SWP_NOREDRAW; |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 221 | dprintf_win(stddeb, "MoveWindow: %d %d,%d %dx%d %d\n", |
| 222 | hwnd, x, y, cx, cy, repaint ); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 223 | return SetWindowPos( hwnd, 0, x, y, cx, cy, flags ); |
| 224 | } |
| 225 | |
| 226 | |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 227 | #if 0 |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 228 | /* |
| 229 | * hwnd is the handle to the first child window to hide |
| 230 | */ |
| 231 | static void WINPOS_hideChildren(HWND hwnd) |
| 232 | { |
| 233 | WND *wndPtr; |
| 234 | |
| 235 | while (hwnd) { |
| 236 | ShowWindow(hwnd, SW_HIDE); |
| 237 | wndPtr = WIN_FindWndPtr(hwnd); |
| 238 | assert(wndPtr); |
| 239 | WINPOS_hideChildren(wndPtr->hwndChild); |
| 240 | hwnd = wndPtr->hwndNext; |
| 241 | } |
| 242 | } |
| 243 | |
| 244 | |
| 245 | static void WINPOS_ChildrenComeOutToPlay(HWND hwnd) |
| 246 | { |
| 247 | WND *wndPtr; |
| 248 | |
| 249 | while (hwnd) { |
| 250 | /* |
| 251 | * we shouldn't really be calling SW_SHOWNOACTIVATE |
| 252 | * here because we wake up all windows, even the ones |
| 253 | * the user has decided to iconify or hide |
| 254 | * |
| 255 | * have to use SHOWNOACTIVATE instead of SHOWNORMAL |
| 256 | * since we are traversing the window tree and don't |
| 257 | * want windows linked/unlined under us |
| 258 | */ |
| 259 | ShowWindow(hwnd, SW_SHOWNOACTIVATE); |
| 260 | wndPtr = WIN_FindWndPtr(hwnd); |
| 261 | assert(wndPtr); |
| 262 | WINPOS_ChildrenComeOutToPlay(wndPtr->hwndChild); |
| 263 | hwnd = wndPtr->hwndNext; |
| 264 | } |
| 265 | } |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 266 | #endif |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 267 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 268 | /*********************************************************************** |
| 269 | * ShowWindow (USER.42) |
| 270 | */ |
| 271 | BOOL ShowWindow( HWND hwnd, int cmd ) |
| 272 | { |
| 273 | WND * wndPtr = WIN_FindWndPtr( hwnd ); |
| 274 | BOOL wasVisible; |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 275 | BOOL wasIconic; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 276 | int swpflags = 0; |
| 277 | |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 278 | if (!wndPtr) return FALSE; |
| 279 | |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 280 | dprintf_win(stddeb,"ShowWindow: hwnd=%04X, cmd=%d\n", hwnd, cmd); |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 281 | |
| 282 | /* |
| 283 | * wasVisible is true if user has not made window invisible |
| 284 | * wasIconic is true if the window is not iconified |
| 285 | */ |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 286 | wasVisible = (wndPtr->dwStyle & WS_VISIBLE) != 0; |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 287 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 288 | switch(cmd) |
| 289 | { |
| 290 | case SW_HIDE: |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 291 | /* |
| 292 | * if the window wasn't visible to begin with -- just return |
| 293 | */ |
| 294 | if (!wasVisible) |
| 295 | return FALSE; /* Nothing to do */ |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 296 | swpflags |= SWP_HIDEWINDOW | SWP_NOSIZE | SWP_NOMOVE | |
| 297 | SWP_NOACTIVATE | SWP_NOZORDER; |
| 298 | break; |
| 299 | |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 300 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 301 | case SW_SHOWMINNOACTIVE: |
| 302 | case SW_SHOWMINIMIZED: |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 303 | case SW_MINIMIZE: |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 304 | wndPtr->dwStyle |= WS_MINIMIZE; |
| 305 | swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE | |
| 306 | SWP_NOACTIVATE | SWP_NOZORDER; |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 307 | |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 308 | #if 0 |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 309 | /* |
| 310 | * tell children that they are getting hidden |
| 311 | */ |
| 312 | WINPOS_hideChildren(wndPtr->hwndChild); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 313 | #endif |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 314 | |
| 315 | /* store the size and position of the window, so we can |
| 316 | * deiconify it to the same size and position |
| 317 | */ |
| 318 | wndPtr->rectNormal = wndPtr->rectWindow; |
| 319 | wndPtr->ptIconPos.x = wndPtr->rectWindow.left; |
| 320 | wndPtr->ptIconPos.y = wndPtr->rectWindow.top; |
| 321 | /* move the window to icon size and position and |
| 322 | * tell it that it is going to have to be painted |
| 323 | */ |
| 324 | MoveWindow(hwnd, wndPtr->ptIconPos.x, wndPtr->ptIconPos.y, |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 325 | SYSMETRICS_CXICON, SYSMETRICS_CYICON, FALSE); |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 326 | SendMessage(hwnd, WM_PAINTICON, 0, 0); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 327 | break; |
| 328 | |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 329 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 330 | case SW_SHOWNA: |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 331 | case SW_SHOWMAXIMIZED: /* same as SW_MAXIMIZE: */ |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 332 | case SW_SHOW: |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 333 | swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; |
| 334 | break; |
| 335 | |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 336 | |
| 337 | case SW_SHOWNORMAL: /* same as SW_NORMAL: */ |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 338 | case SW_SHOWNOACTIVATE: |
| 339 | case SW_RESTORE: |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 340 | wasIconic = IsIconic(hwnd); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 341 | wndPtr->dwStyle &= ~WS_MINIMIZE; |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 342 | wndPtr->dwStyle &= ~WS_MAXIMIZE; |
| 343 | swpflags |= SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOMOVE; |
| 344 | if (cmd == SW_SHOWNOACTIVATE) |
| 345 | { |
| 346 | swpflags |= SWP_NOZORDER; |
| 347 | if (GetActiveWindow()) swpflags |= SWP_NOACTIVATE; |
| 348 | } |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 349 | if (wasIconic) { |
| 350 | MoveWindow(hwnd, wndPtr->rectNormal.left, |
| 351 | wndPtr->rectNormal.top, |
| 352 | wndPtr->rectNormal.right - wndPtr->rectNormal.left, |
| 353 | wndPtr->rectNormal.bottom - wndPtr->rectNormal.top, |
| 354 | FALSE); |
| 355 | } |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 356 | #if 0 |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 357 | WINPOS_ChildrenComeOutToPlay(wndPtr->hwndChild); |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 358 | #endif |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 359 | break; |
| 360 | } |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 361 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 362 | SendMessage( hwnd, WM_SHOWWINDOW, (cmd != SW_HIDE), 0 ); |
| 363 | SetWindowPos( hwnd, 0, 0, 0, 0, 0, swpflags ); |
| 364 | |
| 365 | /* Send WM_SIZE and WM_MOVE messages if not already done */ |
| 366 | if (!(wndPtr->flags & WIN_GOT_SIZEMSG)) |
| 367 | { |
| 368 | int wParam = SIZE_RESTORED; |
| 369 | if (wndPtr->dwStyle & WS_MAXIMIZE) wParam = SIZE_MAXIMIZED; |
| 370 | else if (wndPtr->dwStyle & WS_MINIMIZE) wParam = SIZE_MINIMIZED; |
| 371 | wndPtr->flags |= WIN_GOT_SIZEMSG; |
| 372 | SendMessage( hwnd, WM_SIZE, wParam, |
| 373 | MAKELONG(wndPtr->rectClient.right-wndPtr->rectClient.left, |
| 374 | wndPtr->rectClient.bottom-wndPtr->rectClient.top)); |
| 375 | SendMessage( hwnd, WM_MOVE, 0, |
| 376 | MAKELONG(wndPtr->rectClient.left, wndPtr->rectClient.top) ); |
| 377 | } |
Alexandre Julliard | 940d58c | 1994-09-16 09:24:37 +0000 | [diff] [blame] | 378 | |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 379 | return wasVisible; |
| 380 | } |
| 381 | |
| 382 | |
| 383 | /*********************************************************************** |
Alexandre Julliard | 86a8d0f | 1994-01-18 23:04:40 +0000 | [diff] [blame] | 384 | * GetInternalWindowPos (USER.460) |
| 385 | */ |
| 386 | WORD GetInternalWindowPos( HWND hwnd, LPRECT rectWnd, LPPOINT ptIcon ) |
| 387 | { |
| 388 | WINDOWPLACEMENT wndpl; |
| 389 | if (!GetWindowPlacement( hwnd, &wndpl )) return 0; |
| 390 | if (rectWnd) *rectWnd = wndpl.rcNormalPosition; |
| 391 | if (ptIcon) *ptIcon = wndpl.ptMinPosition; |
| 392 | return wndpl.showCmd; |
| 393 | } |
| 394 | |
| 395 | |
| 396 | /*********************************************************************** |
| 397 | * SetInternalWindowPos (USER.461) |
| 398 | */ |
| 399 | void SetInternalWindowPos( HWND hwnd, WORD showCmd, LPRECT rect, LPPOINT pt ) |
| 400 | { |
| 401 | WINDOWPLACEMENT wndpl; |
| 402 | WND *wndPtr = WIN_FindWndPtr( hwnd ); |
| 403 | |
| 404 | wndpl.length = sizeof(wndpl); |
| 405 | wndpl.flags = (pt != NULL) ? WPF_SETMINPOSITION : 0; |
| 406 | wndpl.showCmd = showCmd; |
| 407 | if (pt) wndpl.ptMinPosition = *pt; |
| 408 | wndpl.rcNormalPosition = (rect != NULL) ? *rect : wndPtr->rectNormal; |
| 409 | wndpl.ptMaxPosition = wndPtr->ptMaxPos; |
| 410 | SetWindowPlacement( hwnd, &wndpl ); |
| 411 | } |
| 412 | |
| 413 | |
| 414 | /*********************************************************************** |
| 415 | * GetWindowPlacement (USER.370) |
| 416 | */ |
| 417 | BOOL GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl ) |
| 418 | { |
| 419 | WND *wndPtr = WIN_FindWndPtr( hwnd ); |
| 420 | if (!wndPtr) return FALSE; |
| 421 | |
| 422 | wndpl->length = sizeof(*wndpl); |
| 423 | wndpl->flags = 0; |
| 424 | wndpl->showCmd = IsZoomed(hwnd) ? SW_SHOWMAXIMIZED : |
| 425 | (IsIconic(hwnd) ? SW_SHOWMINIMIZED : SW_SHOWNORMAL); |
| 426 | wndpl->ptMinPosition = wndPtr->ptIconPos; |
| 427 | wndpl->ptMaxPosition = wndPtr->ptMaxPos; |
| 428 | wndpl->rcNormalPosition = wndPtr->rectNormal; |
| 429 | return TRUE; |
| 430 | } |
| 431 | |
| 432 | |
| 433 | /*********************************************************************** |
| 434 | * SetWindowPlacement (USER.371) |
| 435 | */ |
| 436 | BOOL SetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl ) |
| 437 | { |
| 438 | WND *wndPtr = WIN_FindWndPtr( hwnd ); |
| 439 | if (!wndPtr) return FALSE; |
| 440 | |
| 441 | if (wndpl->flags & WPF_SETMINPOSITION) |
| 442 | wndPtr->ptIconPos = wndpl->ptMinPosition; |
| 443 | if ((wndpl->flags & WPF_RESTORETOMAXIMIZED) && |
| 444 | (wndpl->showCmd == SW_SHOWMINIMIZED)) wndPtr->flags |= WIN_RESTORE_MAX; |
| 445 | wndPtr->ptMaxPos = wndpl->ptMaxPosition; |
| 446 | wndPtr->rectNormal = wndpl->rcNormalPosition; |
| 447 | ShowWindow( hwnd, wndpl->showCmd ); |
| 448 | return TRUE; |
| 449 | } |
| 450 | |
| 451 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 452 | /******************************************************************* |
| 453 | * WINPOS_GetMinMaxInfo |
| 454 | * |
| 455 | * Send a WM_GETMINMAXINFO to the window. |
| 456 | */ |
| 457 | void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos, |
| 458 | POINT *minTrack, POINT *maxTrack ) |
| 459 | { |
| 460 | HANDLE minmaxHandle; |
| 461 | MINMAXINFO MinMax, *pMinMax; |
| 462 | WND *wndPtr = WIN_FindWndPtr( hwnd ); |
| 463 | |
| 464 | MinMax.ptMaxSize.x = SYSMETRICS_CXSCREEN; |
| 465 | MinMax.ptMaxSize.y = SYSMETRICS_CYSCREEN; |
| 466 | MinMax.ptMaxPosition = wndPtr->ptMaxPos; |
| 467 | MinMax.ptMinTrackSize.x = SYSMETRICS_CXMINTRACK; |
| 468 | MinMax.ptMinTrackSize.y = SYSMETRICS_CYMINTRACK; |
| 469 | MinMax.ptMaxTrackSize.x = SYSMETRICS_CXSCREEN; |
| 470 | MinMax.ptMaxTrackSize.y = SYSMETRICS_CYSCREEN; |
| 471 | |
| 472 | minmaxHandle = USER_HEAP_ALLOC( LMEM_MOVEABLE, sizeof(MINMAXINFO) ); |
| 473 | if (minmaxHandle) |
| 474 | { |
| 475 | pMinMax = (MINMAXINFO *) USER_HEAP_ADDR( minmaxHandle ); |
| 476 | memcpy( pMinMax, &MinMax, sizeof(MinMax) ); |
| 477 | SendMessage( hwnd, WM_GETMINMAXINFO, 0, (LONG)pMinMax ); |
| 478 | } |
| 479 | else pMinMax = &MinMax; |
| 480 | |
Alexandre Julliard | fb9a919 | 1994-03-01 19:48:04 +0000 | [diff] [blame] | 481 | /* Some sanity checks */ |
| 482 | |
| 483 | pMinMax->ptMaxTrackSize.x = max( pMinMax->ptMaxTrackSize.x, |
| 484 | pMinMax->ptMinTrackSize.x ); |
| 485 | pMinMax->ptMaxTrackSize.y = max( pMinMax->ptMaxTrackSize.y, |
| 486 | pMinMax->ptMinTrackSize.y ); |
| 487 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 488 | if (maxSize) *maxSize = pMinMax->ptMaxSize; |
| 489 | if (maxPos) *maxPos = pMinMax->ptMaxPosition; |
| 490 | if (minTrack) *minTrack = pMinMax->ptMinTrackSize; |
| 491 | if (maxTrack) *maxTrack = pMinMax->ptMaxTrackSize; |
| 492 | if (minmaxHandle) USER_HEAP_FREE( minmaxHandle ); |
| 493 | } |
| 494 | |
| 495 | |
| 496 | /******************************************************************* |
| 497 | * WINPOS_ChangeActiveWindow |
| 498 | * |
| 499 | * Change the active window and send the corresponding messages. |
| 500 | */ |
| 501 | HWND WINPOS_ChangeActiveWindow( HWND hwnd, BOOL mouseMsg ) |
| 502 | { |
| 503 | HWND prevActive = hwndActive; |
| 504 | if (hwnd == hwndActive) return 0; |
| 505 | if (hwndActive) |
| 506 | { |
| 507 | if (!SendMessage( hwndActive, WM_NCACTIVATE, FALSE, 0 )) return 0; |
| 508 | SendMessage( hwndActive, WM_ACTIVATE, WA_INACTIVE, |
| 509 | MAKELONG( IsIconic(hwndActive), hwnd ) ); |
| 510 | /* Send WM_ACTIVATEAPP here */ |
| 511 | } |
| 512 | |
| 513 | hwndActive = hwnd; |
| 514 | if (hwndActive) |
| 515 | { |
Alexandre Julliard | 5819953 | 1994-04-21 01:20:00 +0000 | [diff] [blame] | 516 | WND *wndPtr = WIN_FindWndPtr( hwndActive ); |
| 517 | wndPtr->hwndPrevActive = prevActive; |
| 518 | |
Alexandre Julliard | dba420a | 1994-02-02 06:48:31 +0000 | [diff] [blame] | 519 | /* Send WM_ACTIVATEAPP here */ |
| 520 | SendMessage( hwnd, WM_NCACTIVATE, TRUE, 0 ); |
| 521 | SendMessage( hwnd, WM_ACTIVATE, mouseMsg ? WA_CLICKACTIVE : WA_ACTIVE, |
| 522 | MAKELONG( IsIconic(hwnd), prevActive ) ); |
| 523 | } |
| 524 | return prevActive; |
| 525 | } |
| 526 | |
| 527 | |
Alexandre Julliard | 86a8d0f | 1994-01-18 23:04:40 +0000 | [diff] [blame] | 528 | /*********************************************************************** |
Alexandre Julliard | 2d159fb | 1994-07-15 16:04:31 +0000 | [diff] [blame] | 529 | * WINPOS_SendNCCalcSize |
| 530 | * |
| 531 | * Send a WM_NCCALCSIZE message to a window. |
| 532 | * All parameters are read-only except newClientRect. |
| 533 | * oldWindowRect, oldClientRect and winpos must be non-NULL only |
| 534 | * when calcValidRect is TRUE. |
| 535 | */ |
| 536 | LONG WINPOS_SendNCCalcSize( HWND hwnd, BOOL calcValidRect, RECT *newWindowRect, |
| 537 | RECT *oldWindowRect, RECT *oldClientRect, |
| 538 | WINDOWPOS *winpos, RECT *newClientRect ) |
| 539 | { |
| 540 | NCCALCSIZE_PARAMS *params; |
| 541 | HANDLE hparams; |
| 542 | LONG result; |
| 543 | |
| 544 | if (!(hparams = USER_HEAP_ALLOC( GMEM_MOVEABLE, sizeof(*params) ))) |
| 545 | return 0; |
| 546 | params = (NCCALCSIZE_PARAMS *) USER_HEAP_ADDR( hparams ); |
| 547 | params->rgrc[0] = *newWindowRect; |
| 548 | if (calcValidRect) |
| 549 | { |
| 550 | params->rgrc[1] = *oldWindowRect; |
| 551 | params->rgrc[2] = *oldClientRect; |
| 552 | params->lppos = winpos; |
| 553 | } |
| 554 | result = SendMessage( hwnd, WM_NCCALCSIZE, calcValidRect, (LONG)params); |
| 555 | *newClientRect = params->rgrc[0]; |
| 556 | USER_HEAP_FREE( hparams ); |
| 557 | return result; |
| 558 | } |
| 559 | |
| 560 | |
| 561 | /*********************************************************************** |
| 562 | * WINPOS_HandleWindowPosChanging |
| 563 | * |
| 564 | * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc(). |
| 565 | */ |
| 566 | LONG WINPOS_HandleWindowPosChanging( WINDOWPOS *winpos ) |
| 567 | { |
| 568 | POINT maxSize; |
| 569 | WND *wndPtr = WIN_FindWndPtr( winpos->hwnd ); |
| 570 | if (!wndPtr || (winpos->flags & SWP_NOSIZE)) return 0; |
| 571 | if ((wndPtr->dwStyle & WS_THICKFRAME) || |
| 572 | (wndPtr->dwStyle & (WS_POPUP | WS_CHILD) == 0)) |
| 573 | { |
| 574 | WINPOS_GetMinMaxInfo( winpos->hwnd, &maxSize, NULL, NULL, NULL ); |
| 575 | winpos->cx = min( winpos->cx, maxSize.x ); |
| 576 | winpos->cy = min( winpos->cy, maxSize.y ); |
| 577 | } |
| 578 | return 0; |
| 579 | } |
| 580 | |
| 581 | |
| 582 | /*********************************************************************** |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 583 | * WINPOS_MoveWindowZOrder |
| 584 | * |
| 585 | * Move a window in Z order, invalidating everything that needs it. |
| 586 | * Only necessary for windows without associated X window. |
| 587 | */ |
| 588 | static void WINPOS_MoveWindowZOrder( HWND hwnd, HWND hwndAfter, BOOL erase ) |
| 589 | { |
| 590 | BOOL movingUp; |
| 591 | HWND hwndCur; |
| 592 | WND *wndPtr = WIN_FindWndPtr( hwnd ); |
| 593 | |
| 594 | /* We have two possible cases: |
| 595 | * - The window is moving up: we have to invalidate all areas |
| 596 | * of the window that were covered by other windows |
| 597 | * - The window is moving down: we have to invalidate areas |
| 598 | * of other windows covered by this one. |
| 599 | */ |
| 600 | |
| 601 | if (hwndAfter == HWND_TOP) |
| 602 | { |
| 603 | movingUp = TRUE; |
| 604 | } |
| 605 | else if (hwndAfter == HWND_BOTTOM) |
| 606 | { |
| 607 | if (!wndPtr->hwndNext) return; /* Already at the bottom */ |
| 608 | movingUp = FALSE; |
| 609 | } |
| 610 | else |
| 611 | { |
| 612 | if (wndPtr->hwndNext == hwndAfter) return; /* Already placed right */ |
| 613 | |
| 614 | /* Determine which window we encounter first in Z-order */ |
| 615 | hwndCur = GetWindow( wndPtr->hwndParent, GW_CHILD ); |
| 616 | while ((hwndCur != hwnd) && (hwndCur != hwndAfter)) |
| 617 | hwndCur = GetWindow( hwndCur, GW_HWNDNEXT ); |
| 618 | movingUp = (hwndCur == hwndAfter); |
| 619 | } |
| 620 | |
| 621 | if (movingUp) |
| 622 | { |
| 623 | HWND hwndPrevAfter = wndPtr->hwndNext; |
| 624 | WIN_UnlinkWindow( hwnd ); |
| 625 | WIN_LinkWindow( hwnd, hwndAfter ); |
| 626 | hwndCur = wndPtr->hwndNext; |
| 627 | while (hwndCur != hwndPrevAfter) |
| 628 | { |
| 629 | WND *curPtr = WIN_FindWndPtr( hwndCur ); |
| 630 | RECT rect = curPtr->rectWindow; |
| 631 | OffsetRect( &rect, -wndPtr->rectClient.left, |
| 632 | -wndPtr->rectClient.top ); |
| 633 | RedrawWindow( hwnd, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | |
| 634 | RDW_FRAME | (erase ? RDW_ERASENOW : RDW_ERASE) ); |
| 635 | hwndCur = curPtr->hwndNext; |
| 636 | } |
| 637 | } |
| 638 | else /* Moving down */ |
| 639 | { |
| 640 | hwndCur = wndPtr->hwndNext; |
| 641 | WIN_UnlinkWindow( hwnd ); |
| 642 | WIN_LinkWindow( hwnd, hwndAfter ); |
| 643 | while (hwndCur != hwnd) |
| 644 | { |
| 645 | WND *curPtr = WIN_FindWndPtr( hwndCur ); |
| 646 | RECT rect = wndPtr->rectWindow; |
| 647 | OffsetRect( &rect, -curPtr->rectClient.left, |
| 648 | -curPtr->rectClient.top ); |
| 649 | RedrawWindow( hwndCur, &rect, 0, RDW_INVALIDATE | RDW_ALLCHILDREN | |
| 650 | RDW_FRAME | (erase ? RDW_ERASENOW : RDW_ERASE) ); |
| 651 | hwndCur = curPtr->hwndNext; |
| 652 | } |
| 653 | } |
| 654 | } |
| 655 | |
| 656 | |
| 657 | /*********************************************************************** |
Alexandre Julliard | 2d159fb | 1994-07-15 16:04:31 +0000 | [diff] [blame] | 658 | * WINPOS_InternalSetWindowPos |
| 659 | * |
| 660 | * Helper function for SetWindowPos. |
| 661 | */ |
| 662 | static BOOL WINPOS_InternalSetWindowPos( WINDOWPOS *winpos ) |
| 663 | { |
| 664 | HWND hwndAfter; |
| 665 | WND *wndPtr; |
| 666 | RECT newWindowRect, newClientRect; |
| 667 | int flags, result; |
| 668 | int changeMask = 0; |
| 669 | XWindowChanges winChanges; |
| 670 | |
| 671 | /* Send WM_WINDOWPOSCHANGING message */ |
| 672 | |
| 673 | if (!(winpos->flags & SWP_NOSENDCHANGING)) |
| 674 | SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGING, 0, (LONG)winpos ); |
| 675 | |
| 676 | /* Check window handle */ |
| 677 | |
| 678 | if (winpos->hwnd == GetDesktopWindow()) return FALSE; |
| 679 | if (!(wndPtr = WIN_FindWndPtr( winpos->hwnd ))) return FALSE; |
| 680 | |
| 681 | /* Check dimensions */ |
| 682 | |
| 683 | if (winpos->cx <= 0) winpos->cx = 1; |
| 684 | if (winpos->cy <= 0) winpos->cy = 1; |
| 685 | |
| 686 | /* Check flags */ |
| 687 | |
| 688 | flags = winpos->flags; |
Alexandre Julliard | 2d159fb | 1994-07-15 16:04:31 +0000 | [diff] [blame] | 689 | if (winpos->hwnd == hwndActive) flags |= SWP_NOACTIVATE; /*Already active*/ |
| 690 | |
| 691 | /* Check hwndAfter */ |
| 692 | |
| 693 | hwndAfter = winpos->hwndInsertAfter; |
| 694 | if (!(flags & (SWP_NOZORDER | SWP_NOACTIVATE))) |
| 695 | { |
| 696 | /* Ignore TOPMOST flags when activating a window */ |
| 697 | /* _and_ moving it in Z order. */ |
| 698 | if ((hwndAfter == HWND_TOPMOST) || (hwndAfter == HWND_NOTOPMOST)) |
| 699 | hwndAfter = HWND_TOP; |
| 700 | } |
| 701 | /* TOPMOST not supported yet */ |
| 702 | if ((hwndAfter == HWND_TOPMOST) || (hwndAfter == HWND_NOTOPMOST)) |
| 703 | hwndAfter = HWND_TOP; |
| 704 | /* hwndAfter must be a sibling of the window */ |
| 705 | if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM) && |
| 706 | (GetParent(winpos->hwnd) != GetParent(hwndAfter))) return FALSE; |
| 707 | |
| 708 | /* Calculate new position and size */ |
| 709 | |
| 710 | newWindowRect = wndPtr->rectWindow; |
| 711 | newClientRect = wndPtr->rectClient; |
| 712 | |
| 713 | if (!(flags & SWP_NOSIZE)) |
| 714 | { |
| 715 | newWindowRect.right = newWindowRect.left + winpos->cx; |
| 716 | newWindowRect.bottom = newWindowRect.top + winpos->cy; |
| 717 | winChanges.width = winpos->cx; |
| 718 | winChanges.height = winpos->cy; |
| 719 | changeMask |= CWWidth | CWHeight; |
| 720 | } |
| 721 | if (!(flags & SWP_NOMOVE)) |
| 722 | { |
| 723 | newWindowRect.left = winpos->x; |
| 724 | newWindowRect.top = winpos->y; |
| 725 | newWindowRect.right += winpos->x - wndPtr->rectWindow.left; |
| 726 | newWindowRect.bottom += winpos->y - wndPtr->rectWindow.top; |
| 727 | if (wndPtr->dwStyle & WS_CHILD) |
| 728 | { |
| 729 | WND *parentPtr = WIN_FindWndPtr(wndPtr->hwndParent); |
| 730 | winChanges.x = winpos->x + parentPtr->rectClient.left |
| 731 | - parentPtr->rectWindow.left; |
| 732 | winChanges.y = winpos->y + parentPtr->rectClient.top |
| 733 | - parentPtr->rectWindow.top; |
| 734 | } |
| 735 | else |
| 736 | { |
| 737 | winChanges.x = winpos->x; |
| 738 | winChanges.y = winpos->y; |
| 739 | } |
| 740 | changeMask |= CWX | CWY; |
| 741 | } |
| 742 | |
| 743 | /* Reposition window in Z order */ |
| 744 | |
| 745 | if (!(flags & SWP_NOZORDER)) |
| 746 | { |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 747 | if (wndPtr->window) |
| 748 | { |
| 749 | WIN_UnlinkWindow( winpos->hwnd ); |
| 750 | WIN_LinkWindow( winpos->hwnd, hwndAfter ); |
| 751 | if (hwndAfter == HWND_TOP) winChanges.stack_mode = Above; |
| 752 | else winChanges.stack_mode = Below; |
| 753 | if ((hwndAfter != HWND_TOP) && (hwndAfter != HWND_BOTTOM)) |
| 754 | { |
| 755 | WND * insertPtr = WIN_FindWndPtr( hwndAfter ); |
| 756 | winChanges.sibling = insertPtr->window; |
| 757 | changeMask |= CWSibling; |
| 758 | } |
| 759 | changeMask |= CWStackMode; |
| 760 | } |
| 761 | else WINPOS_MoveWindowZOrder( winpos->hwnd, hwndAfter, |
| 762 | !(flags & SWP_DEFERERASE) ); |
Alexandre Julliard | 2d159fb | 1994-07-15 16:04:31 +0000 | [diff] [blame] | 763 | } |
| 764 | |
| 765 | /* Send WM_NCCALCSIZE message to get new client area */ |
| 766 | |
| 767 | result = WINPOS_SendNCCalcSize( winpos->hwnd, TRUE, &newWindowRect, |
| 768 | &wndPtr->rectWindow, &wndPtr->rectClient, |
| 769 | winpos, &newClientRect ); |
| 770 | /* .... Should handle result here */ |
| 771 | |
| 772 | /* Perform the moving and resizing */ |
| 773 | |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 774 | if (wndPtr->window) |
| 775 | { |
| 776 | if (changeMask) XConfigureWindow( display, wndPtr->window, |
| 777 | changeMask, &winChanges ); |
| 778 | wndPtr->rectWindow = newWindowRect; |
| 779 | wndPtr->rectClient = newClientRect; |
| 780 | } |
| 781 | else |
| 782 | { |
| 783 | RECT oldWindowRect = wndPtr->rectWindow; |
| 784 | |
| 785 | wndPtr->rectWindow = newWindowRect; |
| 786 | wndPtr->rectClient = newClientRect; |
| 787 | |
| 788 | if (changeMask) |
| 789 | { |
| 790 | HRGN hrgn1 = CreateRectRgnIndirect( &oldWindowRect ); |
| 791 | HRGN hrgn2 = CreateRectRgnIndirect( &wndPtr->rectWindow ); |
| 792 | HRGN hrgn3 = CreateRectRgn( 0, 0, 0, 0 ); |
| 793 | CombineRgn( hrgn3, hrgn1, hrgn2, RGN_DIFF ); |
| 794 | RedrawWindow( wndPtr->hwndParent, NULL, hrgn3, |
| 795 | RDW_INVALIDATE | RDW_ALLCHILDREN | RDW_ERASENOW ); |
| 796 | if ((oldWindowRect.left != wndPtr->rectWindow.left) || |
| 797 | (oldWindowRect.top != wndPtr->rectWindow.top)) |
| 798 | { |
| 799 | RedrawWindow( winpos->hwnd, NULL, 0, RDW_INVALIDATE | |
| 800 | RDW_FRAME | RDW_ALLCHILDREN | RDW_ERASENOW ); |
| 801 | } |
| 802 | DeleteObject( hrgn1 ); |
| 803 | DeleteObject( hrgn2 ); |
| 804 | DeleteObject( hrgn3 ); |
| 805 | } |
| 806 | } |
Alexandre Julliard | 2d159fb | 1994-07-15 16:04:31 +0000 | [diff] [blame] | 807 | |
| 808 | if (flags & SWP_SHOWWINDOW) |
| 809 | { |
| 810 | wndPtr->dwStyle |= WS_VISIBLE; |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 811 | if (wndPtr->window) |
| 812 | { |
| 813 | XMapWindow( display, wndPtr->window ); |
| 814 | MSG_Synchronize(); |
| 815 | if (flags & SWP_NOREDRAW) /* Validate the whole window */ |
| 816 | RedrawWindow( winpos->hwnd, NULL, 0, RDW_VALIDATE ); |
| 817 | } |
Alexandre Julliard | 2d159fb | 1994-07-15 16:04:31 +0000 | [diff] [blame] | 818 | } |
| 819 | else if (flags & SWP_HIDEWINDOW) |
| 820 | { |
| 821 | wndPtr->dwStyle &= ~WS_VISIBLE; |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 822 | if (wndPtr->window) |
| 823 | { |
| 824 | XUnmapWindow( display, wndPtr->window ); |
| 825 | } |
| 826 | else |
| 827 | { |
| 828 | RedrawWindow( wndPtr->hwndParent, &wndPtr->rectWindow, 0, |
| 829 | RDW_INVALIDATE | RDW_FRAME | |
| 830 | RDW_ALLCHILDREN | RDW_ERASENOW ); |
| 831 | } |
| 832 | if ((winpos->hwnd == GetFocus()) || IsChild(winpos->hwnd, GetFocus())) |
| 833 | SetFocus( GetParent(winpos->hwnd) ); /* Revert focus to parent */ |
Alexandre Julliard | 2d159fb | 1994-07-15 16:04:31 +0000 | [diff] [blame] | 834 | if (winpos->hwnd == hwndActive) |
| 835 | { |
| 836 | /* Activate previously active window if possible */ |
| 837 | HWND newActive = wndPtr->hwndPrevActive; |
| 838 | if (!IsWindow(newActive) || (newActive == winpos->hwnd)) |
| 839 | { |
| 840 | newActive = GetTopWindow(GetDesktopWindow()); |
| 841 | if (newActive == winpos->hwnd) newActive = wndPtr->hwndNext; |
| 842 | } |
| 843 | WINPOS_ChangeActiveWindow( newActive, FALSE ); |
| 844 | } |
| 845 | } |
| 846 | |
| 847 | /* Activate the window */ |
| 848 | |
| 849 | if (!(flags & SWP_NOACTIVATE)) |
| 850 | { |
| 851 | if (!(wndPtr->dwStyle & WS_CHILD)) |
| 852 | WINPOS_ChangeActiveWindow( winpos->hwnd, FALSE ); |
| 853 | } |
| 854 | |
| 855 | /* Send WM_NCPAINT message if needed */ |
| 856 | |
Alexandre Julliard | f720725 | 1994-07-23 07:57:48 +0000 | [diff] [blame] | 857 | if (flags & SWP_SHOWWINDOW) |
| 858 | { |
| 859 | /* Repaint the window frame and background */ |
| 860 | RedrawWindow( winpos->hwnd, NULL, 0, |
| 861 | RDW_INVALIDATE | RDW_FRAME | RDW_ERASENOW ); |
| 862 | } |
| 863 | else |
| 864 | { |
| 865 | if ((flags & SWP_FRAMECHANGED) || |
| 866 | (!(flags & SWP_NOSIZE)) || |
| 867 | (!(flags & SWP_NOMOVE)) || |
| 868 | (!(flags & SWP_NOACTIVATE)) || |
| 869 | (!(flags & SWP_NOZORDER))) |
| 870 | SendMessage( winpos->hwnd, WM_NCPAINT, 1, 0L ); |
| 871 | } |
Alexandre Julliard | 2d159fb | 1994-07-15 16:04:31 +0000 | [diff] [blame] | 872 | |
| 873 | /* And last, send the WM_WINDOWPOSCHANGED message */ |
| 874 | |
| 875 | SendMessage( winpos->hwnd, WM_WINDOWPOSCHANGED, 0, (LONG)winpos ); |
| 876 | return TRUE; |
| 877 | } |
| 878 | |
| 879 | |
| 880 | /*********************************************************************** |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 881 | * BeginDeferWindowPos (USER.259) |
| 882 | */ |
| 883 | HDWP BeginDeferWindowPos( INT count ) |
| 884 | { |
| 885 | HDWP handle; |
| 886 | DWP *pDWP; |
| 887 | |
| 888 | if (count <= 0) return 0; |
| 889 | handle = USER_HEAP_ALLOC( GMEM_MOVEABLE, |
| 890 | sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) ); |
| 891 | if (!handle) return 0; |
| 892 | pDWP = (DWP *) USER_HEAP_ADDR( handle ); |
| 893 | pDWP->actualCount = 0; |
| 894 | pDWP->suggestedCount = count; |
| 895 | pDWP->valid = TRUE; |
| 896 | pDWP->wMagic = DWP_MAGIC; |
| 897 | return handle; |
| 898 | } |
| 899 | |
| 900 | |
| 901 | /*********************************************************************** |
| 902 | * DeferWindowPos (USER.260) |
| 903 | */ |
| 904 | HDWP DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter, INT x, INT y, |
| 905 | INT cx, INT cy, WORD flags ) |
| 906 | { |
| 907 | DWP *pDWP; |
| 908 | int i; |
| 909 | HDWP newhdwp = hdwp; |
| 910 | |
| 911 | pDWP = (DWP *) USER_HEAP_ADDR( hdwp ); |
| 912 | if (!pDWP) return 0; |
| 913 | for (i = 0; i < pDWP->actualCount; i++) |
| 914 | { |
| 915 | if (pDWP->winPos[i].hwnd == hwnd) |
| 916 | { |
| 917 | /* Merge with the other changes */ |
| 918 | if (!(flags & SWP_NOZORDER)) |
| 919 | { |
| 920 | pDWP->winPos[i].hwndInsertAfter = hwndAfter; |
| 921 | } |
| 922 | if (!(flags & SWP_NOMOVE)) |
| 923 | { |
| 924 | pDWP->winPos[i].x = x; |
| 925 | pDWP->winPos[i].y = y; |
| 926 | } |
| 927 | if (!(flags & SWP_NOSIZE)) |
| 928 | { |
| 929 | pDWP->winPos[i].cx = cx; |
| 930 | pDWP->winPos[i].cy = cy; |
| 931 | } |
| 932 | pDWP->winPos[i].flags &= flags & (SWP_NOSIZE | SWP_NOMOVE | |
| 933 | SWP_NOZORDER | SWP_NOREDRAW | |
| 934 | SWP_NOACTIVATE | SWP_NOCOPYBITS | |
| 935 | SWP_NOOWNERZORDER); |
| 936 | pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW | |
| 937 | SWP_FRAMECHANGED); |
| 938 | return hdwp; |
| 939 | } |
| 940 | } |
| 941 | if (pDWP->actualCount >= pDWP->suggestedCount) |
| 942 | { |
| 943 | newhdwp = USER_HEAP_REALLOC( hdwp, |
| 944 | sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS), 0); |
| 945 | if (!newhdwp) return 0; |
| 946 | pDWP = (DWP *) USER_HEAP_ADDR( newhdwp ); |
| 947 | pDWP->suggestedCount++; |
| 948 | } |
| 949 | pDWP->winPos[pDWP->actualCount].hwnd = hwnd; |
| 950 | pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter; |
| 951 | pDWP->winPos[pDWP->actualCount].x = x; |
| 952 | pDWP->winPos[pDWP->actualCount].y = y; |
| 953 | pDWP->winPos[pDWP->actualCount].cx = cx; |
| 954 | pDWP->winPos[pDWP->actualCount].cy = cy; |
| 955 | pDWP->winPos[pDWP->actualCount].flags = flags; |
| 956 | pDWP->actualCount++; |
| 957 | return newhdwp; |
| 958 | } |
| 959 | |
| 960 | |
| 961 | /*********************************************************************** |
| 962 | * EndDeferWindowPos (USER.261) |
| 963 | */ |
| 964 | BOOL EndDeferWindowPos( HDWP hdwp ) |
| 965 | { |
| 966 | DWP *pDWP; |
| 967 | BOOL res = TRUE; |
| 968 | int i; |
| 969 | |
| 970 | pDWP = (DWP *) USER_HEAP_ADDR( hdwp ); |
| 971 | if (!pDWP) return FALSE; |
| 972 | for (i = 0; i < pDWP->actualCount; i++) |
| 973 | { |
| 974 | if (!(res = WINPOS_InternalSetWindowPos( &pDWP->winPos[i] ))) break; |
| 975 | } |
| 976 | USER_HEAP_FREE( hdwp ); |
| 977 | return res; |
| 978 | } |
| 979 | |
| 980 | |
| 981 | /*********************************************************************** |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 982 | * SetWindowPos (USER.232) |
| 983 | */ |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 984 | BOOL SetWindowPos( HWND hwnd, HWND hwndInsertAfter, INT x, INT y, |
| 985 | INT cx, INT cy, WORD flags ) |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 986 | { |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 987 | HDWP hdwp; |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 988 | |
| 989 | #ifdef DEBUG_WIN |
Alexandre Julliard | 1f57929 | 1994-05-25 16:25:21 +0000 | [diff] [blame] | 990 | printf( "SetWindowPos: %04X %d %d,%d %dx%d 0x%x\n", |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 991 | hwnd, hwndInsertAfter, x, y, cx, cy, flags ); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 992 | #endif |
Alexandre Julliard | aca0578 | 1994-10-17 18:12:41 +0000 | [diff] [blame^] | 993 | if (!(hdwp = BeginDeferWindowPos( 1 ))) return FALSE; |
| 994 | if (!(hdwp = DeferWindowPos( hdwp, hwnd, hwndInsertAfter, |
| 995 | x, y, cx, cy, flags ))) return FALSE; |
| 996 | return EndDeferWindowPos( hdwp ); |
Alexandre Julliard | 5f721f8 | 1994-01-04 20:14:34 +0000 | [diff] [blame] | 997 | } |