Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

607 lines
19 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: showwin.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * Contains the xxxShowWindow API and related functions.
  7. *
  8. * History:
  9. * 10-20-90 darrinm Created.
  10. * 02-04-91 IanJa Window handle revalidation added
  11. \***************************************************************************/
  12. #include "precomp.h"
  13. #pragma hdrstop
  14. /***************************************************************************\
  15. * _ShowWindowAsync
  16. *
  17. * This queues a show window event in another thread's queue. Used mainly from
  18. * within taskmgr, so that taskmgr doesn't hang waiting on hung apps.
  19. *
  20. * 04-23-93 ScottLu Created.
  21. \***************************************************************************/
  22. BOOL _ShowWindowAsync(PWND pwnd, int cmdShow, UINT uWPFlags)
  23. {
  24. return PostEventMessage(
  25. GETPTI(pwnd),
  26. GETPTI(pwnd)->pq,
  27. QEVENT_SHOWWINDOW,
  28. NULL,
  29. uWPFlags,
  30. (WPARAM)HWq(pwnd),
  31. cmdShow | TEST_PUDF(PUDF_ANIMATE));
  32. }
  33. /***************************************************************************\
  34. * xxxShowWindow (API)
  35. *
  36. * This function changes the "state" of a window based upon the cmdShow
  37. * parameter. The action taken is:
  38. *
  39. * SW_HIDE 0 Hide the window and pass avtivation to someone else
  40. *
  41. * SW_SHOWNORMAL 1 Show a window in its most recent "normal"
  42. * SW_RESTORE size and position. This will "restore" a iconic
  43. * or zoomed window. This is compatible with 1.03
  44. * SHOW_OPENWINDOW. This will also activate the window.
  45. *
  46. * SW_SHOWMINIMIZED 2 Show the window as iconic and make it active.
  47. *
  48. * SW_SHOWMAXIMIZED 3 Show the window as maximized and make it active.
  49. *
  50. * SW_SHOWNOACTIVATE 4 Same as SW_SHOWNORMAL except that it doesn't change
  51. * the activation (currently active window stays active).
  52. *
  53. * All the above are compatible with 1.03 ShowWindow parameters. Now here are
  54. * the new ones:
  55. *
  56. * SW_SHOW 5 Show the window in its current state (iconic, etc.)
  57. * That is, if the window is iconic when hidden, it will
  58. * still be iconic. This will activate the window.
  59. * (This is one we don't have today)
  60. *
  61. * SW_MINIMIZE 6 minimize the window, activate the toplevel open window
  62. *
  63. * SW_SHOWMINNOACTIVE 7 show the icon, don't change activation.
  64. *
  65. * SW_SHOWNA 8 Same as SW_SHOW except that it doesn't change
  66. * the activation.
  67. *
  68. * SW_SHOWDEFAULT 10 Use value obtained from STARTUPINFO.
  69. *
  70. * History:
  71. * 10-20-90 darrinm Ported from Win 3.0 sources.
  72. * 04-16-91 JimA Added SW_SHOWDEFAULT support.
  73. \***************************************************************************/
  74. /*
  75. * cmdShow now has fAnimate as the lower bit in the upper word. This puts it in the
  76. * MINMAX_ANIMATE position for calling MinMaximize.
  77. */
  78. BOOL xxxShowWindow(
  79. PWND pwnd,
  80. DWORD cmdShowAnimate)
  81. {
  82. BOOL fVisOld, fVisNew;
  83. UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE;
  84. PTHREADINFO pti;
  85. BOOL bFirstMain = FALSE;
  86. int cmdShow = LOWORD(cmdShowAnimate);
  87. CheckLock(pwnd);
  88. fVisOld = TestWF(pwnd, WFVISIBLE);
  89. pti = PtiCurrent();
  90. /*
  91. * See if this is the first "main" top level
  92. * window being created by this application - if show, assume it
  93. * is showing with the SW_SHOWDEFAULT command.
  94. *
  95. * Checks for:
  96. * - cmdShow is a "default" show command
  97. * - we haven't done startupinfo yet (we only use it once)
  98. * - this is not a child (it is a top level window)
  99. * - this has a titlebar (indicator of the main window)
  100. * - it isn't owned (indicator of the main window)
  101. */
  102. if ((pti->ppi->usi.dwFlags & STARTF_USESHOWWINDOW) &&
  103. !TestwndChild(pwnd) &&
  104. (TestWF(pwnd, WFBORDERMASK) == (BYTE)LOBYTE(WFCAPTION)) &&
  105. (pwnd->spwndOwner == NULL)) {
  106. bFirstMain = TRUE;
  107. switch (cmdShow) {
  108. case SW_SHOWNORMAL:
  109. case SW_SHOW:
  110. /*
  111. * Then assume default!
  112. */
  113. cmdShow = SW_SHOWDEFAULT;
  114. break;
  115. }
  116. }
  117. /*
  118. * If this application specified SW_SHOWDEFAULT, then we get the
  119. * real SW_* command from the application's STARTUPINFO structure
  120. * (STARTUPINFO is passed to CreateProcess() when this application
  121. * was launched).
  122. */
  123. if (cmdShow == SW_SHOWDEFAULT) {
  124. /*
  125. * Call the client to get the SW_* command from the STARTUPINFO
  126. * for this process.
  127. */
  128. if (pti->ppi->usi.dwFlags & STARTF_USESHOWWINDOW) {
  129. bFirstMain = TRUE;
  130. cmdShow = pti->ppi->usi.wShowWindow;
  131. /*
  132. * The following code was removed in 3.51
  133. *
  134. * switch (cmdShow) {
  135. * case SW_SHOWMINIMIZED:
  136. * case SW_MINIMIZE:
  137. *
  138. * *
  139. * * If the default show was "minimized", then make sure it doesn't
  140. * * become active. Minimized is effectively "background".
  141. * *
  142. * cmdShow = SW_SHOWMINNOACTIVE;
  143. * break;
  144. * }
  145. *
  146. */
  147. }
  148. }
  149. /*
  150. * This is in case someone said SW_SHOWDEFAULT but has no startupinfo.
  151. * Or in case cmdShow inside of STARTUPINFO is SW_SHOWDEFAULT.
  152. */
  153. if (cmdShow == SW_SHOWDEFAULT)
  154. cmdShow = SW_SHOWNORMAL;
  155. /*
  156. * Turn off startup info. We turn this off after the first call to
  157. * ShowWindow. If we don't apps can be started by progman with
  158. * the start info being minimized and then be restored and then
  159. * call ShowWindow(SW_SHOW) and the app would minimize again.
  160. * Notepad had that problem 2985.
  161. */
  162. if (bFirstMain) {
  163. pti->ppi->usi.dwFlags &=
  164. ~(STARTF_USESHOWWINDOW | STARTF_USESIZE | STARTF_USEPOSITION);
  165. }
  166. /*
  167. * Take care of all the OLD show commands with columns & iconslot.
  168. */
  169. if (cmdShow & 0xFF00) {
  170. if ((cmdShow & 0xFF80) == (int)0xFF80)
  171. cmdShow = SW_SHOWMINNOACTIVE;
  172. else
  173. cmdShow = SW_SHOW;
  174. }
  175. /*
  176. * Change to new fullscreen if needed and in same desktop
  177. */
  178. if ((GetFullScreen(pwnd) != WINDOWED)
  179. && (pwnd->head.rpdesk == grpdeskRitInput)) {
  180. if ((cmdShow == SW_SHOWNORMAL) ||
  181. (cmdShow == SW_RESTORE) ||
  182. (cmdShow == SW_MAXIMIZE) ||
  183. (cmdShow == SW_SHOWMAXIMIZED)) {
  184. cmdShow = SW_SHOWMINIMIZED;
  185. if (GetFullScreen(pwnd) == FULLSCREENMIN) {
  186. SetFullScreen(pwnd, FULLSCREEN);
  187. }
  188. if (gpqForeground != NULL &&
  189. gpqForeground->spwndActive == pwnd) {
  190. xxxMakeWindowForegroundWithState(NULL, 0);
  191. }
  192. }
  193. }
  194. switch (cmdShow) {
  195. case SW_SHOWNOACTIVATE:
  196. case SW_SHOWNORMAL:
  197. case SW_RESTORE:
  198. /*
  199. * If min/max, let xxxMinMaximize() do all the work.
  200. */
  201. if (TestWF(pwnd, WFMINIMIZED) || TestWF(pwnd, WFMAXIMIZED)) {
  202. xxxMinMaximize(pwnd, (UINT)cmdShow, cmdShowAnimate & MINMAX_ANIMATE);
  203. return fVisOld;
  204. } else {
  205. /*
  206. * Ignore if the window is already visible.
  207. */
  208. if (fVisOld) {
  209. return fVisOld;
  210. }
  211. swpFlags |= SWP_SHOWWINDOW;
  212. if ( cmdShow == SW_SHOWNOACTIVATE) {
  213. swpFlags |= SWP_NOZORDER;
  214. #ifdef NEVER
  215. /*
  216. * This is what win3.1 does. On NT, since each "queue" has
  217. * its own active window, there is often no active window.
  218. * In this case, win3.1 turns a SHOWNOACTIVATE into a "SHOW
  219. * with activate". Since win3.1 almost always has an active
  220. * window, this almost never happens. So on NT, we're not
  221. * going to do this check - that way we'll be more compatible
  222. * with win3.1 because we'll usally not activate (like win3.1).
  223. * With this check, this causes FoxPro 2.5 for Windows to not
  224. * properly activate its command window when first coming up.
  225. */
  226. if (pti->pq->spwndActive != NULL)
  227. swpFlags |= SWP_NOACTIVATE;
  228. #else
  229. swpFlags |= SWP_NOACTIVATE;
  230. #endif
  231. }
  232. }
  233. break;
  234. case SW_FORCEMINIMIZE:
  235. xxxMinimizeHungWindow(pwnd);
  236. return fVisOld;
  237. case SW_SHOWMINNOACTIVE:
  238. case SW_SHOWMINIMIZED:
  239. case SW_SHOWMAXIMIZED:
  240. case SW_MINIMIZE:
  241. xxxMinMaximize(pwnd, (UINT)cmdShow, cmdShowAnimate & MINMAX_ANIMATE);
  242. return fVisOld;
  243. case SW_SHOWNA:
  244. swpFlags |= SWP_SHOWWINDOW | SWP_NOACTIVATE;
  245. /*
  246. * LATER removed this to be compatible with SHOWNOACTIVATE
  247. * if (pti->pq->spwndActive != NULL)
  248. * swpFlags |= SWP_NOACTIVATE;
  249. */
  250. break;
  251. case SW_SHOW:
  252. /*
  253. * Don't bother if it is already visible.
  254. */
  255. if (fVisOld)
  256. return fVisOld;
  257. swpFlags |= SWP_SHOWWINDOW;
  258. UserAssert(cmdShow != SW_SHOWNOACTIVATE);
  259. break;
  260. case SW_HIDE:
  261. /*
  262. * Don't bother if it is already hidden.
  263. */
  264. if (!fVisOld)
  265. return fVisOld;
  266. swpFlags |= SWP_HIDEWINDOW;
  267. if (pwnd != pti->pq->spwndActive)
  268. swpFlags |= (SWP_NOACTIVATE | SWP_NOZORDER);
  269. break;
  270. default:
  271. RIPERR0(ERROR_INVALID_SHOWWIN_COMMAND, RIP_VERBOSE, "");
  272. return fVisOld;
  273. }
  274. /*
  275. * If we're changing from visible to hidden or vise-versa, send
  276. * WM_SHOWWINDOW.
  277. */
  278. fVisNew = !(cmdShow == SW_HIDE);
  279. if (fVisNew != fVisOld) {
  280. xxxSendMessage(pwnd, WM_SHOWWINDOW, fVisNew, 0L);
  281. if (!TestWF(pwnd, WFWIN31COMPAT)) {
  282. xxxSendMessage(pwnd, WM_SETVISIBLE, fVisNew, 0L);
  283. }
  284. }
  285. if (!TestwndChild(pwnd)) {
  286. if (TestCF(pwnd, CFSAVEBITS)) {
  287. /*
  288. * Activate to prevent discarding saved bits???
  289. */
  290. if (cmdShow == SW_SHOW || cmdShow == SW_SHOWNORMAL) {
  291. xxxActivateWindow(pwnd, AW_USE);
  292. swpFlags |= SWP_NOZORDER | SWP_NOACTIVATE;
  293. }
  294. }
  295. } else {
  296. /*
  297. * Children can't get activation...
  298. */
  299. swpFlags |= (SWP_NOACTIVATE | SWP_NOZORDER);
  300. }
  301. /*
  302. * If our parent is hidden, don't bother to call xxxSetWindowPos.
  303. */
  304. if (_FChildVisible(pwnd)) {
  305. xxxSetWindowPos(pwnd, (PWND)NULL, 0, 0, 0, 0, swpFlags);
  306. } else {
  307. if (cmdShow == SW_HIDE) {
  308. SetVisible(pwnd, SV_UNSET);
  309. ClrWF(pwnd, WEFGHOSTMAKEVISIBLE);
  310. }
  311. else {
  312. SetVisible(pwnd, SV_SET);
  313. SetWF(pwnd, WEFGHOSTMAKEVISIBLE);
  314. }
  315. }
  316. /*
  317. * Send size and move messages AFTER repainting
  318. */
  319. if (TestWF(pwnd, WFSENDSIZEMOVE)) {
  320. ClrWF(pwnd, WFSENDSIZEMOVE);
  321. if (TestWF(pwnd, WFMINIMIZED)) {
  322. xxxSendSizeMessage(pwnd, SIZE_MINIMIZED);
  323. } else if (TestWF(pwnd, WFMAXIMIZED)) {
  324. xxxSendSizeMessage(pwnd, SIZE_MAXIMIZED);
  325. } else {
  326. xxxSendSizeMessage(pwnd, SIZE_RESTORED);
  327. }
  328. xxxSendMessage(pwnd, WM_MOVE, 0,
  329. (pwnd->spwndParent == PWNDDESKTOP(pwnd)) ?
  330. MAKELONG(pwnd->rcClient.left, pwnd->rcClient.top) :
  331. MAKELONG(
  332. pwnd->rcClient.left - pwnd->spwndParent->rcClient.left,
  333. pwnd->rcClient.top - pwnd->spwndParent->rcClient. top));
  334. }
  335. /*
  336. * If hiding and is active-foreground window, activate someone else.
  337. * If hiding a active window make someone active.
  338. */
  339. if (cmdShow == SW_HIDE) {
  340. if ((pwnd == pti->pq->spwndActive) && (pti->pq == gpqForeground)) {
  341. xxxActivateWindow(pwnd, AW_SKIP);
  342. } else {
  343. xxxCheckFocus(pwnd);
  344. }
  345. }
  346. return fVisOld;
  347. }
  348. /***************************************************************************\
  349. * xxxShowOwnedWindows
  350. *
  351. * xxxShowOwnedWindows is used to hide or show associated popups for the
  352. * following reasons:
  353. *
  354. * 1. Window going iconic
  355. * 2. Popup window being hidden
  356. * 3. Iconic window being opened
  357. * 4. Popup window being shown
  358. * 5. Window being zoomed or unzoomed
  359. *
  360. * For cases 1 and 2, all popups associated with that window are hidden,
  361. * and the WFHIDDENPOPUP bit is set. This bit is used to differentiate
  362. * between windows hidded by xxxShowOwnedWindows and those hidden by the
  363. * application.
  364. *
  365. * For cases 3 and 4, all popups associated with that window that have the
  366. * WFHIDDENPOPUP bit set are shown.
  367. *
  368. * For case 5, all popups associated with any window BUT the supplied
  369. * window are hidden or shown. In this case as well, the SW_OTHERZOOM
  370. * or SW_OTHERUNZOOM message is send to all tiled windows to notify them
  371. * that they are being covered or uncovered by the zoomed window.
  372. *
  373. * In all cases, the WM_SHOWWINDOW message is sent to the window to hide or
  374. * show it.
  375. *
  376. * This routine works by simply enumerating all popup windows checking to see
  377. * if the owner of the popup matches the pwndOwner parameter, and taking the
  378. * appropriate action.
  379. *
  380. * We will eventually want 3 separate hide bits: one each for other zoom/unzoom,
  381. * owner iconic/open, owner hide/show. Right now, there is only one bit, so
  382. * we show windows sometimes when we shouldn't
  383. *
  384. * History:
  385. * 10-20-90 darrinm Ported from Win 3.0 sources.
  386. \***************************************************************************/
  387. void xxxShowOwnedWindows(
  388. PWND pwndOwner,
  389. UINT cmdShow,
  390. HRGN hrgnHung)
  391. {
  392. BOOL fShow;
  393. int cmdZoom;
  394. HWND *phwnd;
  395. PBWL pbwl;
  396. PWND pwnd, pwndTopOwner;
  397. TL tlpwnd;
  398. CheckLock(pwndOwner);
  399. /*
  400. * Not interested in child windows
  401. */
  402. if (TestwndChild(pwndOwner))
  403. return;
  404. if ((pbwl = BuildHwndList(PWNDDESKTOP(pwndOwner)->spwndChild, BWL_ENUMLIST, NULL)) == NULL)
  405. return;
  406. /*
  407. * NOTE: The following code assumes the values of SW_* are 1, 2, 3, and 4
  408. */
  409. fShow = (cmdShow >= SW_PARENTOPENING);
  410. cmdZoom = 0;
  411. if (cmdShow == SW_OTHERZOOM)
  412. cmdZoom = SIZEZOOMHIDE;
  413. if (cmdShow == SW_OTHERUNZOOM)
  414. cmdZoom = SIZEZOOMSHOW;
  415. /*
  416. * If zoom/unzoom, then open/close all popups owned by all other
  417. * windows. Otherwise, open/close popups owned by pwndOwner.
  418. */
  419. for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) {
  420. /*
  421. * Lock the window before we play with it.
  422. * If the window handle is invalid, skip it
  423. */
  424. if ((pwnd = RevalidateHwnd(*phwnd)) == NULL)
  425. continue;
  426. /*
  427. * Kanji windows can't be owned, so skip it.
  428. */
  429. if (TestCF(pwnd, CFKANJIWINDOW))
  430. continue;
  431. /*
  432. * If same as window passed in, skip it.
  433. */
  434. if (pwnd == pwndOwner)
  435. continue;
  436. /*
  437. * Find ultimate owner of popup, but only go up as far as pwndOwner.
  438. */
  439. if ((pwndTopOwner = pwnd->spwndOwner) != NULL) {
  440. /*
  441. * The TestwndHI is needed since if it has an icon, pwndOwner
  442. * is invalid.
  443. */
  444. while (!TestwndHI(pwndTopOwner) && pwndTopOwner != pwndOwner &&
  445. pwndTopOwner->spwndOwner != NULL)
  446. pwndTopOwner = pwndTopOwner->spwndOwner;
  447. }
  448. /*
  449. * Zoom/Unzoom case.
  450. */
  451. if (cmdZoom != 0) {
  452. /*
  453. * If no parent, or parents are the same, skip.
  454. */
  455. if (pwndTopOwner == NULL || pwndTopOwner == pwndOwner)
  456. continue;
  457. /*
  458. * If owner is iconic, then this window should stay hidden,
  459. * UNLESS the minimized window is disabled, in which case we'd
  460. * better show the window.
  461. */
  462. if ( cmdShow == SW_OTHERUNZOOM
  463. && pwndTopOwner != NULL
  464. && TestWF(pwndTopOwner, WFMINIMIZED)
  465. && !TestWF(pwndTopOwner, WFDISABLED)
  466. )
  467. continue;
  468. } else {
  469. /*
  470. * Hide/Iconize/Show/Open case.
  471. */
  472. /*
  473. * If parents aren't the same, skip.
  474. */
  475. if (pwndTopOwner != pwndOwner)
  476. continue;
  477. }
  478. /*
  479. * Hide or show if:
  480. * Showing & this is a hidden popup
  481. * OR
  482. * Hiding & this is a visible window
  483. */
  484. if ((fShow && TestWF(pwnd, WFHIDDENPOPUP)) ||
  485. (!fShow && TestWF(pwnd, WFVISIBLE))) {
  486. /*
  487. * For hung minimization, just set the HIDDENPOPUP bit, clear
  488. * the visible bit and add the window rect to the region to
  489. * be repainted.
  490. */
  491. if (hrgnHung != NULL) {
  492. HRGN hrgn = GreCreateRectRgnIndirect(&pwnd->rcWindow);
  493. UnionRgn(hrgnHung, hrgnHung, hrgn);
  494. GreDeleteObject(hrgn);
  495. UserAssert(!fShow);
  496. SetWF(pwnd, WFHIDDENPOPUP);
  497. SetVisible(pwnd, SV_UNSET);
  498. } else {
  499. ThreadLockAlways(pwnd, &tlpwnd);
  500. xxxSendMessage(pwnd, WM_SHOWWINDOW, fShow, (LONG)cmdShow);
  501. ThreadUnlock(&tlpwnd);
  502. }
  503. }
  504. }
  505. /*
  506. * Free the window list.
  507. */
  508. FreeHwndList(pbwl);
  509. }
  510. /***************************************************************************\
  511. * xxxShowOwnedPopups (API)
  512. *
  513. * This routine is accessable to the user. It will either show or
  514. * hide all popup windows owned by the window handle specified. If
  515. * fShow if TRUE, all hidden popups will be shown. If it is FALSE, all
  516. * visible popups will be hidden.
  517. *
  518. * History:
  519. * 10-20-90 darrinm Ported from Win 3.0 sources.
  520. \***************************************************************************/
  521. BOOL xxxShowOwnedPopups(
  522. PWND pwndOwner,
  523. BOOL fShow)
  524. {
  525. CheckLock(pwndOwner);
  526. xxxShowOwnedWindows(pwndOwner,
  527. (UINT)(fShow ? SW_PARENTOPENING : SW_PARENTCLOSING), NULL);
  528. return TRUE;
  529. }