Main Page | Class Hierarchy | Class List | File List | Class Members | File Members

showwin.c

Go to the documentation of this file.
00001 /****************************** Module Header ******************************\ 00002 * Module Name: showwin.c 00003 * 00004 * Copyright (c) 1985 - 1999, Microsoft Corporation 00005 * 00006 * Contains the xxxShowWindow API and related functions. 00007 * 00008 * History: 00009 * 10-20-90 darrinm Created. 00010 * 02-04-91 IanJa Window handle revalidation added 00011 \***************************************************************************/ 00012 00013 #include "precomp.h" 00014 #pragma hdrstop 00015 00016 /***************************************************************************\ 00017 * _ShowWindowAsync 00018 * 00019 * This queues a show window event in another thread's queue. Used mainly from 00020 * within taskmgr, so that taskmgr doesn't hang waiting on hung apps. 00021 * 00022 * 04-23-93 ScottLu Created. 00023 \***************************************************************************/ 00024 00025 BOOL _ShowWindowAsync(PWND pwnd, int cmdShow, UINT uWPFlags) 00026 { 00027 00028 return PostEventMessage( 00029 GETPTI(pwnd), 00030 GETPTI(pwnd)->pq, 00031 QEVENT_SHOWWINDOW, 00032 NULL, 00033 uWPFlags, 00034 (WPARAM)HWq(pwnd), 00035 cmdShow | TEST_PUDF(PUDF_ANIMATE)); 00036 } 00037 00038 /***************************************************************************\ 00039 * xxxShowWindow (API) 00040 * 00041 * This function changes the "state" of a window based upon the cmdShow 00042 * parameter. The action taken is: 00043 * 00044 * SW_HIDE 0 Hide the window and pass avtivation to someone else 00045 * 00046 * SW_SHOWNORMAL 1 Show a window in its most recent "normal" 00047 * SW_RESTORE size and position. This will "restore" a iconic 00048 * or zoomed window. This is compatible with 1.03 00049 * SHOW_OPENWINDOW. This will also activate the window. 00050 * 00051 * SW_SHOWMINIMIZED 2 Show the window as iconic and make it active. 00052 * 00053 * SW_SHOWMAXIMIZED 3 Show the window as maximized and make it active. 00054 * 00055 * SW_SHOWNOACTIVATE 4 Same as SW_SHOWNORMAL except that it doesn't change 00056 * the activation (currently active window stays active). 00057 * 00058 * All the above are compatible with 1.03 ShowWindow parameters. Now here are 00059 * the new ones: 00060 * 00061 * SW_SHOW 5 Show the window in its current state (iconic, etc.) 00062 * That is, if the window is iconic when hidden, it will 00063 * still be iconic. This will activate the window. 00064 * (This is one we don't have today) 00065 * 00066 * SW_MINIMIZE 6 minimize the window, activate the toplevel open window 00067 * 00068 * SW_SHOWMINNOACTIVE 7 show the icon, don't change activation. 00069 * 00070 * SW_SHOWNA 8 Same as SW_SHOW except that it doesn't change 00071 * the activation. 00072 * 00073 * SW_SHOWDEFAULT 10 Use value obtained from STARTUPINFO. 00074 * 00075 * History: 00076 * 10-20-90 darrinm Ported from Win 3.0 sources. 00077 * 04-16-91 JimA Added SW_SHOWDEFAULT support. 00078 \***************************************************************************/ 00079 00080 /* 00081 * cmdShow now has fAnimate as the lower bit in the upper word. This puts it in the 00082 * MINMAX_ANIMATE position for calling MinMaximize. 00083 */ 00084 00085 BOOL xxxShowWindow( 00086 PWND pwnd, 00087 DWORD cmdShowAnimate) 00088 { 00089 BOOL fVisOld, fVisNew; 00090 UINT swpFlags = SWP_NOMOVE | SWP_NOSIZE; 00091 PTHREADINFO pti; 00092 BOOL bFirstMain = FALSE; 00093 int cmdShow = LOWORD(cmdShowAnimate); 00094 00095 CheckLock(pwnd); 00096 00097 fVisOld = TestWF(pwnd, WFVISIBLE); 00098 pti = PtiCurrent(); 00099 00100 /* 00101 * See if this is the first "main" top level 00102 * window being created by this application - if show, assume it 00103 * is showing with the SW_SHOWDEFAULT command. 00104 * 00105 * Checks for: 00106 * - cmdShow is a "default" show command 00107 * - we haven't done startupinfo yet (we only use it once) 00108 * - this is not a child (it is a top level window) 00109 * - this has a titlebar (indicator of the main window) 00110 * - it isn't owned (indicator of the main window) 00111 */ 00112 if ((pti->ppi->usi.dwFlags & STARTF_USESHOWWINDOW) && 00113 !TestwndChild(pwnd) && 00114 (TestWF(pwnd, WFBORDERMASK) == (BYTE)LOBYTE(WFCAPTION)) && 00115 (pwnd->spwndOwner == NULL)) { 00116 00117 bFirstMain = TRUE; 00118 00119 switch (cmdShow) { 00120 case SW_SHOWNORMAL: 00121 case SW_SHOW: 00122 00123 /* 00124 * Then assume default! 00125 */ 00126 cmdShow = SW_SHOWDEFAULT; 00127 break; 00128 } 00129 } 00130 00131 /* 00132 * If this application specified SW_SHOWDEFAULT, then we get the 00133 * real SW_* command from the application's STARTUPINFO structure 00134 * (STARTUPINFO is passed to CreateProcess() when this application 00135 * was launched). 00136 */ 00137 if (cmdShow == SW_SHOWDEFAULT) { 00138 00139 /* 00140 * Call the client to get the SW_* command from the STARTUPINFO 00141 * for this process. 00142 */ 00143 if (pti->ppi->usi.dwFlags & STARTF_USESHOWWINDOW) { 00144 00145 bFirstMain = TRUE; 00146 00147 cmdShow = pti->ppi->usi.wShowWindow; 00148 00149 /* 00150 * The following code was removed in 3.51 00151 * 00152 * switch (cmdShow) { 00153 * case SW_SHOWMINIMIZED: 00154 * case SW_MINIMIZE: 00155 * 00156 * * 00157 * * If the default show was "minimized", then make sure it doesn't 00158 * * become active. Minimized is effectively "background". 00159 * * 00160 * cmdShow = SW_SHOWMINNOACTIVE; 00161 * break; 00162 * } 00163 * 00164 */ 00165 } 00166 } 00167 00168 00169 /* 00170 * This is in case someone said SW_SHOWDEFAULT but has no startupinfo. 00171 * Or in case cmdShow inside of STARTUPINFO is SW_SHOWDEFAULT. 00172 */ 00173 if (cmdShow == SW_SHOWDEFAULT) 00174 cmdShow = SW_SHOWNORMAL; 00175 00176 /* 00177 * Turn off startup info. We turn this off after the first call to 00178 * ShowWindow. If we don't apps can be started by progman with 00179 * the start info being minimized and then be restored and then 00180 * call ShowWindow(SW_SHOW) and the app would minimize again. 00181 * Notepad had that problem 2985. 00182 */ 00183 if (bFirstMain) { 00184 pti->ppi->usi.dwFlags &= 00185 ~(STARTF_USESHOWWINDOW | STARTF_USESIZE | STARTF_USEPOSITION); 00186 } 00187 00188 00189 /* 00190 * Take care of all the OLD show commands with columns & iconslot. 00191 */ 00192 if (cmdShow & 0xFF00) { 00193 if ((cmdShow & 0xFF80) == (int)0xFF80) 00194 cmdShow = SW_SHOWMINNOACTIVE; 00195 else 00196 cmdShow = SW_SHOW; 00197 } 00198 00199 /* 00200 * Change to new fullscreen if needed and in same desktop 00201 */ 00202 if ((GetFullScreen(pwnd) != WINDOWED) 00203 && (pwnd->head.rpdesk == grpdeskRitInput)) { 00204 if ((cmdShow == SW_SHOWNORMAL) || 00205 (cmdShow == SW_RESTORE) || 00206 (cmdShow == SW_MAXIMIZE) || 00207 (cmdShow == SW_SHOWMAXIMIZED)) { 00208 cmdShow = SW_SHOWMINIMIZED; 00209 00210 if (GetFullScreen(pwnd) == FULLSCREENMIN) { 00211 SetFullScreen(pwnd, FULLSCREEN); 00212 } 00213 00214 if (gpqForeground != NULL && 00215 gpqForeground->spwndActive == pwnd) { 00216 xxxMakeWindowForegroundWithState(NULL, 0); 00217 } 00218 } 00219 } 00220 00221 switch (cmdShow) { 00222 case SW_SHOWNOACTIVATE: 00223 case SW_SHOWNORMAL: 00224 case SW_RESTORE: 00225 00226 /* 00227 * If min/max, let xxxMinMaximize() do all the work. 00228 */ 00229 if (TestWF(pwnd, WFMINIMIZED) || TestWF(pwnd, WFMAXIMIZED)) { 00230 xxxMinMaximize(pwnd, (UINT)cmdShow, cmdShowAnimate & MINMAX_ANIMATE); 00231 return fVisOld; 00232 00233 } else { 00234 00235 /* 00236 * Ignore if the window is already visible. 00237 */ 00238 if (fVisOld) { 00239 return fVisOld; 00240 } 00241 00242 swpFlags |= SWP_SHOWWINDOW; 00243 if ( cmdShow == SW_SHOWNOACTIVATE) { 00244 swpFlags |= SWP_NOZORDER; 00245 #ifdef NEVER 00246 /* 00247 * This is what win3.1 does. On NT, since each "queue" has 00248 * its own active window, there is often no active window. 00249 * In this case, win3.1 turns a SHOWNOACTIVATE into a "SHOW 00250 * with activate". Since win3.1 almost always has an active 00251 * window, this almost never happens. So on NT, we're not 00252 * going to do this check - that way we'll be more compatible 00253 * with win3.1 because we'll usally not activate (like win3.1). 00254 * With this check, this causes FoxPro 2.5 for Windows to not 00255 * properly activate its command window when first coming up. 00256 */ 00257 if (pti->pq->spwndActive != NULL) 00258 swpFlags |= SWP_NOACTIVATE; 00259 #else 00260 swpFlags |= SWP_NOACTIVATE; 00261 #endif 00262 } 00263 } 00264 break; 00265 00266 case SW_FORCEMINIMIZE: 00267 xxxMinimizeHungWindow(pwnd); 00268 return fVisOld; 00269 00270 case SW_SHOWMINNOACTIVE: 00271 case SW_SHOWMINIMIZED: 00272 case SW_SHOWMAXIMIZED: 00273 case SW_MINIMIZE: 00274 xxxMinMaximize(pwnd, (UINT)cmdShow, cmdShowAnimate & MINMAX_ANIMATE); 00275 return fVisOld; 00276 00277 case SW_SHOWNA: 00278 swpFlags |= SWP_SHOWWINDOW | SWP_NOACTIVATE; 00279 00280 00281 /* 00282 * LATER removed this to be compatible with SHOWNOACTIVATE 00283 * if (pti->pq->spwndActive != NULL) 00284 * swpFlags |= SWP_NOACTIVATE; 00285 */ 00286 break; 00287 00288 case SW_SHOW: 00289 00290 /* 00291 * Don't bother if it is already visible. 00292 */ 00293 if (fVisOld) 00294 return fVisOld; 00295 00296 swpFlags |= SWP_SHOWWINDOW; 00297 UserAssert(cmdShow != SW_SHOWNOACTIVATE); 00298 break; 00299 00300 case SW_HIDE: 00301 00302 /* 00303 * Don't bother if it is already hidden. 00304 */ 00305 if (!fVisOld) 00306 return fVisOld; 00307 00308 swpFlags |= SWP_HIDEWINDOW; 00309 if (pwnd != pti->pq->spwndActive) 00310 swpFlags |= (SWP_NOACTIVATE | SWP_NOZORDER); 00311 break; 00312 00313 default: 00314 RIPERR0(ERROR_INVALID_SHOWWIN_COMMAND, RIP_VERBOSE, ""); 00315 return fVisOld; 00316 } 00317 00318 /* 00319 * If we're changing from visible to hidden or vise-versa, send 00320 * WM_SHOWWINDOW. 00321 */ 00322 fVisNew = !(cmdShow == SW_HIDE); 00323 if (fVisNew != fVisOld) { 00324 xxxSendMessage(pwnd, WM_SHOWWINDOW, fVisNew, 0L); 00325 if (!TestWF(pwnd, WFWIN31COMPAT)) { 00326 xxxSendMessage(pwnd, WM_SETVISIBLE, fVisNew, 0L); 00327 } 00328 } 00329 00330 if (!TestwndChild(pwnd)) { 00331 if (TestCF(pwnd, CFSAVEBITS)) { 00332 00333 /* 00334 * Activate to prevent discarding saved bits??? 00335 */ 00336 if (cmdShow == SW_SHOW || cmdShow == SW_SHOWNORMAL) { 00337 xxxActivateWindow(pwnd, AW_USE); 00338 swpFlags |= SWP_NOZORDER | SWP_NOACTIVATE; 00339 } 00340 } 00341 } else { 00342 00343 /* 00344 * Children can't get activation... 00345 */ 00346 swpFlags |= (SWP_NOACTIVATE | SWP_NOZORDER); 00347 } 00348 00349 /* 00350 * If our parent is hidden, don't bother to call xxxSetWindowPos. 00351 */ 00352 if (_FChildVisible(pwnd)) { 00353 xxxSetWindowPos(pwnd, (PWND)NULL, 0, 0, 0, 0, swpFlags); 00354 } else { 00355 if (cmdShow == SW_HIDE) 00356 SetVisible(pwnd, SV_UNSET); 00357 else 00358 SetVisible(pwnd, SV_SET); 00359 } 00360 00361 /* 00362 * Send size and move messages AFTER repainting 00363 */ 00364 if (TestWF(pwnd, WFSENDSIZEMOVE)) { 00365 ClrWF(pwnd, WFSENDSIZEMOVE); 00366 if (TestWF(pwnd, WFMINIMIZED)) { 00367 xxxSendSizeMessage(pwnd, SIZE_MINIMIZED); 00368 } else if (TestWF(pwnd, WFMAXIMIZED)) { 00369 xxxSendSizeMessage(pwnd, SIZE_MAXIMIZED); 00370 } else { 00371 xxxSendSizeMessage(pwnd, SIZE_RESTORED); 00372 } 00373 00374 xxxSendMessage(pwnd, WM_MOVE, 0, 00375 (pwnd->spwndParent == PWNDDESKTOP(pwnd)) ? 00376 MAKELONG(pwnd->rcClient.left, pwnd->rcClient.top) : 00377 MAKELONG( 00378 pwnd->rcClient.left - pwnd->spwndParent->rcClient.left, 00379 pwnd->rcClient.top - pwnd->spwndParent->rcClient. top)); 00380 } 00381 00382 /* 00383 * If hiding and is active-foreground window, activate someone else. 00384 * If hiding a active window make someone active. 00385 */ 00386 if (cmdShow == SW_HIDE) { 00387 if ((pwnd == pti->pq->spwndActive) && (pti->pq == gpqForeground)) { 00388 xxxActivateWindow(pwnd, AW_SKIP); 00389 } else { 00390 xxxCheckFocus(pwnd); 00391 } 00392 } 00393 00394 return fVisOld; 00395 } 00396 00397 /***************************************************************************\ 00398 * xxxShowOwnedWindows 00399 * 00400 * xxxShowOwnedWindows is used to hide or show associated popups for the 00401 * following reasons: 00402 * 00403 * 1. Window going iconic 00404 * 2. Popup window being hidden 00405 * 3. Iconic window being opened 00406 * 4. Popup window being shown 00407 * 5. Window being zoomed or unzoomed 00408 * 00409 * For cases 1 and 2, all popups associated with that window are hidden, 00410 * and the WFHIDDENPOPUP bit is set. This bit is used to differentiate 00411 * between windows hidded by xxxShowOwnedWindows and those hidden by the 00412 * application. 00413 * 00414 * For cases 3 and 4, all popups associated with that window that have the 00415 * WFHIDDENPOPUP bit set are shown. 00416 * 00417 * For case 5, all popups associated with any window BUT the supplied 00418 * window are hidden or shown. In this case as well, the SW_OTHERZOOM 00419 * or SW_OTHERUNZOOM message is send to all tiled windows to notify them 00420 * that they are being covered or uncovered by the zoomed window. 00421 * 00422 * In all cases, the WM_SHOWWINDOW message is sent to the window to hide or 00423 * show it. 00424 * 00425 * This routine works by simply enumerating all popup windows checking to see 00426 * if the owner of the popup matches the pwndOwner parameter, and taking the 00427 * appropriate action. 00428 * 00429 * We will eventually want 3 separate hide bits: one each for other zoom/unzoom, 00430 * owner iconic/open, owner hide/show. Right now, there is only one bit, so 00431 * we show windows sometimes when we shouldn't 00432 * 00433 * History: 00434 * 10-20-90 darrinm Ported from Win 3.0 sources. 00435 \***************************************************************************/ 00436 00437 void xxxShowOwnedWindows( 00438 PWND pwndOwner, 00439 UINT cmdShow, 00440 HRGN hrgnHung) 00441 { 00442 BOOL fShow; 00443 int cmdZoom; 00444 HWND *phwnd; 00445 PBWL pbwl; 00446 PWND pwnd, pwndTopOwner; 00447 TL tlpwnd; 00448 00449 CheckLock(pwndOwner); 00450 00451 /* 00452 * Not interested in child windows 00453 */ 00454 if (TestwndChild(pwndOwner)) 00455 return; 00456 00457 if ((pbwl = BuildHwndList(PWNDDESKTOP(pwndOwner)->spwndChild, BWL_ENUMLIST, NULL)) == NULL) 00458 return; 00459 00460 /* 00461 * NOTE: The following code assumes the values of SW_* are 1, 2, 3, and 4 00462 */ 00463 fShow = (cmdShow >= SW_PARENTOPENING); 00464 00465 cmdZoom = 0; 00466 if (cmdShow == SW_OTHERZOOM) 00467 cmdZoom = SIZEZOOMHIDE; 00468 00469 if (cmdShow == SW_OTHERUNZOOM) 00470 cmdZoom = SIZEZOOMSHOW; 00471 00472 /* 00473 * If zoom/unzoom, then open/close all popups owned by all other 00474 * windows. Otherwise, open/close popups owned by pwndOwner. 00475 */ 00476 for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { 00477 00478 /* 00479 * Lock the window before we play with it. 00480 * If the window handle is invalid, skip it 00481 */ 00482 if ((pwnd = RevalidateHwnd(*phwnd)) == NULL) 00483 continue; 00484 00485 /* 00486 * Kanji windows can't be owned, so skip it. 00487 */ 00488 if (TestCF(pwnd, CFKANJIWINDOW)) 00489 continue; 00490 00491 /* 00492 * If same as window passed in, skip it. 00493 */ 00494 if (pwnd == pwndOwner) 00495 continue; 00496 00497 /* 00498 * Find ultimate owner of popup, but only go up as far as pwndOwner. 00499 */ 00500 if ((pwndTopOwner = pwnd->spwndOwner) != NULL) { 00501 00502 /* 00503 * The TestwndHI is needed since if it has an icon, pwndOwner 00504 * is invalid. 00505 */ 00506 while (!TestwndHI(pwndTopOwner) && pwndTopOwner != pwndOwner && 00507 pwndTopOwner->spwndOwner != NULL) 00508 pwndTopOwner = pwndTopOwner->spwndOwner; 00509 } 00510 00511 /* 00512 * Zoom/Unzoom case. 00513 */ 00514 if (cmdZoom != 0) { 00515 00516 /* 00517 * If no parent, or parents are the same, skip. 00518 */ 00519 if (pwndTopOwner == NULL || pwndTopOwner == pwndOwner) 00520 continue; 00521 00522 /* 00523 * If owner is iconic, then this window should stay hidden, 00524 * UNLESS the minimized window is disabled, in which case we'd 00525 * better show the window. 00526 */ 00527 if ( cmdShow == SW_OTHERUNZOOM 00528 && pwndTopOwner != NULL 00529 && TestWF(pwndTopOwner, WFMINIMIZED) 00530 && !TestWF(pwndTopOwner, WFDISABLED) 00531 ) 00532 continue; 00533 } else { 00534 /* 00535 * Hide/Iconize/Show/Open case. 00536 */ 00537 /* 00538 * If parents aren't the same, skip. 00539 */ 00540 if (pwndTopOwner != pwndOwner) 00541 continue; 00542 } 00543 00544 /* 00545 * Hide or show if: 00546 * Showing & this is a hidden popup 00547 * OR 00548 * Hiding & this is a visible window 00549 */ 00550 if ((fShow && TestWF(pwnd, WFHIDDENPOPUP)) || 00551 (!fShow && TestWF(pwnd, WFVISIBLE))) { 00552 /* 00553 * For hung minimization, just set the HIDDENPOPUP bit, clear 00554 * the visible bit and add the window rect to the region to 00555 * be repainted. 00556 */ 00557 if (hrgnHung != NULL) { 00558 HRGN hrgn = GreCreateRectRgnIndirect(&pwnd->rcWindow); 00559 UnionRgn(hrgnHung, hrgnHung, hrgn); 00560 GreDeleteObject(hrgn); 00561 00562 UserAssert(!fShow); 00563 00564 SetWF(pwnd, WFHIDDENPOPUP); 00565 SetVisible(pwnd, SV_UNSET); 00566 } else { 00567 ThreadLockAlways(pwnd, &tlpwnd); 00568 xxxSendMessage(pwnd, WM_SHOWWINDOW, fShow, (LONG)cmdShow); 00569 ThreadUnlock(&tlpwnd); 00570 } 00571 } 00572 } 00573 00574 /* 00575 * Free the window list. 00576 */ 00577 FreeHwndList(pbwl); 00578 } 00579 00580 00581 /***************************************************************************\ 00582 * xxxShowOwnedPopups (API) 00583 * 00584 * This routine is accessable to the user. It will either show or 00585 * hide all popup windows owned by the window handle specified. If 00586 * fShow if TRUE, all hidden popups will be shown. If it is FALSE, all 00587 * visible popups will be hidden. 00588 * 00589 * History: 00590 * 10-20-90 darrinm Ported from Win 3.0 sources. 00591 \***************************************************************************/ 00592 00593 BOOL xxxShowOwnedPopups( 00594 PWND pwndOwner, 00595 BOOL fShow) 00596 { 00597 CheckLock(pwndOwner); 00598 00599 xxxShowOwnedWindows(pwndOwner, 00600 (UINT)(fShow ? SW_PARENTOPENING : SW_PARENTCLOSING), NULL); 00601 return TRUE; 00602 } 00603

Generated on Sat May 15 19:41:49 2004 for test by doxygen 1.3.7