winpos.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. /*
  2. * Window position related functions.
  3. *
  4. * Copyright 1993, 1994, 1995 Alexandre Julliard
  5. * 1995, 1996, 1999 Alex Korobka
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21. #include "config.h"
  22. #include "wine/port.h"
  23. #include <stdarg.h>
  24. #include <string.h>
  25. #include "winerror.h"
  26. #include "windef.h"
  27. #include "winbase.h"
  28. #include "wingdi.h"
  29. #include "winerror.h"
  30. #include "ntstatus.h"
  31. #include "wine/winuser16.h"
  32. #include "wine/server.h"
  33. #include "controls.h"
  34. #include "user_private.h"
  35. #include "win.h"
  36. #include "message.h"
  37. #include "winpos.h"
  38. #include "wine/debug.h"
  39. WINE_DEFAULT_DEBUG_CHANNEL(win);
  40. #define HAS_DLGFRAME(style,exStyle) \
  41. (((exStyle) & WS_EX_DLGMODALFRAME) || \
  42. (((style) & WS_DLGFRAME) && !((style) & WS_BORDER)))
  43. #define HAS_THICKFRAME(style) \
  44. (((style) & WS_THICKFRAME) && \
  45. !(((style) & (WS_DLGFRAME|WS_BORDER)) == WS_DLGFRAME))
  46. #define EMPTYPOINT(pt) ((*(LONG*)&(pt)) == -1)
  47. #define PLACE_MIN 0x0001
  48. #define PLACE_MAX 0x0002
  49. #define PLACE_RECT 0x0004
  50. #define DWP_MAGIC ((INT)('W' | ('P' << 8) | ('O' << 16) | ('S' << 24)))
  51. typedef struct
  52. {
  53. INT actualCount;
  54. INT suggestedCount;
  55. BOOL valid;
  56. INT wMagic;
  57. HWND hwndParent;
  58. WINDOWPOS winPos[1];
  59. } DWP;
  60. typedef struct
  61. {
  62. RECT16 rectNormal;
  63. POINT16 ptIconPos;
  64. POINT16 ptMaxPos;
  65. HWND hwndIconTitle;
  66. } INTERNALPOS, *LPINTERNALPOS;
  67. /* ----- internal variables ----- */
  68. static LPCSTR atomInternalPos;
  69. /***********************************************************************
  70. * WINPOS_CreateInternalPosAtom
  71. */
  72. BOOL WINPOS_CreateInternalPosAtom()
  73. {
  74. LPCSTR str = "SysIP";
  75. atomInternalPos = (LPCSTR)(DWORD)GlobalAddAtomA(str);
  76. return (atomInternalPos) ? TRUE : FALSE;
  77. }
  78. /***********************************************************************
  79. * WINPOS_CheckInternalPos
  80. *
  81. * Called when a window is destroyed.
  82. */
  83. void WINPOS_CheckInternalPos( HWND hwnd )
  84. {
  85. LPINTERNALPOS lpPos = (LPINTERNALPOS) GetPropA( hwnd, atomInternalPos );
  86. if( lpPos )
  87. {
  88. if( IsWindow(lpPos->hwndIconTitle) )
  89. DestroyWindow( lpPos->hwndIconTitle );
  90. HeapFree( GetProcessHeap(), 0, lpPos );
  91. }
  92. }
  93. /***********************************************************************
  94. * ArrangeIconicWindows (USER32.@)
  95. */
  96. UINT WINAPI ArrangeIconicWindows( HWND parent )
  97. {
  98. RECT rectParent;
  99. HWND hwndChild;
  100. INT x, y, xspacing, yspacing;
  101. GetClientRect( parent, &rectParent );
  102. x = rectParent.left;
  103. y = rectParent.bottom;
  104. xspacing = GetSystemMetrics(SM_CXICONSPACING);
  105. yspacing = GetSystemMetrics(SM_CYICONSPACING);
  106. hwndChild = GetWindow( parent, GW_CHILD );
  107. while (hwndChild)
  108. {
  109. if( IsIconic( hwndChild ) )
  110. {
  111. WINPOS_ShowIconTitle( hwndChild, FALSE );
  112. SetWindowPos( hwndChild, 0, x + (xspacing - GetSystemMetrics(SM_CXICON)) / 2,
  113. y - yspacing - GetSystemMetrics(SM_CYICON)/2, 0, 0,
  114. SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
  115. if( IsWindow(hwndChild) )
  116. WINPOS_ShowIconTitle(hwndChild , TRUE );
  117. if (x <= rectParent.right - xspacing) x += xspacing;
  118. else
  119. {
  120. x = rectParent.left;
  121. y -= yspacing;
  122. }
  123. }
  124. hwndChild = GetWindow( hwndChild, GW_HWNDNEXT );
  125. }
  126. return yspacing;
  127. }
  128. /***********************************************************************
  129. * SwitchToThisWindow (USER32.@)
  130. */
  131. void WINAPI SwitchToThisWindow( HWND hwnd, BOOL restore )
  132. {
  133. ShowWindow( hwnd, restore ? SW_RESTORE : SW_SHOWMINIMIZED );
  134. }
  135. /***********************************************************************
  136. * GetWindowRect (USER32.@)
  137. */
  138. BOOL WINAPI GetWindowRect( HWND hwnd, LPRECT rect )
  139. {
  140. BOOL ret = WIN_GetRectangles( hwnd, rect, NULL );
  141. if (ret)
  142. {
  143. MapWindowPoints( GetAncestor( hwnd, GA_PARENT ), 0, (POINT *)rect, 2 );
  144. TRACE( "hwnd %p (%ld,%ld)-(%ld,%ld)\n",
  145. hwnd, rect->left, rect->top, rect->right, rect->bottom);
  146. }
  147. return ret;
  148. }
  149. /***********************************************************************
  150. * GetWindowRgn (USER32.@)
  151. */
  152. int WINAPI GetWindowRgn ( HWND hwnd, HRGN hrgn )
  153. {
  154. int nRet = ERROR;
  155. NTSTATUS status;
  156. HRGN win_rgn = 0;
  157. RGNDATA *data;
  158. size_t size = 256;
  159. do
  160. {
  161. if (!(data = HeapAlloc( GetProcessHeap(), 0, sizeof(*data) + size - 1 )))
  162. {
  163. SetLastError( ERROR_OUTOFMEMORY );
  164. return ERROR;
  165. }
  166. SERVER_START_REQ( get_window_region )
  167. {
  168. req->window = hwnd;
  169. wine_server_set_reply( req, data->Buffer, size );
  170. if (!(status = wine_server_call( req )))
  171. {
  172. size_t reply_size = wine_server_reply_size( reply );
  173. if (reply_size)
  174. {
  175. data->rdh.dwSize = sizeof(data->rdh);
  176. data->rdh.iType = RDH_RECTANGLES;
  177. data->rdh.nCount = reply_size / sizeof(RECT);
  178. data->rdh.nRgnSize = reply_size;
  179. win_rgn = ExtCreateRegion( NULL, size, data );
  180. }
  181. }
  182. else size = reply->total_size;
  183. }
  184. SERVER_END_REQ;
  185. HeapFree( GetProcessHeap(), 0, data );
  186. } while (status == STATUS_BUFFER_OVERFLOW);
  187. if (status) SetLastError( RtlNtStatusToDosError(status) );
  188. else if (win_rgn)
  189. {
  190. nRet = CombineRgn( hrgn, win_rgn, 0, RGN_COPY );
  191. DeleteObject( win_rgn );
  192. }
  193. return nRet;
  194. }
  195. /***********************************************************************
  196. * SetWindowRgn (USER32.@)
  197. */
  198. int WINAPI SetWindowRgn( HWND hwnd, HRGN hrgn, BOOL bRedraw )
  199. {
  200. static const RECT empty_rect;
  201. BOOL ret;
  202. if (hrgn)
  203. {
  204. RGNDATA *data;
  205. DWORD size;
  206. if (!(size = GetRegionData( hrgn, 0, NULL ))) return FALSE;
  207. if (!(data = HeapAlloc( GetProcessHeap(), 0, size ))) return FALSE;
  208. if (!GetRegionData( hrgn, size, data ))
  209. {
  210. HeapFree( GetProcessHeap(), 0, data );
  211. return FALSE;
  212. }
  213. SERVER_START_REQ( set_window_region )
  214. {
  215. req->window = hwnd;
  216. if (data->rdh.nCount)
  217. wine_server_add_data( req, data->Buffer, data->rdh.nCount * sizeof(RECT) );
  218. else
  219. wine_server_add_data( req, &empty_rect, sizeof(empty_rect) );
  220. ret = !wine_server_call_err( req );
  221. }
  222. SERVER_END_REQ;
  223. }
  224. else /* clear existing region */
  225. {
  226. SERVER_START_REQ( set_window_region )
  227. {
  228. req->window = hwnd;
  229. ret = !wine_server_call_err( req );
  230. }
  231. SERVER_END_REQ;
  232. }
  233. if (ret && USER_Driver.pSetWindowRgn)
  234. ret = USER_Driver.pSetWindowRgn( hwnd, hrgn, bRedraw );
  235. if (ret && bRedraw) RedrawWindow( hwnd, NULL, 0, RDW_FRAME | RDW_INVALIDATE | RDW_ERASE );
  236. return ret;
  237. }
  238. /***********************************************************************
  239. * GetClientRect (USER32.@)
  240. */
  241. BOOL WINAPI GetClientRect( HWND hwnd, LPRECT rect )
  242. {
  243. BOOL ret;
  244. if ((ret = WIN_GetRectangles( hwnd, NULL, rect )))
  245. {
  246. rect->right -= rect->left;
  247. rect->bottom -= rect->top;
  248. rect->left = rect->top = 0;
  249. }
  250. return ret;
  251. }
  252. /*******************************************************************
  253. * ClientToScreen (USER32.@)
  254. */
  255. BOOL WINAPI ClientToScreen( HWND hwnd, LPPOINT lppnt )
  256. {
  257. MapWindowPoints( hwnd, 0, lppnt, 1 );
  258. return TRUE;
  259. }
  260. /*******************************************************************
  261. * ScreenToClient (USER32.@)
  262. */
  263. BOOL WINAPI ScreenToClient( HWND hwnd, LPPOINT lppnt )
  264. {
  265. MapWindowPoints( 0, hwnd, lppnt, 1 );
  266. return TRUE;
  267. }
  268. /***********************************************************************
  269. * list_children_from_point
  270. *
  271. * Get the list of children that can contain point from the server.
  272. * Point is in screen coordinates.
  273. * Returned list must be freed by caller.
  274. */
  275. static HWND *list_children_from_point( HWND hwnd, POINT pt )
  276. {
  277. HWND *list;
  278. int size = 32;
  279. for (;;)
  280. {
  281. int count = 0;
  282. if (!(list = HeapAlloc( GetProcessHeap(), 0, size * sizeof(HWND) ))) break;
  283. SERVER_START_REQ( get_window_children_from_point )
  284. {
  285. req->parent = hwnd;
  286. req->x = pt.x;
  287. req->y = pt.y;
  288. wine_server_set_reply( req, list, (size-1) * sizeof(HWND) );
  289. if (!wine_server_call( req )) count = reply->count;
  290. }
  291. SERVER_END_REQ;
  292. if (count && count < size)
  293. {
  294. list[count] = 0;
  295. return list;
  296. }
  297. HeapFree( GetProcessHeap(), 0, list );
  298. if (!count) break;
  299. size = count + 1; /* restart with a large enough buffer */
  300. }
  301. return NULL;
  302. }
  303. /***********************************************************************
  304. * WINPOS_WindowFromPoint
  305. *
  306. * Find the window and hittest for a given point.
  307. */
  308. HWND WINPOS_WindowFromPoint( HWND hwndScope, POINT pt, INT *hittest )
  309. {
  310. int i, res;
  311. HWND ret, *list;
  312. if (!hwndScope) hwndScope = GetDesktopWindow();
  313. *hittest = HTNOWHERE;
  314. if (!(list = list_children_from_point( hwndScope, pt ))) return 0;
  315. /* now determine the hittest */
  316. for (i = 0; list[i]; i++)
  317. {
  318. LONG style = GetWindowLongW( list[i], GWL_STYLE );
  319. /* If window is minimized or disabled, return at once */
  320. if (style & WS_MINIMIZE)
  321. {
  322. *hittest = HTCAPTION;
  323. break;
  324. }
  325. if (style & WS_DISABLED)
  326. {
  327. *hittest = HTERROR;
  328. break;
  329. }
  330. /* Send WM_NCCHITTEST (if same thread) */
  331. if (!WIN_IsCurrentThread( list[i] ))
  332. {
  333. *hittest = HTCLIENT;
  334. break;
  335. }
  336. res = SendMessageA( list[i], WM_NCHITTEST, 0, MAKELONG(pt.x,pt.y) );
  337. if (res != HTTRANSPARENT)
  338. {
  339. *hittest = res; /* Found the window */
  340. break;
  341. }
  342. /* continue search with next window in z-order */
  343. }
  344. ret = list[i];
  345. HeapFree( GetProcessHeap(), 0, list );
  346. TRACE( "scope %p (%ld,%ld) returning %p\n", hwndScope, pt.x, pt.y, ret );
  347. return ret;
  348. }
  349. /*******************************************************************
  350. * WindowFromPoint (USER32.@)
  351. */
  352. HWND WINAPI WindowFromPoint( POINT pt )
  353. {
  354. INT hittest;
  355. return WINPOS_WindowFromPoint( 0, pt, &hittest );
  356. }
  357. /*******************************************************************
  358. * ChildWindowFromPoint (USER32.@)
  359. */
  360. HWND WINAPI ChildWindowFromPoint( HWND hwndParent, POINT pt )
  361. {
  362. return ChildWindowFromPointEx( hwndParent, pt, CWP_ALL );
  363. }
  364. /*******************************************************************
  365. * ChildWindowFromPointEx (USER32.@)
  366. */
  367. HWND WINAPI ChildWindowFromPointEx( HWND hwndParent, POINT pt, UINT uFlags)
  368. {
  369. /* pt is in the client coordinates */
  370. HWND *list;
  371. int i;
  372. RECT rect;
  373. HWND retvalue;
  374. GetClientRect( hwndParent, &rect );
  375. if (!PtInRect( &rect, pt )) return 0;
  376. if (!(list = WIN_ListChildren( hwndParent ))) return 0;
  377. for (i = 0; list[i]; i++)
  378. {
  379. if (!WIN_GetRectangles( list[i], &rect, NULL )) continue;
  380. if (!PtInRect( &rect, pt )) continue;
  381. if (uFlags & (CWP_SKIPINVISIBLE|CWP_SKIPDISABLED))
  382. {
  383. LONG style = GetWindowLongW( list[i], GWL_STYLE );
  384. if ((uFlags & CWP_SKIPINVISIBLE) && !(style & WS_VISIBLE)) continue;
  385. if ((uFlags & CWP_SKIPDISABLED) && (style & WS_DISABLED)) continue;
  386. }
  387. if (uFlags & CWP_SKIPTRANSPARENT)
  388. {
  389. if (GetWindowLongW( list[i], GWL_EXSTYLE ) & WS_EX_TRANSPARENT) continue;
  390. }
  391. break;
  392. }
  393. retvalue = list[i];
  394. HeapFree( GetProcessHeap(), 0, list );
  395. if (!retvalue) retvalue = hwndParent;
  396. return retvalue;
  397. }
  398. /*******************************************************************
  399. * WINPOS_GetWinOffset
  400. *
  401. * Calculate the offset between the origin of the two windows. Used
  402. * to implement MapWindowPoints.
  403. */
  404. static void WINPOS_GetWinOffset( HWND hwndFrom, HWND hwndTo, POINT *offset )
  405. {
  406. WND * wndPtr;
  407. offset->x = offset->y = 0;
  408. /* Translate source window origin to screen coords */
  409. if (hwndFrom)
  410. {
  411. HWND hwnd = hwndFrom;
  412. while (hwnd && hwnd != GetDesktopWindow())
  413. {
  414. if (hwnd == hwndTo) return;
  415. if (!(wndPtr = WIN_GetPtr( hwnd )))
  416. {
  417. ERR( "bad hwndFrom = %p\n", hwnd );
  418. return;
  419. }
  420. if (wndPtr == WND_OTHER_PROCESS) goto other_process;
  421. offset->x += wndPtr->rectClient.left;
  422. offset->y += wndPtr->rectClient.top;
  423. hwnd = wndPtr->parent;
  424. WIN_ReleasePtr( wndPtr );
  425. }
  426. }
  427. /* Translate origin to destination window coords */
  428. if (hwndTo)
  429. {
  430. HWND hwnd = hwndTo;
  431. while (hwnd && hwnd != GetDesktopWindow())
  432. {
  433. if (!(wndPtr = WIN_GetPtr( hwnd )))
  434. {
  435. ERR( "bad hwndTo = %p\n", hwnd );
  436. return;
  437. }
  438. if (wndPtr == WND_OTHER_PROCESS) goto other_process;
  439. offset->x -= wndPtr->rectClient.left;
  440. offset->y -= wndPtr->rectClient.top;
  441. hwnd = wndPtr->parent;
  442. WIN_ReleasePtr( wndPtr );
  443. }
  444. }
  445. return;
  446. other_process: /* one of the parents may belong to another process, do it the hard way */
  447. offset->x = offset->y = 0;
  448. SERVER_START_REQ( get_windows_offset )
  449. {
  450. req->from = hwndFrom;
  451. req->to = hwndTo;
  452. if (!wine_server_call( req ))
  453. {
  454. offset->x = reply->x;
  455. offset->y = reply->y;
  456. }
  457. }
  458. SERVER_END_REQ;
  459. }
  460. /*******************************************************************
  461. * MapWindowPoints (USER.258)
  462. */
  463. void WINAPI MapWindowPoints16( HWND16 hwndFrom, HWND16 hwndTo,
  464. LPPOINT16 lppt, UINT16 count )
  465. {
  466. POINT offset;
  467. WINPOS_GetWinOffset( WIN_Handle32(hwndFrom), WIN_Handle32(hwndTo), &offset );
  468. while (count--)
  469. {
  470. lppt->x += offset.x;
  471. lppt->y += offset.y;
  472. lppt++;
  473. }
  474. }
  475. /*******************************************************************
  476. * MapWindowPoints (USER32.@)
  477. */
  478. INT WINAPI MapWindowPoints( HWND hwndFrom, HWND hwndTo, LPPOINT lppt, UINT count )
  479. {
  480. POINT offset;
  481. WINPOS_GetWinOffset( hwndFrom, hwndTo, &offset );
  482. while (count--)
  483. {
  484. lppt->x += offset.x;
  485. lppt->y += offset.y;
  486. lppt++;
  487. }
  488. return MAKELONG( LOWORD(offset.x), LOWORD(offset.y) );
  489. }
  490. /***********************************************************************
  491. * IsIconic (USER32.@)
  492. */
  493. BOOL WINAPI IsIconic(HWND hWnd)
  494. {
  495. return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MINIMIZE) != 0;
  496. }
  497. /***********************************************************************
  498. * IsZoomed (USER32.@)
  499. */
  500. BOOL WINAPI IsZoomed(HWND hWnd)
  501. {
  502. return (GetWindowLongW( hWnd, GWL_STYLE ) & WS_MAXIMIZE) != 0;
  503. }
  504. /*******************************************************************
  505. * AllowSetForegroundWindow (USER32.@)
  506. */
  507. BOOL WINAPI AllowSetForegroundWindow( DWORD procid )
  508. {
  509. /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
  510. * implemented, then fix this function. */
  511. return TRUE;
  512. }
  513. /*******************************************************************
  514. * LockSetForegroundWindow (USER32.@)
  515. */
  516. BOOL WINAPI LockSetForegroundWindow( UINT lockcode )
  517. {
  518. /* FIXME: If Win98/2000 style SetForegroundWindow behavior is
  519. * implemented, then fix this function. */
  520. return TRUE;
  521. }
  522. /***********************************************************************
  523. * BringWindowToTop (USER32.@)
  524. */
  525. BOOL WINAPI BringWindowToTop( HWND hwnd )
  526. {
  527. return SetWindowPos( hwnd, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE );
  528. }
  529. /***********************************************************************
  530. * MoveWindow (USER32.@)
  531. */
  532. BOOL WINAPI MoveWindow( HWND hwnd, INT x, INT y, INT cx, INT cy,
  533. BOOL repaint )
  534. {
  535. int flags = SWP_NOZORDER | SWP_NOACTIVATE;
  536. if (!repaint) flags |= SWP_NOREDRAW;
  537. TRACE("%p %d,%d %dx%d %d\n", hwnd, x, y, cx, cy, repaint );
  538. return SetWindowPos( hwnd, 0, x, y, cx, cy, flags );
  539. }
  540. /***********************************************************************
  541. * WINPOS_InitInternalPos
  542. */
  543. static LPINTERNALPOS WINPOS_InitInternalPos( WND* wnd )
  544. {
  545. LPINTERNALPOS lpPos = GetPropA( wnd->hwndSelf, atomInternalPos );
  546. if( !lpPos )
  547. {
  548. /* this happens when the window is minimized/maximized
  549. * for the first time (rectWindow is not adjusted yet) */
  550. lpPos = HeapAlloc( GetProcessHeap(), 0, sizeof(INTERNALPOS) );
  551. if( !lpPos ) return NULL;
  552. SetPropA( wnd->hwndSelf, atomInternalPos, (HANDLE)lpPos );
  553. lpPos->hwndIconTitle = 0; /* defer until needs to be shown */
  554. lpPos->rectNormal.left = wnd->rectWindow.left;
  555. lpPos->rectNormal.top = wnd->rectWindow.top;
  556. lpPos->rectNormal.right = wnd->rectWindow.right;
  557. lpPos->rectNormal.bottom = wnd->rectWindow.bottom;
  558. lpPos->ptIconPos.x = lpPos->ptIconPos.y = -1;
  559. lpPos->ptMaxPos.x = lpPos->ptMaxPos.y = -1;
  560. }
  561. if( wnd->dwStyle & WS_MINIMIZE )
  562. {
  563. lpPos->ptIconPos.x = wnd->rectWindow.left;
  564. lpPos->ptIconPos.y = wnd->rectWindow.top;
  565. }
  566. else if( wnd->dwStyle & WS_MAXIMIZE )
  567. {
  568. lpPos->ptMaxPos.x = wnd->rectWindow.left;
  569. lpPos->ptMaxPos.y = wnd->rectWindow.top;
  570. }
  571. else
  572. {
  573. lpPos->rectNormal.left = wnd->rectWindow.left;
  574. lpPos->rectNormal.top = wnd->rectWindow.top;
  575. lpPos->rectNormal.right = wnd->rectWindow.right;
  576. lpPos->rectNormal.bottom = wnd->rectWindow.bottom;
  577. }
  578. return lpPos;
  579. }
  580. /***********************************************************************
  581. * WINPOS_RedrawIconTitle
  582. */
  583. BOOL WINPOS_RedrawIconTitle( HWND hWnd )
  584. {
  585. LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hWnd, atomInternalPos );
  586. if( lpPos )
  587. {
  588. if( lpPos->hwndIconTitle )
  589. {
  590. SendMessageA( lpPos->hwndIconTitle, WM_SHOWWINDOW, TRUE, 0);
  591. InvalidateRect( lpPos->hwndIconTitle, NULL, TRUE );
  592. return TRUE;
  593. }
  594. }
  595. return FALSE;
  596. }
  597. /***********************************************************************
  598. * WINPOS_ShowIconTitle
  599. */
  600. BOOL WINPOS_ShowIconTitle( HWND hwnd, BOOL bShow )
  601. {
  602. LPINTERNALPOS lpPos = (LPINTERNALPOS)GetPropA( hwnd, atomInternalPos );
  603. if (lpPos && !GetPropA( hwnd, "__wine_x11_managed" ))
  604. {
  605. HWND title = lpPos->hwndIconTitle;
  606. TRACE("%p %i\n", hwnd, (bShow != 0) );
  607. if( !title )
  608. lpPos->hwndIconTitle = title = ICONTITLE_Create( hwnd );
  609. if( bShow )
  610. {
  611. if (!IsWindowVisible(title))
  612. {
  613. SendMessageA( title, WM_SHOWWINDOW, TRUE, 0 );
  614. SetWindowPos( title, 0, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE |
  615. SWP_NOACTIVATE | SWP_NOZORDER | SWP_SHOWWINDOW );
  616. }
  617. }
  618. else ShowWindow( title, SW_HIDE );
  619. }
  620. return FALSE;
  621. }
  622. /*******************************************************************
  623. * WINPOS_GetMinMaxInfo
  624. *
  625. * Get the minimized and maximized information for a window.
  626. */
  627. void WINPOS_GetMinMaxInfo( HWND hwnd, POINT *maxSize, POINT *maxPos,
  628. POINT *minTrack, POINT *maxTrack )
  629. {
  630. LPINTERNALPOS lpPos;
  631. MINMAXINFO MinMax;
  632. INT xinc, yinc;
  633. LONG style = GetWindowLongA( hwnd, GWL_STYLE );
  634. LONG exstyle = GetWindowLongA( hwnd, GWL_EXSTYLE );
  635. RECT rc;
  636. /* Compute default values */
  637. GetWindowRect(hwnd, &rc);
  638. MinMax.ptReserved.x = rc.left;
  639. MinMax.ptReserved.y = rc.top;
  640. if (style & WS_CHILD)
  641. {
  642. if ((style & WS_CAPTION) == WS_CAPTION)
  643. style &= ~WS_BORDER; /* WS_CAPTION = WS_DLGFRAME | WS_BORDER */
  644. GetClientRect(GetParent(hwnd), &rc);
  645. AdjustWindowRectEx(&rc, style, 0, exstyle);
  646. /* avoid calculating this twice */
  647. style &= ~(WS_DLGFRAME | WS_BORDER | WS_THICKFRAME);
  648. MinMax.ptMaxSize.x = rc.right - rc.left;
  649. MinMax.ptMaxSize.y = rc.bottom - rc.top;
  650. }
  651. else
  652. {
  653. MinMax.ptMaxSize.x = GetSystemMetrics(SM_CXSCREEN);
  654. MinMax.ptMaxSize.y = GetSystemMetrics(SM_CYSCREEN);
  655. }
  656. MinMax.ptMinTrackSize.x = GetSystemMetrics(SM_CXMINTRACK);
  657. MinMax.ptMinTrackSize.y = GetSystemMetrics(SM_CYMINTRACK);
  658. MinMax.ptMaxTrackSize.x = GetSystemMetrics(SM_CXSCREEN) + 2*GetSystemMetrics(SM_CXFRAME);
  659. MinMax.ptMaxTrackSize.y = GetSystemMetrics(SM_CYSCREEN) + 2*GetSystemMetrics(SM_CYFRAME);
  660. if (HAS_DLGFRAME( style, exstyle ))
  661. {
  662. xinc = GetSystemMetrics(SM_CXDLGFRAME);
  663. yinc = GetSystemMetrics(SM_CYDLGFRAME);
  664. }
  665. else
  666. {
  667. xinc = yinc = 0;
  668. if (HAS_THICKFRAME(style))
  669. {
  670. xinc += GetSystemMetrics(SM_CXFRAME);
  671. yinc += GetSystemMetrics(SM_CYFRAME);
  672. }
  673. if (style & WS_BORDER)
  674. {
  675. xinc += GetSystemMetrics(SM_CXBORDER);
  676. yinc += GetSystemMetrics(SM_CYBORDER);
  677. }
  678. }
  679. MinMax.ptMaxSize.x += 2 * xinc;
  680. MinMax.ptMaxSize.y += 2 * yinc;
  681. lpPos = (LPINTERNALPOS)GetPropA( hwnd, atomInternalPos );
  682. if( lpPos && !EMPTYPOINT(lpPos->ptMaxPos) )
  683. {
  684. MinMax.ptMaxPosition.x = lpPos->ptMaxPos.x;
  685. MinMax.ptMaxPosition.y = lpPos->ptMaxPos.y;
  686. }
  687. else
  688. {
  689. MinMax.ptMaxPosition.x = -xinc;
  690. MinMax.ptMaxPosition.y = -yinc;
  691. }
  692. SendMessageA( hwnd, WM_GETMINMAXINFO, 0, (LPARAM)&MinMax );
  693. /* Some sanity checks */
  694. TRACE("%ld %ld / %ld %ld / %ld %ld / %ld %ld\n",
  695. MinMax.ptMaxSize.x, MinMax.ptMaxSize.y,
  696. MinMax.ptMaxPosition.x, MinMax.ptMaxPosition.y,
  697. MinMax.ptMaxTrackSize.x, MinMax.ptMaxTrackSize.y,
  698. MinMax.ptMinTrackSize.x, MinMax.ptMinTrackSize.y);
  699. MinMax.ptMaxTrackSize.x = max( MinMax.ptMaxTrackSize.x,
  700. MinMax.ptMinTrackSize.x );
  701. MinMax.ptMaxTrackSize.y = max( MinMax.ptMaxTrackSize.y,
  702. MinMax.ptMinTrackSize.y );
  703. if (maxSize) *maxSize = MinMax.ptMaxSize;
  704. if (maxPos) *maxPos = MinMax.ptMaxPosition;
  705. if (minTrack) *minTrack = MinMax.ptMinTrackSize;
  706. if (maxTrack) *maxTrack = MinMax.ptMaxTrackSize;
  707. }
  708. /***********************************************************************
  709. * ShowWindowAsync (USER32.@)
  710. *
  711. * doesn't wait; returns immediately.
  712. * used by threads to toggle windows in other (possibly hanging) threads
  713. */
  714. BOOL WINAPI ShowWindowAsync( HWND hwnd, INT cmd )
  715. {
  716. HWND full_handle;
  717. if (is_broadcast(hwnd))
  718. {
  719. SetLastError( ERROR_INVALID_PARAMETER );
  720. return FALSE;
  721. }
  722. if ((full_handle = WIN_IsCurrentThread( hwnd )))
  723. {
  724. if (USER_Driver.pShowWindow)
  725. return USER_Driver.pShowWindow( full_handle, cmd );
  726. return FALSE;
  727. }
  728. return SendNotifyMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
  729. }
  730. /***********************************************************************
  731. * ShowWindow (USER32.@)
  732. */
  733. BOOL WINAPI ShowWindow( HWND hwnd, INT cmd )
  734. {
  735. HWND full_handle;
  736. if (is_broadcast(hwnd))
  737. {
  738. SetLastError( ERROR_INVALID_PARAMETER );
  739. return FALSE;
  740. }
  741. if ((full_handle = WIN_IsCurrentThread( hwnd )))
  742. {
  743. if (USER_Driver.pShowWindow)
  744. return USER_Driver.pShowWindow( full_handle, cmd );
  745. return FALSE;
  746. }
  747. return SendMessageW( hwnd, WM_WINE_SHOWWINDOW, cmd, 0 );
  748. }
  749. /***********************************************************************
  750. * GetInternalWindowPos (USER32.@)
  751. */
  752. UINT WINAPI GetInternalWindowPos( HWND hwnd, LPRECT rectWnd,
  753. LPPOINT ptIcon )
  754. {
  755. WINDOWPLACEMENT wndpl;
  756. if (GetWindowPlacement( hwnd, &wndpl ))
  757. {
  758. if (rectWnd) *rectWnd = wndpl.rcNormalPosition;
  759. if (ptIcon) *ptIcon = wndpl.ptMinPosition;
  760. return wndpl.showCmd;
  761. }
  762. return 0;
  763. }
  764. /***********************************************************************
  765. * GetWindowPlacement (USER32.@)
  766. *
  767. * Win95:
  768. * Fails if wndpl->length of Win95 (!) apps is invalid.
  769. */
  770. BOOL WINAPI GetWindowPlacement( HWND hwnd, WINDOWPLACEMENT *wndpl )
  771. {
  772. WND *pWnd = WIN_GetPtr( hwnd );
  773. LPINTERNALPOS lpPos;
  774. if (!pWnd) return FALSE;
  775. if (pWnd == WND_OTHER_PROCESS)
  776. {
  777. if (IsWindow( hwnd )) FIXME( "not supported on other process window %p\n", hwnd );
  778. return FALSE;
  779. }
  780. lpPos = WINPOS_InitInternalPos( pWnd );
  781. wndpl->length = sizeof(*wndpl);
  782. if( pWnd->dwStyle & WS_MINIMIZE )
  783. wndpl->showCmd = SW_SHOWMINIMIZED;
  784. else
  785. wndpl->showCmd = ( pWnd->dwStyle & WS_MAXIMIZE ) ? SW_SHOWMAXIMIZED : SW_SHOWNORMAL ;
  786. if( pWnd->flags & WIN_RESTORE_MAX )
  787. wndpl->flags = WPF_RESTORETOMAXIMIZED;
  788. else
  789. wndpl->flags = 0;
  790. wndpl->ptMinPosition.x = lpPos->ptIconPos.x;
  791. wndpl->ptMinPosition.y = lpPos->ptIconPos.y;
  792. wndpl->ptMaxPosition.x = lpPos->ptMaxPos.x;
  793. wndpl->ptMaxPosition.y = lpPos->ptMaxPos.y;
  794. wndpl->rcNormalPosition.left = lpPos->rectNormal.left;
  795. wndpl->rcNormalPosition.top = lpPos->rectNormal.top;
  796. wndpl->rcNormalPosition.right = lpPos->rectNormal.right;
  797. wndpl->rcNormalPosition.bottom = lpPos->rectNormal.bottom;
  798. WIN_ReleasePtr( pWnd );
  799. return TRUE;
  800. }
  801. /***********************************************************************
  802. * WINPOS_SetPlacement
  803. */
  804. static BOOL WINPOS_SetPlacement( HWND hwnd, const WINDOWPLACEMENT *wndpl, UINT flags )
  805. {
  806. LPINTERNALPOS lpPos;
  807. DWORD style;
  808. WND *pWnd = WIN_GetPtr( hwnd );
  809. if (!pWnd || pWnd == WND_OTHER_PROCESS) return FALSE;
  810. lpPos = WINPOS_InitInternalPos( pWnd );
  811. if( flags & PLACE_MIN )
  812. {
  813. lpPos->ptIconPos.x = wndpl->ptMinPosition.x;
  814. lpPos->ptIconPos.y = wndpl->ptMinPosition.y;
  815. }
  816. if( flags & PLACE_MAX )
  817. {
  818. lpPos->ptMaxPos.x = wndpl->ptMaxPosition.x;
  819. lpPos->ptMaxPos.y = wndpl->ptMaxPosition.y;
  820. }
  821. if( flags & PLACE_RECT)
  822. {
  823. lpPos->rectNormal.left = wndpl->rcNormalPosition.left;
  824. lpPos->rectNormal.top = wndpl->rcNormalPosition.top;
  825. lpPos->rectNormal.right = wndpl->rcNormalPosition.right;
  826. lpPos->rectNormal.bottom = wndpl->rcNormalPosition.bottom;
  827. }
  828. style = pWnd->dwStyle;
  829. WIN_ReleasePtr( pWnd );
  830. if( style & WS_MINIMIZE )
  831. {
  832. WINPOS_ShowIconTitle( hwnd, FALSE );
  833. if( wndpl->flags & WPF_SETMINPOSITION && !EMPTYPOINT(lpPos->ptIconPos))
  834. SetWindowPos( hwnd, 0, lpPos->ptIconPos.x, lpPos->ptIconPos.y,
  835. 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
  836. }
  837. else if( style & WS_MAXIMIZE )
  838. {
  839. if( !EMPTYPOINT(lpPos->ptMaxPos) )
  840. SetWindowPos( hwnd, 0, lpPos->ptMaxPos.x, lpPos->ptMaxPos.y,
  841. 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
  842. }
  843. else if( flags & PLACE_RECT )
  844. SetWindowPos( hwnd, 0, lpPos->rectNormal.left, lpPos->rectNormal.top,
  845. lpPos->rectNormal.right - lpPos->rectNormal.left,
  846. lpPos->rectNormal.bottom - lpPos->rectNormal.top,
  847. SWP_NOZORDER | SWP_NOACTIVATE );
  848. ShowWindow( hwnd, wndpl->showCmd );
  849. if (IsIconic( hwnd ))
  850. {
  851. if (GetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE) WINPOS_ShowIconTitle( hwnd, TRUE );
  852. /* SDK: ...valid only the next time... */
  853. if( wndpl->flags & WPF_RESTORETOMAXIMIZED )
  854. {
  855. pWnd = WIN_GetPtr( hwnd );
  856. if (pWnd && pWnd != WND_OTHER_PROCESS)
  857. {
  858. pWnd->flags |= WIN_RESTORE_MAX;
  859. WIN_ReleasePtr( pWnd );
  860. }
  861. }
  862. }
  863. return TRUE;
  864. }
  865. /***********************************************************************
  866. * SetWindowPlacement (USER32.@)
  867. *
  868. * Win95:
  869. * Fails if wndpl->length of Win95 (!) apps is invalid.
  870. */
  871. BOOL WINAPI SetWindowPlacement( HWND hwnd, const WINDOWPLACEMENT *wpl )
  872. {
  873. if (!wpl) return FALSE;
  874. return WINPOS_SetPlacement( hwnd, wpl, PLACE_MIN | PLACE_MAX | PLACE_RECT );
  875. }
  876. /***********************************************************************
  877. * AnimateWindow (USER32.@)
  878. * Shows/Hides a window with an animation
  879. * NO ANIMATION YET
  880. */
  881. BOOL WINAPI AnimateWindow(HWND hwnd, DWORD dwTime, DWORD dwFlags)
  882. {
  883. FIXME("partial stub\n");
  884. /* If trying to show/hide and it's already *
  885. * shown/hidden or invalid window, fail with *
  886. * invalid parameter */
  887. if(!IsWindow(hwnd) ||
  888. (IsWindowVisible(hwnd) && !(dwFlags & AW_HIDE)) ||
  889. (!IsWindowVisible(hwnd) && (dwFlags & AW_HIDE)))
  890. {
  891. SetLastError(ERROR_INVALID_PARAMETER);
  892. return FALSE;
  893. }
  894. ShowWindow(hwnd, (dwFlags & AW_HIDE) ? SW_HIDE : ((dwFlags & AW_ACTIVATE) ? SW_SHOW : SW_SHOWNA));
  895. return TRUE;
  896. }
  897. /***********************************************************************
  898. * SetInternalWindowPos (USER32.@)
  899. */
  900. void WINAPI SetInternalWindowPos( HWND hwnd, UINT showCmd,
  901. LPRECT rect, LPPOINT pt )
  902. {
  903. if( IsWindow(hwnd) )
  904. {
  905. WINDOWPLACEMENT wndpl;
  906. UINT flags;
  907. wndpl.length = sizeof(wndpl);
  908. wndpl.showCmd = showCmd;
  909. wndpl.flags = flags = 0;
  910. if( pt )
  911. {
  912. flags |= PLACE_MIN;
  913. wndpl.flags |= WPF_SETMINPOSITION;
  914. wndpl.ptMinPosition = *pt;
  915. }
  916. if( rect )
  917. {
  918. flags |= PLACE_RECT;
  919. wndpl.rcNormalPosition = *rect;
  920. }
  921. WINPOS_SetPlacement( hwnd, &wndpl, flags );
  922. }
  923. }
  924. /*******************************************************************
  925. * can_activate_window
  926. *
  927. * Check if we can activate the specified window.
  928. */
  929. static BOOL can_activate_window( HWND hwnd )
  930. {
  931. LONG style;
  932. if (!hwnd) return FALSE;
  933. style = GetWindowLongW( hwnd, GWL_STYLE );
  934. if (!(style & WS_VISIBLE)) return FALSE;
  935. if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE;
  936. return !(style & WS_DISABLED);
  937. }
  938. /*******************************************************************
  939. * WINPOS_ActivateOtherWindow
  940. *
  941. * Activates window other than pWnd.
  942. */
  943. void WINPOS_ActivateOtherWindow(HWND hwnd)
  944. {
  945. HWND hwndTo, fg;
  946. if ((GetWindowLongW( hwnd, GWL_STYLE ) & WS_POPUP) && (hwndTo = GetWindow( hwnd, GW_OWNER )))
  947. {
  948. hwndTo = GetAncestor( hwndTo, GA_ROOT );
  949. if (can_activate_window( hwndTo )) goto done;
  950. }
  951. hwndTo = hwnd;
  952. for (;;)
  953. {
  954. if (!(hwndTo = GetWindow( hwndTo, GW_HWNDNEXT ))) break;
  955. if (can_activate_window( hwndTo )) break;
  956. }
  957. done:
  958. fg = GetForegroundWindow();
  959. TRACE("win = %p fg = %p\n", hwndTo, fg);
  960. if (!fg || (hwnd == fg))
  961. {
  962. if (SetForegroundWindow( hwndTo )) return;
  963. }
  964. if (!SetActiveWindow( hwndTo )) SetActiveWindow(0);
  965. }
  966. /***********************************************************************
  967. * WINPOS_HandleWindowPosChanging
  968. *
  969. * Default handling for a WM_WINDOWPOSCHANGING. Called from DefWindowProc().
  970. */
  971. LONG WINPOS_HandleWindowPosChanging( HWND hwnd, WINDOWPOS *winpos )
  972. {
  973. POINT minTrack, maxTrack;
  974. LONG style = GetWindowLongW( hwnd, GWL_STYLE );
  975. if (winpos->flags & SWP_NOSIZE) return 0;
  976. if ((style & WS_THICKFRAME) || ((style & (WS_POPUP | WS_CHILD)) == 0))
  977. {
  978. WINPOS_GetMinMaxInfo( hwnd, NULL, NULL, &minTrack, &maxTrack );
  979. if (winpos->cx > maxTrack.x) winpos->cx = maxTrack.x;
  980. if (winpos->cy > maxTrack.y) winpos->cy = maxTrack.y;
  981. if (!(style & WS_MINIMIZE))
  982. {
  983. if (winpos->cx < minTrack.x ) winpos->cx = minTrack.x;
  984. if (winpos->cy < minTrack.y ) winpos->cy = minTrack.y;
  985. }
  986. }
  987. return 0;
  988. }
  989. /***********************************************************************
  990. * dump_winpos_flags
  991. */
  992. static void dump_winpos_flags(UINT flags)
  993. {
  994. TRACE("flags:");
  995. if(flags & SWP_NOSIZE) TRACE(" SWP_NOSIZE");
  996. if(flags & SWP_NOMOVE) TRACE(" SWP_NOMOVE");
  997. if(flags & SWP_NOZORDER) TRACE(" SWP_NOZORDER");
  998. if(flags & SWP_NOREDRAW) TRACE(" SWP_NOREDRAW");
  999. if(flags & SWP_NOACTIVATE) TRACE(" SWP_NOACTIVATE");
  1000. if(flags & SWP_FRAMECHANGED) TRACE(" SWP_FRAMECHANGED");
  1001. if(flags & SWP_SHOWWINDOW) TRACE(" SWP_SHOWWINDOW");
  1002. if(flags & SWP_HIDEWINDOW) TRACE(" SWP_HIDEWINDOW");
  1003. if(flags & SWP_NOCOPYBITS) TRACE(" SWP_NOCOPYBITS");
  1004. if(flags & SWP_NOOWNERZORDER) TRACE(" SWP_NOOWNERZORDER");
  1005. if(flags & SWP_NOSENDCHANGING) TRACE(" SWP_NOSENDCHANGING");
  1006. if(flags & SWP_DEFERERASE) TRACE(" SWP_DEFERERASE");
  1007. if(flags & SWP_ASYNCWINDOWPOS) TRACE(" SWP_ASYNCWINDOWPOS");
  1008. #define DUMPED_FLAGS \
  1009. (SWP_NOSIZE | \
  1010. SWP_NOMOVE | \
  1011. SWP_NOZORDER | \
  1012. SWP_NOREDRAW | \
  1013. SWP_NOACTIVATE | \
  1014. SWP_FRAMECHANGED | \
  1015. SWP_SHOWWINDOW | \
  1016. SWP_HIDEWINDOW | \
  1017. SWP_NOCOPYBITS | \
  1018. SWP_NOOWNERZORDER | \
  1019. SWP_NOSENDCHANGING | \
  1020. SWP_DEFERERASE | \
  1021. SWP_ASYNCWINDOWPOS)
  1022. if(flags & ~DUMPED_FLAGS) TRACE(" %08x", flags & ~DUMPED_FLAGS);
  1023. TRACE("\n");
  1024. #undef DUMPED_FLAGS
  1025. }
  1026. /***********************************************************************
  1027. * SetWindowPos (USER32.@)
  1028. */
  1029. BOOL WINAPI SetWindowPos( HWND hwnd, HWND hwndInsertAfter,
  1030. INT x, INT y, INT cx, INT cy, UINT flags )
  1031. {
  1032. WINDOWPOS winpos;
  1033. TRACE("hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
  1034. hwnd, hwndInsertAfter, x, y, cx, cy, flags);
  1035. if(TRACE_ON(win)) dump_winpos_flags(flags);
  1036. if (is_broadcast(hwnd))
  1037. {
  1038. SetLastError( ERROR_INVALID_PARAMETER );
  1039. return FALSE;
  1040. }
  1041. winpos.hwnd = WIN_GetFullHandle(hwnd);
  1042. winpos.hwndInsertAfter = WIN_GetFullHandle(hwndInsertAfter);
  1043. winpos.x = x;
  1044. winpos.y = y;
  1045. winpos.cx = cx;
  1046. winpos.cy = cy;
  1047. winpos.flags = flags;
  1048. if (WIN_IsCurrentThread( hwnd ))
  1049. {
  1050. if (USER_Driver.pSetWindowPos)
  1051. return USER_Driver.pSetWindowPos( &winpos );
  1052. return FALSE;
  1053. }
  1054. return SendMessageW( winpos.hwnd, WM_WINE_SETWINDOWPOS, 0, (LPARAM)&winpos );
  1055. }
  1056. /***********************************************************************
  1057. * BeginDeferWindowPos (USER32.@)
  1058. */
  1059. HDWP WINAPI BeginDeferWindowPos( INT count )
  1060. {
  1061. HDWP handle;
  1062. DWP *pDWP;
  1063. TRACE("%d\n", count);
  1064. if (count < 0)
  1065. {
  1066. SetLastError(ERROR_INVALID_PARAMETER);
  1067. return 0;
  1068. }
  1069. /* Windows allows zero count, in which case it allocates context for 8 moves */
  1070. if (count == 0) count = 8;
  1071. handle = USER_HEAP_ALLOC( sizeof(DWP) + (count-1)*sizeof(WINDOWPOS) );
  1072. if (!handle) return 0;
  1073. pDWP = (DWP *) USER_HEAP_LIN_ADDR( handle );
  1074. pDWP->actualCount = 0;
  1075. pDWP->suggestedCount = count;
  1076. pDWP->valid = TRUE;
  1077. pDWP->wMagic = DWP_MAGIC;
  1078. pDWP->hwndParent = 0;
  1079. TRACE("returning hdwp %p\n", handle);
  1080. return handle;
  1081. }
  1082. /***********************************************************************
  1083. * DeferWindowPos (USER32.@)
  1084. */
  1085. HDWP WINAPI DeferWindowPos( HDWP hdwp, HWND hwnd, HWND hwndAfter,
  1086. INT x, INT y, INT cx, INT cy,
  1087. UINT flags )
  1088. {
  1089. DWP *pDWP;
  1090. int i;
  1091. HDWP newhdwp = hdwp,retvalue;
  1092. TRACE("hdwp %p, hwnd %p, after %p, %d,%d (%dx%d), flags %08x\n",
  1093. hdwp, hwnd, hwndAfter, x, y, cx, cy, flags);
  1094. hwnd = WIN_GetFullHandle( hwnd );
  1095. if (hwnd == GetDesktopWindow()) return 0;
  1096. if (!(pDWP = USER_HEAP_LIN_ADDR( hdwp ))) return 0;
  1097. USER_Lock();
  1098. for (i = 0; i < pDWP->actualCount; i++)
  1099. {
  1100. if (pDWP->winPos[i].hwnd == hwnd)
  1101. {
  1102. /* Merge with the other changes */
  1103. if (!(flags & SWP_NOZORDER))
  1104. {
  1105. pDWP->winPos[i].hwndInsertAfter = WIN_GetFullHandle(hwndAfter);
  1106. }
  1107. if (!(flags & SWP_NOMOVE))
  1108. {
  1109. pDWP->winPos[i].x = x;
  1110. pDWP->winPos[i].y = y;
  1111. }
  1112. if (!(flags & SWP_NOSIZE))
  1113. {
  1114. pDWP->winPos[i].cx = cx;
  1115. pDWP->winPos[i].cy = cy;
  1116. }
  1117. pDWP->winPos[i].flags &= flags | ~(SWP_NOSIZE | SWP_NOMOVE |
  1118. SWP_NOZORDER | SWP_NOREDRAW |
  1119. SWP_NOACTIVATE | SWP_NOCOPYBITS|
  1120. SWP_NOOWNERZORDER);
  1121. pDWP->winPos[i].flags |= flags & (SWP_SHOWWINDOW | SWP_HIDEWINDOW |
  1122. SWP_FRAMECHANGED);
  1123. retvalue = hdwp;
  1124. goto END;
  1125. }
  1126. }
  1127. if (pDWP->actualCount >= pDWP->suggestedCount)
  1128. {
  1129. newhdwp = USER_HEAP_REALLOC( hdwp,
  1130. sizeof(DWP) + pDWP->suggestedCount*sizeof(WINDOWPOS) );
  1131. if (!newhdwp)
  1132. {
  1133. retvalue = 0;
  1134. goto END;
  1135. }
  1136. pDWP = (DWP *) USER_HEAP_LIN_ADDR( newhdwp );
  1137. pDWP->suggestedCount++;
  1138. }
  1139. pDWP->winPos[pDWP->actualCount].hwnd = hwnd;
  1140. pDWP->winPos[pDWP->actualCount].hwndInsertAfter = hwndAfter;
  1141. pDWP->winPos[pDWP->actualCount].x = x;
  1142. pDWP->winPos[pDWP->actualCount].y = y;
  1143. pDWP->winPos[pDWP->actualCount].cx = cx;
  1144. pDWP->winPos[pDWP->actualCount].cy = cy;
  1145. pDWP->winPos[pDWP->actualCount].flags = flags;
  1146. pDWP->actualCount++;
  1147. retvalue = newhdwp;
  1148. END:
  1149. USER_Unlock();
  1150. return retvalue;
  1151. }
  1152. /***********************************************************************
  1153. * EndDeferWindowPos (USER32.@)
  1154. */
  1155. BOOL WINAPI EndDeferWindowPos( HDWP hdwp )
  1156. {
  1157. DWP *pDWP;
  1158. WINDOWPOS *winpos;
  1159. BOOL res = TRUE;
  1160. int i;
  1161. TRACE("%p\n", hdwp);
  1162. pDWP = (DWP *) USER_HEAP_LIN_ADDR( hdwp );
  1163. if (!pDWP) return FALSE;
  1164. for (i = 0, winpos = pDWP->winPos; i < pDWP->actualCount; i++, winpos++)
  1165. {
  1166. if (!USER_Driver.pSetWindowPos || !(res = USER_Driver.pSetWindowPos( winpos ))) break;
  1167. }
  1168. USER_HEAP_FREE( hdwp );
  1169. return res;
  1170. }
  1171. /***********************************************************************
  1172. * TileChildWindows (USER.199)
  1173. */
  1174. void WINAPI TileChildWindows16( HWND16 parent, WORD action )
  1175. {
  1176. FIXME("(%04x, %d): stub\n", parent, action);
  1177. }
  1178. /***********************************************************************
  1179. * CascadeChildWindows (USER.198)
  1180. */
  1181. void WINAPI CascadeChildWindows16( HWND16 parent, WORD action )
  1182. {
  1183. FIXME("(%04x, %d): stub\n", parent, action);
  1184. }