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

tmswitch.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define DGF_NODRAW   1
#define ALT_F6   2
#define ALT_ESCAPE   1
#define FDIR_FORWARD   0
#define FDIR_BACKWARD   1
#define CXICONSLOT   43
#define CYICONSLOT   43
#define CXICONSIZE   32
#define CYICONSIZE   32
#define MAXTASKNAMELEN   50

Functions

VOID xxxPaintIconsInSwitchWindow (PWND, PSWINFO, HDC, INT, INT, INT, BOOL, BOOL, PICON)
__inline PSWINFO Getpswi (PWND pwnd)
__inline void Setpswi (PWND pwnd, PSWINFO pswi)
PWND DSW_GetTopLevelCreatorWindow (PWND pwnd)
PWND _GetNextQueueWindow (PWND pwnd, BOOL fPrev, BOOL fAltEsc)
VOID xxxSwitchToThisWindow (PWND pwnd, BOOL fAltTab)
INT NextPrevTaskIndex (PSWINFO pswInfo, INT iIndex, INT iCount, BOOL fNext)
PHWND NextPrevPhwnd (PSWINFO pswInfo, PHWND phwnd, BOOL fNext)
BOOL _IsTaskWindow (PWND pwnd, PWND pwndActive)
INT _RemoveNonTaskWindows (PBWL pbwl, PWND pwndActive, LPINT lpiActiveTask, PHWND *pphwndLast)
VOID DrawSwitchWndHilite (PSWINFO pswInfo, HDC hdcSwitch, int iCol, int iRow, BOOL fShow)
VOID CALLBACK DrawIconCallBack (HWND hwnd, UINT uMsg, ULONG_PTR dwData, LRESULT lResult)
BOOL TSW_CalcRowAndCol (PSWINFO pswInfo, INT iTaskIndex, LPINT lpiRow, LPINT lpiCol)
VOID xxxPaintSwitchWindow (PWND pwndSwitch)
PWND InitSwitchWndInfo (PSWINFO *lppswInfo, PWND pwndCurActive, BOOL fPrev)
HWND xxxMoveSwitchWndHilite (PWND pwndSwitch, PSWINFO pswInfo, BOOL fPrev)
BOOL xxxShowSwitchWindow (PWND pwndAltTab)
VOID SwitchWndCleanup (PSWINFO *ppswInfo)
LRESULT xxxSwitchWndProc (PWND pwnd, UINT message, WPARAM wParam, LPARAM lParam)
VOID xxxCancelCoolSwitch (void)
VOID xxxNextWindow (PQ pq, DWORD wParam)
VOID xxxOldNextWindow (UINT flags)
BOOL WINAPI _GetAltTabInfo (int iItem, PALTTABINFO pati, LPWSTR ccxpwszItemText, UINT cchItemText OPTIONAL, BOOL bAnsi)


Define Documentation

#define ALT_ESCAPE   1
 

Definition at line 23 of file tmswitch.c.

Referenced by xxxOldNextWindow().

#define ALT_F6   2
 

Definition at line 22 of file tmswitch.c.

Referenced by xxxOldNextWindow().

#define CXICONSIZE   32
 

Definition at line 35 of file tmswitch.c.

Referenced by InitSwitchWndInfo(), and xxxPaintIconsInSwitchWindow().

#define CXICONSLOT   43
 

Definition at line 33 of file tmswitch.c.

Referenced by _GetAltTabInfo(), DrawSwitchWndHilite(), InitSwitchWndInfo(), and xxxPaintIconsInSwitchWindow().

#define CYICONSIZE   32
 

Definition at line 36 of file tmswitch.c.

Referenced by InitSwitchWndInfo(), and xxxPaintIconsInSwitchWindow().

#define CYICONSLOT   43
 

Definition at line 34 of file tmswitch.c.

Referenced by _GetAltTabInfo(), DrawSwitchWndHilite(), InitSwitchWndInfo(), and xxxPaintIconsInSwitchWindow().

#define DGF_NODRAW   1
 

Definition at line 20 of file tmswitch.c.

#define FDIR_BACKWARD   1
 

Definition at line 26 of file tmswitch.c.

Referenced by xxxNextWindow().

#define FDIR_FORWARD   0
 

Definition at line 25 of file tmswitch.c.

Referenced by xxxNextWindow(), and xxxSwitchToThisWindow().

#define MAXTASKNAMELEN   50
 

Definition at line 37 of file tmswitch.c.


Function Documentation

BOOL WINAPI _GetAltTabInfo int  iItem,
PALTTABINFO  pati,
LPWSTR  ccxpwszItemText,
UINT cchItemText  OPTIONAL,
BOOL  bAnsi
 

Definition at line 2635 of file tmswitch.c.

References _LARGE_UNICODE_STRING::Buffer, CXICONSLOT, CYICONSLOT, FALSE, Getpswi(), gspwndAltTab, tagSwitchWndInfo::iCurCol, tagSwitchWndInfo::iCurRow, tagSwitchWndInfo::iNoOfColumns, tagSwitchWndInfo::iNoOfRows, tagSwitchWndInfo::iTotalTasks, _LARGE_UNICODE_STRING::Length, NULL, NullTerminateString(), tagSwitchWndInfo::pbwl, tagSwitchWndInfo::ptFirstRowStart, RevalidateHwnd, tagBWL::rghwnd, RtlUnicodeToMultiByteN(), tagWND::strName, TextCopy(), and TRUE.

Referenced by NtUserGetAltTabInfo().

02641 { 02642 PSWINFO pswCurrent; 02643 02644 if (!gspwndAltTab || ((pswCurrent = Getpswi(gspwndAltTab)) == NULL)) { 02645 RIPERR0(ERROR_NOT_FOUND, RIP_WARNING, "no Alt-Tab window"); 02646 return FALSE; 02647 } 02648 02649 /* 02650 * Fill in general information 02651 */ 02652 pati->cItems = pswCurrent->iTotalTasks; 02653 pati->cColumns = pswCurrent->iNoOfColumns; 02654 pati->cRows = pswCurrent->iNoOfRows; 02655 02656 pati->iColFocus = pswCurrent->iCurCol; 02657 pati->iRowFocus = pswCurrent->iCurRow; 02658 02659 pati->cxItem = CXICONSLOT; 02660 pati->cyItem = CYICONSLOT; 02661 pati->ptStart = pswCurrent->ptFirstRowStart; 02662 02663 /* 02664 * Fill in specific information if asked. 02665 */ 02666 if (cchItemText && (iItem >= 0)) { 02667 PWND pwndCur; 02668 02669 pwndCur = NULL; 02670 02671 try { 02672 if ((iItem < pswCurrent->iTotalTasks) && 02673 (pwndCur = RevalidateHwnd(pswCurrent->pbwl->rghwnd[iItem]))) { 02674 if (bAnsi) { 02675 LPSTR ccxpszItemText = (LPSTR)ccxpwszItemText; 02676 ULONG cch; 02677 RtlUnicodeToMultiByteN(ccxpszItemText, cchItemText - 1, 02678 &cch, pwndCur->strName.Buffer, pwndCur->strName.Length); 02679 ccxpszItemText[cch] = '\0'; 02680 } else { 02681 TextCopy(&pwndCur->strName, ccxpwszItemText, cchItemText); 02682 } 02683 } else { 02684 // no such item 02685 NullTerminateString(ccxpwszItemText, bAnsi); 02686 } 02687 } except (W32ExceptionHandler(FALSE, RIP_WARNING)) { 02688 return FALSE; 02689 } 02690 } 02691 02692 return TRUE; 02693 }

PWND _GetNextQueueWindow PWND  pwnd,
BOOL  fPrev,
BOOL  fAltEsc
 

Definition at line 99 of file tmswitch.c.

References _GetWindow(), BOOL, FALSE, GetLastTopMostWindow(), GetTopLevelWindow(), gptiRit, grpdeskRitInput, gspwndAltTab, NULL, tagDESKTOP::pDeskInfo, PtiCurrent, tagDESKTOPINFO::spwnd, tagWND::spwndChild, tagWND::spwndLastActive, tagWND::spwndOwner, tagWND::spwndParent, TestWF, TRUE, WEFNOACTIVATE, WEFTOOLWINDOW, WEFTOPMOST, WFBOTTOMMOST, WFDISABLED, and WFVISIBLE.

Referenced by InitSwitchWndInfo(), xxxNextWindow(), xxxOldNextWindow(), xxxSwitchToThisWindow(), and zzzReattachThreads().

00103 { 00104 PWND pwndAltTab; 00105 PWND pwndNext; 00106 PWND pwndT; 00107 PWND pwndDesktop; 00108 BOOL bBeenHereAlready = FALSE; 00109 PTHREADINFO ptiAltTab; 00110 00111 /* 00112 * HACK: We have a problem with direct-draw full apps where an alttab 00113 * window is created on a queue owned other than the RIT. This 00114 * shows up by alt-tabbing away from ROIDS.EXE during fullscreen. 00115 * 00116 * What is happening is on a ALT-TAB, from xxxSysCommand(), the 00117 * thread is not a rit. xxxSysCommand() calls xxxOldNextWindow 00118 * which finds that the current-thread doesn't have a switch 00119 * window, and then creates one on the current-thread-queue. 00120 * 00121 * The hack here is to make sure the calling thread is the RIT 00122 * before allowing any cool-switch creation. 00123 * 00124 * 21-Mar-1996 : Chriswil 00125 */ 00126 #if 0 00127 ptiAltTab = PtiCurrent(); 00128 #else 00129 ptiAltTab = gptiRit; 00130 #endif 00131 00132 /* 00133 * If the window we receive is Null then use the last topmost window 00134 */ 00135 if (!pwnd) { 00136 pwnd = GetLastTopMostWindow(); 00137 if (!pwnd) { 00138 return NULL; 00139 } 00140 } 00141 00142 pwndAltTab = gspwndAltTab; 00143 00144 pwnd = pwndNext = GetTopLevelWindow(pwnd); 00145 if (!pwndNext) 00146 return NULL; 00147 00148 /* 00149 * Get the window's desktop 00150 */ 00151 if ((pwndDesktop = pwndNext->spwndParent) == NULL) { 00152 pwndDesktop = grpdeskRitInput->pDeskInfo->spwnd; 00153 pwnd = pwndNext = pwndDesktop->spwndChild; 00154 } 00155 00156 while (TRUE) { 00157 00158 if (pwndNext == NULL) 00159 return NULL; 00160 00161 /* 00162 * Get the next window 00163 */ 00164 pwndNext = _GetWindow(pwndNext, fPrev ? GW_HWNDPREV : GW_HWNDNEXT); 00165 00166 if (!pwndNext) { 00167 00168 pwndNext = fPrev ? _GetWindow(pwndDesktop->spwndChild, GW_HWNDLAST) 00169 : pwndDesktop->spwndChild; 00170 /* 00171 * To avoid searching the child chain forever, bale out if we get 00172 * to the end (beginning) of the chain twice. 00173 * This happens if pwnd is a partially destroyed window that has 00174 * been unlinked from its siblings but not yet unlinked from the 00175 * parent. (Happens while sending WM_NCDESTROY in xxxFreeWindow) 00176 */ 00177 if (bBeenHereAlready) { 00178 RIPMSG1(RIP_WARNING, "pwnd %#p is no longer a sibling", pwnd); 00179 return NULL; 00180 } 00181 00182 bBeenHereAlready = TRUE; 00183 } 00184 00185 /* 00186 * If we have gone all the way around with no success, return NULL. 00187 */ 00188 if (!pwndNext || (pwndNext == pwnd)) 00189 return NULL; 00190 00191 /* 00192 * Ignore the following windows: 00193 * Switch window 00194 * Tool Windows 00195 * NoActivate Windows 00196 * Hidden windows 00197 * Disabled windows 00198 * Topmost windows if via Alt+Esc 00199 * Bottommost windows if via Alt+Esc 00200 * 00201 * If we're doing Alt-Esc processing, we have to skip topmost windows. 00202 * 00203 * Because topmost windows don't really go to the back when we 00204 * send them there, alt-esc would never enumerate non-topmost windows. 00205 * So, although we're allowed to start enumeration at a topmost window, 00206 * we only allow enumeration of non-topmost windows, so the user can 00207 * enumerate his presumably more important applications. 00208 */ 00209 if ((pwndNext != pwndAltTab) && 00210 // BradG - Win95 is missing the check for Tool Windows 00211 (!TestWF(pwndNext, WEFTOOLWINDOW)) && 00212 (!TestWF(pwndNext, WEFNOACTIVATE)) && 00213 (TestWF(pwndNext, WFVISIBLE)) && 00214 ((pwndNext->spwndLastActive == NULL) || (!TestWF(pwndNext->spwndLastActive, WFDISABLED)) && 00215 (!fAltEsc || (!TestWF(pwndNext, WEFTOPMOST) && !TestWF(pwndNext, WFBOTTOMMOST))))) { 00216 /* 00217 * If this window is owned, don't return it unless it is the most 00218 * recently active window in its owner/ownee group. 00219 */ 00220 /* 00221 * Hard loop to find top level owner 00222 */ 00223 for (pwndT = pwndNext; pwndT->spwndOwner; pwndT = pwndT->spwndOwner) 00224 ; 00225 00226 /* 00227 * Don't return it unless it is the most recently active 00228 * window in its owner/ownee group. 00229 */ 00230 if (pwndNext == pwndT->spwndLastActive) 00231 return pwndNext; 00232 } 00233 } 00234 }

BOOL _IsTaskWindow PWND  pwnd,
PWND  pwndActive
 

Definition at line 384 of file tmswitch.c.

References BOOL, NULL, tagWND::spwndLastActive, TestWF, WEFAPPWINDOW, WEFNOACTIVATE, WEFTOOLWINDOW, WFDISABLED, and WFVISIBLE.

Referenced by _RemoveNonTaskWindows().

00387 { 00388 /* 00389 * Following windows do not qualify to be shown in task list: 00390 * Switch Window, Hidden windows (unless they are the active 00391 * window), Disabled windows, Kanji Conv windows. 00392 * 00393 * Also, check for a combobox popup list which has the top-most 00394 * style (it's spwndLastActive will be NULL). 00395 */ 00396 UserAssert(pwnd != NULL); 00397 return( (TestWF(pwnd, WEFAPPWINDOW) 00398 || (!TestWF(pwnd, WEFTOOLWINDOW) && !TestWF(pwnd, WEFNOACTIVATE))) && 00399 (TestWF(pwnd, WFVISIBLE) || (pwnd == pwndActive)) && 00400 (!(pwnd->spwndLastActive && TestWF(pwnd->spwndLastActive, WFDISABLED)))); 00401 }

INT _RemoveNonTaskWindows PBWL  pbwl,
PWND  pwndActive,
LPINT  lpiActiveTask,
PHWND pphwndLast
 

Definition at line 418 of file tmswitch.c.

References _IsTaskWindow(), INT, NULL, PHWND, RevalidateHwnd, tagBWL::rghwnd, tagWND::spwndLastActive, tagWND::spwndOwner, TestWF, WEFAPPWINDOW, WEFCONTROLPARENT, and WEFTOOLWINDOW.

Referenced by InitSwitchWndInfo().

00423 { 00424 INT iTaskCount = 0; 00425 PHWND phwnd; 00426 PWND pwnd; 00427 PWND pwndUse; 00428 PWND pwndOwnee; 00429 PHWND phwndHole; 00430 00431 *lpiActiveTask = -1; 00432 00433 /* 00434 * Walk down the window list and do the following: 00435 * 1. Remove all entries that do not qualify to be shown in the task list. 00436 * 2. Count the total number of windows that qualify. 00437 * 3. Get the pointer to the entry that contains current active window. 00438 * 4. Get the pointer to the last dummy entry (that has 1 in it) 00439 */ 00440 for (phwndHole = phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { 00441 pwnd = RevalidateHwnd( *phwnd ); 00442 // BradG - Win95 Assert 00443 // Maybe we just want to remove this window if it is gone. 00444 // UserAssert(pwnd != NULL); 00445 if (!pwnd) 00446 continue; 00447 00448 if (_IsTaskWindow(pwnd, pwndActive)) { 00449 pwndUse = pwnd; 00450 00451 // BradG - Why is Win95 doing this? 00452 // We aren't making any callbacks. 00453 // Assert(IsWindow32(hwndUse)); 00454 00455 /* 00456 * First let's find the task-list owner of this window 00457 */ 00458 while (!TestWF(pwndUse, WEFAPPWINDOW) && pwndUse->spwndOwner) { 00459 pwndOwnee = pwndUse; 00460 pwndUse = pwndUse->spwndOwner; 00461 if (TestWF(pwndUse, WEFTOOLWINDOW)) { 00462 /* 00463 * If this is the owner of a top level property sheet, 00464 * show the property sheet. 00465 */ 00466 if (TestWF(pwndOwnee, WEFCONTROLPARENT) && (pwndUse->spwndOwner == NULL)) { 00467 pwndUse = pwnd; 00468 } else { 00469 pwndUse = NULL; 00470 } 00471 break; 00472 } 00473 } 00474 00475 if (!pwndUse || !pwndUse->spwndLastActive) 00476 continue; 00477 00478 /* 00479 * walk up from the last active window 'til we find a valid task 00480 * list window or until we run out of windows in the ownership 00481 * chain 00482 */ 00483 for (pwndUse = pwndUse->spwndLastActive; pwndUse; pwndUse = pwndUse->spwndOwner) 00484 if (_IsTaskWindow(pwndUse, pwndActive)) 00485 break; 00486 00487 /* 00488 * if we ran out of windows in the ownership chain then use the 00489 * owned window itself -- or if we didn't run out of the ownership 00490 * chain, then only include this window if it's the window in the 00491 * ownership chain that we just found (VB will love us for it !) 00492 * -- jeffbog -- 4/20/95 -- Win95C B#2821 00493 */ 00494 if (!pwndUse || (pwndUse == pwnd)) { 00495 00496 /* 00497 * Do we have any holes above this? If so, move this handle to 00498 * that hole. 00499 */ 00500 if (phwndHole < phwnd) { 00501 00502 /* 00503 * Yes! There is a hole. Let us move the valid 00504 * handle there. 00505 */ 00506 *phwndHole = *phwnd; 00507 } 00508 00509 if (pwndActive == pwnd) 00510 *lpiActiveTask = iTaskCount; 00511 iTaskCount++; 00512 phwndHole++; // Move to the next entry. 00513 } 00514 00515 /* 00516 * Else, leave it as a hole for later filling. 00517 */ 00518 } 00519 } 00520 00521 *phwndHole = (HWND)1; 00522 *pphwndLast = phwndHole; 00523 00524 return iTaskCount; 00525 }

VOID CALLBACK DrawIconCallBack HWND  hwnd,
UINT  uMsg,
ULONG_PTR  dwData,
LRESULT  lResult
 

Definition at line 674 of file tmswitch.c.

References DrawIcon, FALSE, Getpswi(), HMValidateHandleNoRip(), INT, NULL, tagSwitchWndInfo::pbwl, PHWND, PICON, RevalidateHwnd, tagBWL::rghwnd, tagWND::spwndOwner, SYSICO, TestWF, ThreadLockAlways, ThreadUnlock, TYPE_CURSOR, VOID(), WFVISIBLE, and xxxPaintIconsInSwitchWindow().

Referenced by xxxPaintIconsInSwitchWindow().

00679 { 00680 PWND pwndAltTab; 00681 00682 /* 00683 * dwData is the pointer to the switch window handle. 00684 * If this Alt+Tab instance is still active, we need to derive this 00685 * window's index in the bwl array, otherwise, we are receiving an icon 00686 * for an old Alt+Tab window. 00687 */ 00688 pwndAltTab = RevalidateHwnd((HWND)dwData); 00689 if (pwndAltTab && TestWF(pwndAltTab, WFVISIBLE)) { 00690 00691 PSWINFO pswCurrent; 00692 PICON pIcon; 00693 PHWND phwnd; 00694 PWND pwnd; 00695 PWND pwndT; 00696 INT iStartTaskIndex; 00697 TL tlpwndAltTab; 00698 00699 /* 00700 * Derive this window's index in the BWL array 00701 */ 00702 if ((pwnd = RevalidateHwnd(hwnd)) == NULL) 00703 return; 00704 00705 /* 00706 * Get the switch window info 00707 */ 00708 pswCurrent = Getpswi(pwndAltTab); 00709 if (!pswCurrent) 00710 return; 00711 00712 for (iStartTaskIndex = 0, phwnd=&(pswCurrent->pbwl->rghwnd[0]); *phwnd != (HWND)1; phwnd++, iStartTaskIndex++) { 00713 /* 00714 * Because we list the active window in the Switch Window, the 00715 * hwnd here might not be the same, so we also need to walk back 00716 * to the top-level window to see if this is the right entry 00717 * in the list. 00718 */ 00719 for(pwndT = RevalidateHwnd(*phwnd); pwndT; pwndT = pwndT->spwndOwner) { 00720 if (pwnd == pwndT) 00721 goto DrawIcon; 00722 } 00723 } 00724 return; 00725 00726 /* 00727 * Convert the App's HICON into a PICON, or if the App did not return 00728 * an icon, use the Windows default icon. 00729 */ 00730 DrawIcon: 00731 pIcon = NULL; 00732 if (lResult) 00733 pIcon = HMValidateHandleNoRip((HCURSOR)lResult, TYPE_CURSOR); 00734 00735 if (!pIcon) 00736 pIcon = SYSICO(WINLOGO); 00737 00738 /* 00739 * Paint this icon in the Alt+Tab window. 00740 */ 00741 ThreadLockAlways(pwndAltTab, &tlpwndAltTab); 00742 xxxPaintIconsInSwitchWindow(pwndAltTab, 00743 pswCurrent, 00744 NULL, 00745 iStartTaskIndex, 00746 0, 00747 1, 00748 FALSE, 00749 FALSE, 00750 pIcon); 00751 ThreadUnlock(&tlpwndAltTab); 00752 } 00753 00754 UNREFERENCED_PARAMETER(uMsg); 00755 }

VOID DrawSwitchWndHilite PSWINFO  pswInfo,
HDC  hdcSwitch,
int  iCol,
int  iRow,
BOOL  fShow
 

Definition at line 538 of file tmswitch.c.

References _GetDCEx(), _ReleaseDC(), BOOL, CCHTITLEMAX, CopyRect, CXICONSLOT, CYICONSLOT, DF_PATCOPY, DrawFrame(), FillRect(), GETPWNDPPI, gpsi, gptiRit, gspwndAltTab, INT, _LARGE_UNICODE_STRING::Length, NULL, tagSwitchWndInfo::phwndCurrent, tagSwitchWndInfo::ptFirstRowStart, PtiCurrent, _LPKDRAWSWITCHWND::rcRect, tagSwitchWndInfo::rcTaskName, RevalidateHwnd, RtlInitLargeUnicodeString(), _LPKDRAWSWITCHWND::strName, tagWND::strName, SYSHBR, SYSRGB, TextCopy(), ThreadLock, ThreadUnlock, UINT, VOID(), and xxxSendMessageTimeout().

Referenced by xxxMoveSwitchWndHilite(), and xxxPaintSwitchWindow().

00544 { 00545 BOOL fGetAndReleaseIt; 00546 RECT rcTemp; 00547 PTHREADINFO ptiAltTab; 00548 /* 00549 * HACK: We have a problem with direct-draw full apps where an alttab 00550 * window is created on a queue owned other than the RIT. This 00551 * shows up by alt-tabbing away from ROIDS.EXE during fullscreen. 00552 * 00553 * What is happening is on a ALT-TAB, from xxxSysCommand(), the 00554 * thread is not a rit. xxxSysCommand() calls xxxOldNextWindow 00555 * which finds that the current-thread doesn't have a switch 00556 * window, and then creates one on the current-thread-queue. 00557 * 00558 * The hack here is to make sure the calling thread is the RIT 00559 * before allowing any cool-switch creation. 00560 * 00561 * 21-Mar-1996 : Chriswil 00562 */ 00563 #if 0 00564 ptiAltTab = PtiCurrent(); 00565 #else 00566 ptiAltTab = gptiRit; 00567 #endif 00568 00569 /* 00570 * Draw or erase the hilite depending on "fShow". 00571 */ 00572 if (fGetAndReleaseIt = (hdcSwitch == NULL)) 00573 hdcSwitch = _GetDCEx(gspwndAltTab, NULL, DCX_USESTYLE); 00574 00575 rcTemp.left = pswInfo->ptFirstRowStart.x + iCol * CXICONSLOT; 00576 rcTemp.top = pswInfo->ptFirstRowStart.y + iRow * CYICONSLOT; 00577 rcTemp.right = rcTemp.left + CXICONSLOT; 00578 rcTemp.bottom = rcTemp.top + CYICONSLOT; 00579 00580 DrawFrame(hdcSwitch, 00581 &rcTemp, 00582 2, 00583 DF_PATCOPY | ((fShow ? COLOR_HIGHLIGHT : COLOR_3DFACE) << 3)); 00584 00585 00586 /* 00587 * Update the Task title window. 00588 */ 00589 if (fShow) { 00590 WCHAR szText[CCHTITLEMAX]; 00591 INT cch; 00592 COLORREF clrOldText, clrOldBk; 00593 PWND pwnd; 00594 RECT rcRect; 00595 HFONT hOldFont; 00596 INT iLeft; 00597 ULONG_PTR dwResult = 0; 00598 00599 clrOldText = GreSetTextColor(hdcSwitch, SYSRGB(BTNTEXT)); 00600 clrOldBk = GreSetBkColor(hdcSwitch, SYSRGB(3DFACE)); 00601 hOldFont = GreSelectFont(hdcSwitch, gpsi->hCaptionFont); 00602 00603 00604 /* 00605 * Validate this window handle; This could be some app that terminated 00606 * in the background and the following line will GP fault in that case; 00607 * BOGUS: We should handle it some other better way. 00608 */ 00609 pwnd = RevalidateHwnd( *(pswInfo->phwndCurrent) ); 00610 if (pwnd) { 00611 /* 00612 * Get the windows title (up to MAXTASKNAMELEN's worth) 00613 */ 00614 // BradG - We can do better than MAXTASKNAMELEN characters! 00615 if (pwnd->strName.Length) { 00616 cch = TextCopy(&pwnd->strName, szText, CCHTITLEMAX); 00617 } else { 00618 *szText = TEXT('\0'); 00619 cch = 0; 00620 } 00621 00622 /* 00623 * Draw the text 00624 */ 00625 CopyRect(&rcRect, &pswInfo->rcTaskName); 00626 iLeft = rcRect.left; 00627 FillRect(hdcSwitch, &rcRect, SYSHBR(3DFACE)); 00628 /* 00629 * If an lpk is installed let it draw the text. 00630 */ 00631 if (GETPWNDPPI(pwnd)->dwLpkEntryPoints) { 00632 TL tlpwnd; 00633 LPKDRAWSWITCHWND LpkDrawSwitchWnd; 00634 00635 RtlInitLargeUnicodeString(&LpkDrawSwitchWnd.strName, szText, (UINT)-1); 00636 LpkDrawSwitchWnd.rcRect = rcRect; 00637 00638 ThreadLock(pwnd, &tlpwnd); 00639 xxxSendMessageTimeout(pwnd, WM_LPKDRAWSWITCHWND, (WPARAM)hdcSwitch, 00640 (LPARAM)&LpkDrawSwitchWnd, SMTO_ABORTIFHUNG, 100, &dwResult); 00641 ThreadUnlock(&tlpwnd); 00642 } 00643 /* 00644 * If the text wasn't draw by the lpk, draw it as best we can. 00645 */ 00646 if (dwResult == 0) { 00647 DRAWTEXTPARAMS dtp; 00648 00649 dtp.cbSize = sizeof(dtp); 00650 dtp.iLeftMargin = 0; 00651 dtp.iRightMargin = 0; 00652 DrawTextEx(hdcSwitch, szText, cch, &rcRect, DT_NOPREFIX | DT_END_ELLIPSIS | DT_SINGLELINE, &dtp ); 00653 } 00654 } 00655 00656 GreSelectFont(hdcSwitch, hOldFont); 00657 GreSetBkColor(hdcSwitch, clrOldBk); 00658 GreSetTextColor(hdcSwitch, clrOldText); 00659 } 00660 00661 if (fGetAndReleaseIt) 00662 _ReleaseDC(hdcSwitch); 00663 }

PWND DSW_GetTopLevelCreatorWindow PWND  pwnd  ) 
 

Definition at line 69 of file tmswitch.c.

References NULL, and tagWND::spwndOwner.

Referenced by xxxPaintIconsInSwitchWindow(), and xxxSetForegroundWindow().

00071 { 00072 UserAssert(pwnd != NULL); 00073 00074 if (pwnd != NULL) { 00075 while (pwnd->spwndOwner) 00076 pwnd = pwnd->spwndOwner; 00077 } 00078 00079 return pwnd; 00080 }

__inline PSWINFO Getpswi PWND  pwnd  ) 
 

Definition at line 48 of file tmswitch.c.

References FNID_SWITCH, GETFNID, and PSWITCHWND.

Referenced by _GetAltTabInfo(), DrawIconCallBack(), xxxNextWindow(), xxxOldNextWindow(), xxxPaintSwitchWindow(), xxxShowSwitchWindow(), and xxxSwitchWndProc().

00049 { 00050 UserAssert(GETFNID(pwnd) == FNID_SWITCH); 00051 return ((PSWITCHWND)pwnd)->pswi; 00052 }

PWND InitSwitchWndInfo PSWINFO lppswInfo,
PWND  pwndCurActive,
BOOL  fPrev
 

Definition at line 1120 of file tmswitch.c.

References _GetKeyState(), _GetNextQueueWindow(), _RemoveNonTaskWindows(), BuildHwndList(), BWL_ENUMLIST, CXICONSIZE, CXICONSLOT, tagSwitchWndInfo::cxSwitch, CYICONSIZE, CYICONSLOT, tagSwitchWndInfo::cySwitch, DbgPrint, FALSE, FreeHwndList(), tagSwitchWndInfo::fScroll, gcxCaptionFontChar, gcyCaptionFontChar, GETDESKINFO, GetFullScreen, GetPrimaryMonitor(), gnFastAltTabColumns, gnFastAltTabRows, gpsi, tagSwitchWndInfo::iCurCol, tagSwitchWndInfo::iCurRow, tagSwitchWndInfo::iFirstTaskIndex, tagSwitchWndInfo::iIconsInLastRow, tagSwitchWndInfo::iNoOfColumns, tagSwitchWndInfo::iNoOfRows, INT, tagSwitchWndInfo::iTasksShown, tagSwitchWndInfo::iTotalTasks, min, NextPrevTaskIndex(), NULL, tagSwitchWndInfo::pbwl, PHWND, tagSwitchWndInfo::phwndCurrent, tagSwitchWndInfo::phwndLast, tagSwitchWndInfo::ptFirstRowStart, PtiCurrent, tagMONITOR::rcMonitor, RevalidateHwnd, tagBWL::rghwnd, tagDESKTOPINFO::spwnd, tagWND::spwndChild, tagDESKTOPINFO::spwndShell, SWITCHWNDINFO, SYSMET, and TRUE.

Referenced by xxxNextWindow(), and xxxOldNextWindow().

01124 { 01125 PBWL pbwl; 01126 INT iTotalTasks; 01127 INT iCols, iRows, iIconsInLastRow; 01128 INT iDiff; 01129 PHWND phwndLast; 01130 PSWINFO pswInfo; 01131 INT iIconIndex; 01132 INT iCurRow, iCurCol; 01133 INT cxSwitch, cySwitch; 01134 INT iFirstRowIcons; 01135 INT iActiveTask; 01136 PWND pwnd = NULL; 01137 PTHREADINFO ptiCurrent = PtiCurrent(); 01138 PDESKTOPINFO pdeskinfo = GETDESKINFO(ptiCurrent); 01139 PMONITOR pMonitor = GetPrimaryMonitor(); 01140 01141 /* 01142 * Initialize the list 01143 */ 01144 *lppswInfo = (PSWINFO)NULL; 01145 01146 /* 01147 * Build the Window list of all the top level windows. 01148 */ 01149 #if 0 01150 if (!(pbwl = BuildHwndList(NULL, BWL_ENUMLIST | BWL_ALLDESKTOPS, NULL))) 01151 goto ReturnNextWnd; 01152 #else 01153 // BradG - HACK, enumerate on current desktop! 01154 // For the long run, we will need to enumerate all desktops 01155 // This will be tricky because we need to check the security of 01156 // each desktop, thus needing the user's security "token". 01157 if (!(pbwl = BuildHwndList(pdeskinfo->spwnd->spwndChild, BWL_ENUMLIST, NULL))) { 01158 #ifdef COOLSWITCHTRACE 01159 DbgPrint("CoolSwitch: BuildHwndList failed (contact bradg).\n"); 01160 UserAssert(pbwl != NULL); 01161 #endif 01162 goto ReturnNextWnd; 01163 } 01164 #endif 01165 01166 /* 01167 * Walk down the list and remove all non-task windows from the list. 01168 * Replace those hwnds with 0. 01169 */ 01170 if ((iTotalTasks = _RemoveNonTaskWindows(pbwl, pwndCurActive, &iActiveTask, &phwndLast)) < 2) { 01171 if (iTotalTasks == 1) { 01172 /* 01173 * If we have only one window and it's in full screen mode, we will 01174 * return the shell window so the can switch back to GDI mode. 01175 */ 01176 pwnd = RevalidateHwnd(pbwl->rghwnd[0]); 01177 if (pwnd && GetFullScreen(pwnd) == FULLSCREEN && pwndCurActive == pwnd) 01178 pwnd = pdeskinfo->spwndShell; 01179 01180 } else { 01181 pwnd = pdeskinfo->spwndShell; 01182 } 01183 #ifdef COOLSWITCHTRACE 01184 DbgPrint("CoolSwitch: Not enough windows to switch.\n"); 01185 #endif 01186 goto FreeAndReturnNextWnd; // If there isn't even two tasks, no switch wnd processing. 01187 } 01188 01189 /* 01190 * Allocate the Switch Info structure. If we don't have enough 01191 * memory, act as if we are doing Alt+Esc. 01192 */ 01193 if (!(pswInfo = (PSWINFO)UserAllocPoolWithQuota(sizeof(SWITCHWNDINFO), TAG_ALTTAB))) { 01194 #ifdef COOLSWITCHTRACE 01195 DbgPrint("CoolSwitch: UserAllocPool failed on 0x%X bytes (contact bradg).\n", sizeof(SWITCHWNDINFO)); 01196 UserAssert(pswInfo != NULL); 01197 #endif 01198 goto FreeAndReturnNextWnd; // Unable to alloc SwitchWndInfo struct. 01199 } 01200 01201 pswInfo->pbwl = pbwl; 01202 pswInfo->phwndLast = phwndLast; 01203 pswInfo->iTasksShown = pswInfo->iTotalTasks = iTotalTasks; 01204 01205 /* 01206 * Get the next/prev window that must become active. 01207 */ 01208 iIconIndex = NextPrevTaskIndex(pswInfo, iActiveTask, 1, !fPrev); 01209 pswInfo->phwndCurrent = &(pbwl->rghwnd[iIconIndex]); 01210 01211 iCols = min(gnFastAltTabColumns, iTotalTasks); 01212 iRows = iTotalTasks / iCols; // Truncation might occur. 01213 01214 iIconsInLastRow = iTotalTasks - iRows * iCols; 01215 iRows += (iIconsInLastRow ? 1 : 0); // Take care of earlier truncation. 01216 01217 /* 01218 * Restrict the number of rows to just MAXROWSALLOWED (3) 01219 */ 01220 if (iRows > gnFastAltTabRows) { 01221 iRows = gnFastAltTabRows; 01222 pswInfo->fScroll = TRUE; // We need to scroll. 01223 iIconsInLastRow = iCols; 01224 pswInfo->iTasksShown = iCols * iRows; 01225 } else { 01226 pswInfo->fScroll = FALSE; 01227 } 01228 01229 pswInfo->iNoOfColumns = iCols; 01230 pswInfo->iNoOfRows = iRows; 01231 01232 if (iIconsInLastRow == 0) 01233 iIconsInLastRow = pswInfo->iNoOfColumns; // Last Row is full. 01234 pswInfo->iIconsInLastRow = iIconsInLastRow; 01235 01236 /* 01237 * Find out Row and Col where the next/prev icon will lie. 01238 */ 01239 if (iIconIndex >= (iRows * iCols)) { 01240 /* 01241 * Next Icon lies outside. Bring it to the center. 01242 */ 01243 iCurRow = (iRows >> 2) + 1; 01244 iCurCol = (iCols >> 2) + 1; 01245 iDiff = (iIconIndex - ((iCurRow * iCols) + iCurCol)); 01246 } else { 01247 iDiff = 0; 01248 iCurRow = iIconIndex / iCols; 01249 iCurCol = iIconIndex - (iCurRow * iCols); 01250 } 01251 01252 pswInfo->iFirstTaskIndex = iDiff; 01253 pswInfo->iCurRow = iCurRow; 01254 pswInfo->iCurCol = iCurCol; 01255 01256 /* 01257 * Calculate the Switch Window Dimensions. 01258 */ 01259 cxSwitch = min( 01260 pMonitor->rcMonitor.right - pMonitor->rcMonitor.left, 01261 gnFastAltTabColumns * CXICONSLOT + 01262 CXICONSIZE / 2 + 01263 6 * gpsi->gclBorder * SYSMET(CXBORDER) + 01264 gcxCaptionFontChar); 01265 01266 cySwitch = min( 01267 pMonitor->rcMonitor.bottom - pMonitor->rcMonitor.top, 01268 iRows * CYICONSLOT + 01269 CYICONSIZE + 01270 gcyCaptionFontChar * 2 + 01271 gcyCaptionFontChar / 2); 01272 01273 /* 01274 * Find the number of icons in first row 01275 */ 01276 if (iRows == 1) { 01277 iFirstRowIcons = iIconsInLastRow; 01278 } else { 01279 iFirstRowIcons = iCols; 01280 } 01281 01282 /* 01283 * Center the icons based on the number of icons in first row. 01284 */ 01285 pswInfo->ptFirstRowStart.x = (cxSwitch - 4*gpsi->gclBorder*SYSMET(CXBORDER) - iFirstRowIcons * CXICONSLOT) >> 1; 01286 pswInfo->ptFirstRowStart.y = (CYICONSIZE >> 1); 01287 01288 pswInfo->cxSwitch = cxSwitch; 01289 pswInfo->cySwitch = cySwitch; 01290 01291 *lppswInfo = pswInfo; 01292 01293 return RevalidateHwnd(*(pswInfo->phwndCurrent)); // Success! 01294 01295 01296 /* 01297 * When there is insufficient mem to create the reqd structures, we simply 01298 * return the next window. We make the phwndInfo as NULL. So, we won't 01299 * attempt to draw the switch window. 01300 */ 01301 01302 FreeAndReturnNextWnd: 01303 FreeHwndList(pbwl); 01304 ReturnNextWnd: 01305 if (pwnd) 01306 return(pwnd); 01307 01308 return(_GetNextQueueWindow(pwndCurActive, _GetKeyState(VK_SHIFT) < 0, FALSE)); 01309 }

PHWND NextPrevPhwnd PSWINFO  pswInfo,
PHWND  phwnd,
BOOL  fNext
 

Definition at line 345 of file tmswitch.c.

References tagSwitchWndInfo::pbwl, PHWND, tagSwitchWndInfo::phwndLast, and tagBWL::rghwnd.

Referenced by xxxMoveSwitchWndHilite(), and xxxPaintIconsInSwitchWindow().

00349 { 00350 PBWL pbwl; 00351 PHWND phwndStart; 00352 PHWND phwndLast; 00353 00354 pbwl = pswInfo->pbwl; 00355 phwndStart = &(pbwl->rghwnd[0]); 00356 phwndLast = pswInfo->phwndLast; 00357 00358 UserAssert(*phwndLast == (HWND)1); // Last entry must have a 1. 00359 UserAssert(phwndStart < phwndLast); // There must be atleast one entry. 00360 UserAssert(phwnd != phwndLast); // Can't be passing in an invalid entry. 00361 00362 if (fNext) { 00363 phwnd++; 00364 if(phwnd == phwndLast) 00365 phwnd = phwndStart; 00366 } else { 00367 if (phwnd == phwndStart) { 00368 phwnd = phwndLast - 1; // we have atleast one valid entry. 00369 } else { 00370 phwnd--; 00371 } 00372 } 00373 00374 return phwnd; 00375 }

INT NextPrevTaskIndex PSWINFO  pswInfo,
INT  iIndex,
INT  iCount,
BOOL  fNext
 

Definition at line 313 of file tmswitch.c.

References INT, and tagSwitchWndInfo::iTotalTasks.

Referenced by InitSwitchWndInfo(), xxxMoveSwitchWndHilite(), and xxxPaintIconsInSwitchWindow().

00318 { 00319 UserAssert(iCount <= pswInfo->iTotalTasks); 00320 00321 if (fNext) { 00322 iIndex += iCount; 00323 if(iIndex >= pswInfo->iTotalTasks) 00324 iIndex -= pswInfo->iTotalTasks; 00325 } else { 00326 iIndex -= iCount; 00327 if(iIndex < 0) 00328 iIndex += pswInfo->iTotalTasks; 00329 } 00330 00331 UserAssert((iIndex >= 0) && (iIndex < pswInfo->iTotalTasks)); 00332 return iIndex; 00333 }

__inline void Setpswi PWND  pwnd,
PSWINFO  pswi
 

Definition at line 58 of file tmswitch.c.

References FNID_SWITCH, and GETFNID.

Referenced by xxxNextWindow(), and xxxOldNextWindow().

00059 { 00060 UserAssert(GETFNID(pwnd) == FNID_SWITCH); 00061 ((PSWITCHWND)pwnd)->pswi = pswi; 00062 }

VOID SwitchWndCleanup PSWINFO ppswInfo  ) 
 

Definition at line 1542 of file tmswitch.c.

References FreeHwndList(), NULL, and VOID().

Referenced by xxxNextWindow(), xxxOldNextWindow(), and xxxSwitchWndProc().

01544 { 01545 UserAssert(ppswInfo != NULL); 01546 UserAssert(*ppswInfo != NULL); 01547 01548 /* 01549 * First of all free the Window list. 01550 */ 01551 if ((*ppswInfo)->pbwl) 01552 FreeHwndList((*ppswInfo)->pbwl); 01553 UserFreePool(*ppswInfo); 01554 *ppswInfo = NULL; 01555 }

BOOL TSW_CalcRowAndCol PSWINFO  pswInfo,
INT  iTaskIndex,
LPINT  lpiRow,
LPINT  lpiCol
 

Definition at line 764 of file tmswitch.c.

References BOOL, FALSE, tagSwitchWndInfo::iFirstTaskIndex, tagSwitchWndInfo::iNoOfColumns, tagSwitchWndInfo::iNoOfRows, INT, tagSwitchWndInfo::iTotalTasks, and TRUE.

Referenced by xxxPaintIconsInSwitchWindow().

00769 { 00770 INT iDiff; 00771 INT iRow; 00772 00773 /* 00774 * Calculate how far is the given task from the first task shown 00775 * on the switch window. 00776 */ 00777 if ((iDiff = (iTaskIndex - pswInfo->iFirstTaskIndex)) < 0) 00778 iDiff += pswInfo->iTotalTasks; 00779 00780 /* 00781 * Calculate the Row and if this lies outside the switch window, return FALSE 00782 */ 00783 if ((iRow = iDiff / pswInfo->iNoOfColumns) >= pswInfo->iNoOfRows) 00784 return FALSE; 00785 00786 /* 00787 * Return the Row and column where this task lies. 00788 */ 00789 *lpiRow = iRow; 00790 *lpiCol = iDiff - (iRow * pswInfo->iNoOfColumns); 00791 00792 return TRUE; // This task lies within the switch window. 00793 }

VOID xxxCancelCoolSwitch void   ) 
 

Definition at line 1635 of file tmswitch.c.

References CheckCritIn, FWINABLE, gspwndAltTab, tagWND::head, IsWinEventNotifyDeferredOK, Lock, NULL, PtiCurrent, VOID(), WEF_USEPWNDTHREAD, xxxDestroyWindow(), and xxxWindowEvent().

Referenced by xxxButtonEvent(), xxxKeyEvent(), xxxNextWindow(), xxxOldNextWindow(), and xxxSwitchWndProc().

01637 { 01638 CheckCritIn(); 01639 UserAssert(IsWinEventNotifyDeferredOK()); 01640 01641 /* 01642 * Destroy the Cool Switch window 01643 */ 01644 if (gspwndAltTab != NULL) { 01645 01646 /* 01647 * Make sure that the thread calling this is the same 01648 * thread which created the alttab window. Otherwise, 01649 * we could end up with this window floating around until 01650 * the calling process dies. Remember, we can't destroy 01651 * windows across different threads. 01652 */ 01653 if (gspwndAltTab->head.pti != PtiCurrent()) 01654 return; 01655 01656 if (FWINABLE()) { 01657 xxxWindowEvent(EVENT_SYSTEM_SWITCHEND, gspwndAltTab, OBJID_CLIENT, 01658 0, WEF_USEPWNDTHREAD); 01659 } 01660 xxxDestroyWindow(gspwndAltTab); 01661 01662 Lock(&gspwndAltTab, NULL); 01663 } 01664 }

HWND xxxMoveSwitchWndHilite PWND  pwndSwitch,
PSWINFO  pswInfo,
BOOL  fPrev
 

Definition at line 1325 of file tmswitch.c.

References _GetDCEx(), _ReleaseDC(), BOOL, CheckLock, DrawSwitchWndHilite(), FALSE, tagSwitchWndInfo::fScroll, FWINABLE, tagSwitchWndInfo::iCurCol, tagSwitchWndInfo::iCurRow, tagSwitchWndInfo::iFirstTaskIndex, tagSwitchWndInfo::iIconsInLastRow, tagSwitchWndInfo::iNoOfColumns, tagSwitchWndInfo::iNoOfRows, INT, IsWinEventNotifyDeferredOK, NextPrevPhwnd(), NextPrevTaskIndex(), NULL, tagSwitchWndInfo::phwndCurrent, TRUE, WEF_USEPWNDTHREAD, xxxPaintIconsInSwitchWindow(), and xxxWindowEvent().

Referenced by xxxNextWindow(), and xxxOldNextWindow().

01329 { 01330 INT iCurCol, iCurRow; 01331 INT iMaxColumns; 01332 BOOL fLastRow; 01333 BOOL fNeedToScroll = FALSE; 01334 HDC hdc; 01335 01336 CheckLock(pwndSwitch); 01337 UserAssert(IsWinEventNotifyDeferredOK()); 01338 01339 iCurCol = pswInfo->iCurCol; 01340 iCurRow = pswInfo->iCurRow; 01341 01342 /* 01343 * Find out the new postion (row and column) of hilite. 01344 */ 01345 if (fPrev) { 01346 if (iCurCol > 0) { 01347 /* 01348 * Move cursor to prev column on the same row. 01349 */ 01350 iCurCol--; 01351 } else { 01352 /* 01353 * Try to move to the previous row. 01354 */ 01355 if (iCurRow > 0) { 01356 /* 01357 * Move to the last column on the previous row. 01358 */ 01359 iCurRow--; 01360 iCurCol = pswInfo->iNoOfColumns - 1; 01361 } else { 01362 /* 01363 * We are already at (0,0); See if we need to scroll. 01364 */ 01365 if (pswInfo->fScroll) { 01366 /* 01367 * Time to scroll; Scroll by one Row; 01368 * Repaint the whole window. 01369 */ 01370 fNeedToScroll = TRUE; 01371 pswInfo->iFirstTaskIndex = NextPrevTaskIndex(pswInfo, pswInfo->iFirstTaskIndex, 01372 pswInfo->iNoOfColumns, FALSE); 01373 iCurCol = pswInfo->iNoOfColumns - 1; 01374 } else { 01375 /* 01376 * Move the hilite to the last icon shown. 01377 */ 01378 iCurRow = pswInfo->iNoOfRows - 1; 01379 iCurCol = pswInfo->iIconsInLastRow - 1; 01380 } 01381 } 01382 } 01383 01384 } else { 01385 /* 01386 * !fPrev 01387 * Get the number of columns in the current row. 01388 */ 01389 if (fLastRow = (iCurRow == (pswInfo->iNoOfRows - 1))) // Are we at the last row? 01390 iMaxColumns = pswInfo->iIconsInLastRow; 01391 else 01392 iMaxColumns = pswInfo->iNoOfColumns; 01393 01394 /* 01395 * Are we at the last column yet? 01396 */ 01397 if (iCurCol < (iMaxColumns - 1)) { 01398 /* 01399 * No! Move to the right. 01400 */ 01401 iCurCol++; 01402 } else { 01403 /* 01404 * We are at the last column. 01405 * If we are not at last row, then move to next row. 01406 */ 01407 if (!fLastRow) { 01408 iCurCol = 0; 01409 iCurRow++; 01410 } else { 01411 /* 01412 * We are at the last row, last col; 01413 * See if we need to scroll. 01414 */ 01415 if (pswInfo->fScroll) { 01416 fNeedToScroll = TRUE; 01417 pswInfo->iFirstTaskIndex = NextPrevTaskIndex(pswInfo, pswInfo->iFirstTaskIndex, 01418 pswInfo->iNoOfColumns, TRUE); 01419 iCurCol = 0; 01420 } else { 01421 /* 01422 * Move to the top left corner (0, 0). 01423 */ 01424 iCurRow = iCurCol = 0; 01425 } 01426 } 01427 } 01428 } 01429 01430 /* 01431 * Move the phwnd to the next/prev 01432 */ 01433 pswInfo->phwndCurrent = NextPrevPhwnd(pswInfo, pswInfo->phwndCurrent, !fPrev); 01434 01435 /* 01436 * Remove Hilite from the current location. 01437 */ 01438 hdc = _GetDCEx(pwndSwitch, NULL, DCX_USESTYLE); 01439 DrawSwitchWndHilite(pswInfo, hdc, pswInfo->iCurCol, pswInfo->iCurRow, FALSE); 01440 01441 /* 01442 * Repaint if needed. 01443 */ 01444 if (fNeedToScroll) 01445 xxxPaintIconsInSwitchWindow(pwndSwitch, pswInfo, hdc, pswInfo->iFirstTaskIndex, 0, 0, TRUE, !fPrev, NULL); 01446 01447 /* 01448 * Draw Hilite at the new location. 01449 */ 01450 DrawSwitchWndHilite(pswInfo, hdc, iCurCol, iCurRow, TRUE); 01451 01452 _ReleaseDC(hdc); 01453 01454 pswInfo->iCurRow = iCurRow; 01455 pswInfo->iCurCol = iCurCol; 01456 01457 if (FWINABLE()) { 01458 xxxWindowEvent(EVENT_OBJECT_FOCUS, pwndSwitch, OBJID_CLIENT, 01459 iCurRow * pswInfo->iNoOfColumns + iCurCol + 1, WEF_USEPWNDTHREAD); 01460 } 01461 01462 return (*(pswInfo->phwndCurrent)); 01463 }

VOID xxxNextWindow PQ  pq,
DWORD  wParam
 

Definition at line 1675 of file tmswitch.c.

References _GetAsyncKeyState(), _GetNextQueueWindow(), _PostMessage(), BOOL, ClearMF, DbgPrint, FALSE, FDIR_BACKWARD, FDIR_FORWARD, tagSwitchWndInfo::fJournaling, Getpswi(), GETPTI, GetTopLevelWindow(), gLangToggleKeyState, glinp, gpqForeground, gptiRit, grpdeskRitInput, gspwndActivate, gspwndAltTab, gspwndFullScreen, gwMouseOwnerButton, HW, InitSwitchWndInfo(), IsWinEventNotifyDeferred, KLT_NONE, Lock, MFUNDERLINE, NextTopWindow(), NTW_PREVIOUS, NULL, tagDESKTOP::pDeskInfo, PtiCurrent, tagQ::ptiKeyboard, tagLASTINPUT::ptiLastWoken, PWND_BOTTOM, RevalidateHwnd, tagTHREADINFO::rpdesk, SetMF, Setpswi(), SFW_ACTIVATERESTORE, SFW_SWITCH, tagWND::spmenu, tagDESKTOPINFO::spwnd, tagQ::spwndActive, tagWND::spwndChild, tagQ::spwndFocus, SWITCHWNDCLASS, SwitchWndCleanup(), TestWF, ThreadLockAlwaysWithPti, ThreadLockPool, ThreadLockWithPti, ThreadUnlock, ThreadUnlockPool, TIF_CSRSSTHREAD, TIF_SYSTEMTHREAD, TRUE, Unlock, VER40, VOID(), WEFTOPMOST, WFCHILD, xxxCancelCoolSwitch(), xxxCreateWindowEx(), xxxMoveSwitchWndHilite(), xxxSendMessageTimeout(), xxxSendNotifyMessage(), xxxSetForegroundWindow2(), xxxSetThreadDesktop(), xxxSetWindowPos(), and xxxShowSwitchWindow().

Referenced by xxxKeyEvent().

01678 { 01679 PWND pwndActivateNext; 01680 PWND pwndCurrentActivate, pwndCurrentTopFocus; 01681 int fDir; 01682 TL tlpwndActivateNext; 01683 TL tlpwndCurrentActivate; 01684 TL tlpwndT; 01685 PSWINFO pswCurrent; 01686 ULONG_PTR dwResult; 01687 BOOL fNonRit = FALSE; 01688 PTHREADINFO ptiCurrent = PtiCurrent(); 01689 PTHREADINFO ptiAltTab; 01690 01691 UserAssert(!IsWinEventNotifyDeferred()); 01692 01693 /* 01694 * HACK: We have a problem with direct-draw full apps where an alttab 01695 * window is created on a queue owned other than the RIT. This 01696 * shows up by alt-tabbing away from ROIDS.EXE during fullscreen. 01697 * 01698 * What is happening is on a ALT-TAB, from xxxSysCommand(), the 01699 * thread is not a rit. xxxSysCommand() calls xxxOldNextWindow 01700 * which finds that the current-thread doesn't have a switch 01701 * window, and then creates one on the current-thread-queue. 01702 * 01703 * The hack here is to make sure the calling thread is the RIT 01704 * before allowing any cool-switch creation. 01705 * 01706 * 21-Mar-1996 : Chriswil 01707 */ 01708 #if 0 01709 ptiAltTab = ptiCurrent; 01710 #else 01711 ptiAltTab = gptiRit; 01712 #endif 01713 01714 if (pq == NULL) 01715 return; 01716 01717 fDir = (_GetAsyncKeyState(VK_SHIFT) < 0) ? FDIR_BACKWARD : FDIR_FORWARD; 01718 01719 /* 01720 * NOTE: As of NT 4.0 the slow Alt+Tab functionality now officially acts 01721 * like Alt+Esc with the exception that Alt+Tab will activate the window 01722 * where Alt+Esc will not. 01723 */ 01724 switch (wParam) { 01725 01726 case VK_TAB: 01727 01728 if (gspwndAltTab == NULL) { 01729 01730 PWND pwndSwitch; 01731 TL tlpSwitchInfo; 01732 01733 /* 01734 * We are entering Alt+Tab for the first time, we need to 01735 * initialize the Switch Window structure and if needed 01736 * create and display the Alt+Tab window. We have two special 01737 * cases: (1) The user does not want to use the Switch window, 01738 * (2) The initialize switch window fails thus we will act 01739 * just like slow Alt+Tab 01740 */ 01741 01742 /* 01743 * Since Alt+Shift is the default hotkey for keyboard layout switching, 01744 * Alt+Shift+Tab may cause a KL switching while AltTab window is up. 01745 * To prevent it, we'd better reset the global toggle key state here, 01746 * so that xxxScanSysQueue will not confuse when it handles keyup messages. 01747 */ 01748 gLangToggleKeyState = KLT_NONE; 01749 01750 /* 01751 * Mouse buttons sometimes get stuck down due to hardware glitches, 01752 * usually due to input concentrator switchboxes or faulty serial 01753 * mouse COM ports, so clear the global button state here just in case, 01754 * otherwise we may not be able to change focus with the mouse. 01755 * Also do this in zzzCancelJournalling (Ctr-Esc, Ctrl-Alt-Del, etc.) 01756 */ 01757 #if DBG 01758 if (gwMouseOwnerButton) 01759 RIPMSG1(RIP_WARNING, 01760 "gwMouseOwnerButton=%x, being forcibly cleared\n", 01761 gwMouseOwnerButton); 01762 #endif 01763 gwMouseOwnerButton = 0; 01764 01765 /* 01766 * Determine the current active window. 01767 */ 01768 Lock(&gspwndActivate, pq->spwndActive); 01769 if (gspwndActivate == NULL) { 01770 Lock(&gspwndActivate, grpdeskRitInput->pDeskInfo->spwnd->spwndChild); 01771 } 01772 01773 if (!gspwndActivate) { 01774 return; 01775 } 01776 01777 /* 01778 * Make a local copy of gspwndActivate and lock it because xxxFreeWindow will 01779 * unlock if it is the window being freed. 01780 */ 01781 pwndCurrentActivate = gspwndActivate; 01782 ThreadLockAlwaysWithPti(ptiCurrent, pwndCurrentActivate, &tlpwndCurrentActivate); 01783 01784 /* 01785 * Cancel the active window's mode 01786 */ 01787 xxxSendMessageTimeout(pwndCurrentActivate, WM_CANCELMODE, 0, 0, SMTO_ABORTIFHUNG, 100, &dwResult); 01788 01789 /* 01790 * Initialize the Switch Window data structure, if we 01791 * succeed create and display the window, otherwise act 01792 * like slow Alt+Tab. 01793 */ 01794 pwndActivateNext = InitSwitchWndInfo(&pswCurrent, pwndCurrentActivate, fDir); 01795 01796 ThreadLockWithPti(ptiCurrent, pwndActivateNext, &tlpwndActivateNext); 01797 01798 if (pswCurrent == NULL) { 01799 /* 01800 * Couldn't initialize our switch window data structure, so we 01801 * will act like Alt+Esc. 01802 */ 01803 goto DoSlowAltTab; 01804 } 01805 01806 if (pwndActivateNext == NULL) { 01807 SwitchWndCleanup(&pswCurrent); 01808 ThreadUnlock(&tlpwndActivateNext); 01809 ThreadUnlock(&tlpwndCurrentActivate); 01810 Unlock(&gspwndActivate); 01811 return; 01812 } 01813 01814 ThreadLockPool(ptiCurrent, pswCurrent, &tlpSwitchInfo); 01815 01816 /* 01817 * Since we are in the RIT, test the physical state of the keyboard 01818 */ 01819 pswCurrent->fJournaling = FALSE; 01820 01821 /* 01822 * Create the Alt+Tab window 01823 */ 01824 pwndSwitch = 01825 xxxCreateWindowEx( WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME, 01826 (PLARGE_STRING)SWITCHWNDCLASS, NULL, 01827 WS_POPUP | WS_BORDER | WS_DISABLED, 01828 0, 0, 10, 10, NULL, NULL, NULL, NULL, VER40); 01829 01830 if (gspwndAltTab != NULL) { 01831 UserAssert(0); 01832 01833 _PostMessage(gspwndAltTab, WM_CLOSE, 0, 0); 01834 } 01835 01836 Lock(&gspwndAltTab, pwndSwitch); 01837 01838 ThreadUnlockPool(ptiCurrent, &tlpSwitchInfo); 01839 01840 if (gspwndAltTab == NULL) { 01841 /* 01842 * Could not create the cool switch window, do the Alt+Esc thing 01843 */ 01844 #ifdef COOLSWITCHTRACE 01845 DbgPrint("CoolSwitch: Could not create window (contact bradg).\n"); 01846 UserAssert(gspwndAltTab != NULL); 01847 #endif 01848 SwitchWndCleanup(&pswCurrent); 01849 goto DoSlowAltTab; 01850 } 01851 01852 /* 01853 * Save the pointer to the switch window info structure 01854 */ 01855 Setpswi(gspwndAltTab, pswCurrent); 01856 /* 01857 * Set gspwndActivate so the RIT knows what window we would like 01858 * it to activate. 01859 */ 01860 Lock(&gspwndActivate, pwndActivateNext); 01861 01862 /* 01863 * Make sure that our rit queue has the correct pdesk 01864 */ 01865 if (ptiCurrent->TIF_flags & TIF_SYSTEMTHREAD) { 01866 xxxSetThreadDesktop(NULL, grpdeskRitInput); // DeferWinEventNotify() ?? IANJA ?? 01867 } 01868 01869 /* 01870 * If we're currently full screen tell console to switch to 01871 * the desktop to GDI mode; we can't do this on the RIT because 01872 * it can be slow. 01873 */ 01874 if (gspwndFullScreen != grpdeskRitInput->pDeskInfo->spwnd) { 01875 ThreadLockWithPti(ptiCurrent, grpdeskRitInput->pDeskInfo->spwnd, &tlpwndT); 01876 xxxSendNotifyMessage(grpdeskRitInput->pDeskInfo->spwnd, WM_FULLSCREEN, GDIFULLSCREEN, (LPARAM)HW(grpdeskRitInput->pDeskInfo->spwnd)); 01877 ThreadUnlock(&tlpwndT); 01878 } 01879 01880 /* 01881 * Show the Alt+Tab window. If it returns FALSE this means 01882 * the ALT key has been released, so there is no need to 01883 * paint the icons. 01884 */ 01885 ThreadLockAlwaysWithPti(ptiCurrent, gspwndAltTab, &tlpwndT); 01886 xxxShowSwitchWindow(gspwndAltTab); 01887 ThreadUnlock(&tlpwndT); 01888 01889 /* 01890 * Exit now because the Switch window will have been 01891 * already updated. 01892 */ 01893 ThreadUnlock(&tlpwndActivateNext); 01894 ThreadUnlock(&tlpwndCurrentActivate); 01895 01896 } else { 01897 01898 /* 01899 * We come here to do the actual switching and/or updating of 01900 * the switch window when in Alt+Tab mode. 01901 */ 01902 PWND pwndSwitch; 01903 TL tlpwndSwitch; 01904 PSWINFO pswCurrent; 01905 HWND hwndActivateNext; 01906 HWND hwndStop; 01907 01908 if (!(pwndSwitch = gspwndAltTab)) { 01909 01910 goto DoAltEsc; 01911 01912 } else { 01913 /* 01914 * Move the hilight rect to the next/prev task. It is possible 01915 * that some tasks were destoryed, so we need to skip those. 01916 */ 01917 pswCurrent = Getpswi(pwndSwitch); 01918 ThreadLockAlwaysWithPti(ptiCurrent, pwndSwitch, &tlpwndSwitch); 01919 hwndStop = NULL; 01920 do { 01921 hwndActivateNext = xxxMoveSwitchWndHilite(pwndSwitch, pswCurrent, fDir); 01922 if (!hwndStop) { 01923 hwndStop = hwndActivateNext; 01924 } else { 01925 if (hwndStop == hwndActivateNext) { 01926 pwndActivateNext = NULL; 01927 break; 01928 } 01929 } 01930 pwndActivateNext = RevalidateHwnd(hwndActivateNext); 01931 } while (!pwndActivateNext); 01932 ThreadUnlock(&tlpwndSwitch); 01933 Lock(&gspwndActivate, pwndActivateNext); 01934 if (!gspwndActivate) { 01935 /* 01936 * No Window to activate, bail out of Alt+Tab mode 01937 */ 01938 xxxCancelCoolSwitch(); 01939 } 01940 } 01941 } 01942 break; 01943 01944 DoAltEsc: 01945 case VK_ESCAPE: 01946 /* 01947 * NOTE: The RIT doesn't use gspwndActivate to activate the window when 01948 * processing Alt+Esc, we just use it here as a convenient 01949 * variable. The actual activation takes place below. 01950 */ 01951 pwndCurrentActivate = pq->spwndActive; 01952 if (pwndCurrentActivate == NULL) { 01953 pwndCurrentActivate = pq->ptiKeyboard->rpdesk->pDeskInfo->spwnd->spwndChild; 01954 } 01955 if (!pwndCurrentActivate) 01956 return; 01957 ThreadLockAlwaysWithPti(ptiCurrent, pwndCurrentActivate, &tlpwndCurrentActivate); 01958 01959 /* 01960 * Cancel the active window's mode 01961 */ 01962 xxxSendMessageTimeout(pwndCurrentActivate, WM_CANCELMODE, 0, 0, SMTO_ABORTIFHUNG, 100, &dwResult); 01963 01964 /* 01965 * Determine the next window to activate 01966 */ 01967 pwndActivateNext = _GetNextQueueWindow(pwndCurrentActivate, fDir, TRUE); 01968 ThreadLockWithPti(ptiCurrent, pwndActivateNext, &tlpwndActivateNext); 01969 01970 /* 01971 * If we're going forward through the windows, move the currently 01972 * active window to the bottom so we'll do the right thing when 01973 * we go backwards. 01974 */ 01975 if (pwndActivateNext != pwndCurrentActivate) { 01976 DoSlowAltTab: 01977 if (pwndActivateNext) { 01978 01979 /* 01980 * We're about to activate another window while the ALT key is down, 01981 * so let the current focus window know that it doesn't need the 01982 * menu underlines anymore 01983 */ 01984 pwndCurrentTopFocus = GetTopLevelWindow(pq->spwndFocus); 01985 if ((pwndCurrentTopFocus != NULL) && (pwndCurrentTopFocus->spmenu != NULL)) { 01986 ClearMF(pwndCurrentTopFocus->spmenu, MFUNDERLINE); 01987 } 01988 01989 if (fDir == FDIR_FORWARD) { 01990 /* 01991 * For Alt+ESC only move the window to the bottom if it's 01992 * not a top most window 01993 */ 01994 if (!TestWF(pwndCurrentActivate, WEFTOPMOST)) { 01995 xxxSetWindowPos(pwndCurrentActivate, PWND_BOTTOM, 0, 0, 0, 0, 01996 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | 01997 SWP_DEFERDRAWING | SWP_NOSENDCHANGING | 01998 SWP_ASYNCWINDOWPOS); 01999 } 02000 } 02001 02002 /* 02003 * The ALT key is down, so this window needs menu underlines 02004 */ 02005 if (pwndActivateNext->spmenu != NULL) { 02006 SetMF(pwndActivateNext->spmenu, MFUNDERLINE); 02007 } 02008 02009 02010 /* 02011 * This little ugly hack will cause xxxSetForegroundWindow2() 02012 * to send out an activation messages to a queue that is 02013 * already the active queue allowing us to change the active 02014 * window on that queue. 02015 */ 02016 if (gpqForeground == GETPTI(pwndActivateNext)->pq) 02017 gpqForeground = NULL; 02018 02019 /* 02020 * Make the selected window thread the owner of the last input; 02021 * since he's next, he owns the ALT-ESC. 02022 */ 02023 glinp.ptiLastWoken = GETPTI(pwndActivateNext); 02024 02025 xxxSetForegroundWindow2(pwndActivateNext, NULL, 02026 (wParam == VK_TAB) ? SFW_SWITCH | SFW_ACTIVATERESTORE : SFW_SWITCH); 02027 02028 /* 02029 * Win3.1 calls SetWindowPos() with activate, which z-orders 02030 * first regardless, then activates. Our code relies on 02031 * xxxActivateThisWindow() to z-order, and it'll only do 02032 * it if the window does not have the child bit set (regardless 02033 * that the window is a child of the desktop). 02034 * 02035 * To be compatible, we'll just force z-order here if the 02036 * window has the child bit set. This z-order is asynchronous, 02037 * so this'll z-order after the activate event is processed. 02038 * That'll allow it to come on top because it'll be foreground 02039 * then. (Grammatik has a top level window with the child 02040 * bit set that wants to be come the active window). 02041 */ 02042 if (wParam == VK_TAB && TestWF(pwndActivateNext, WFCHILD)) { 02043 xxxSetWindowPos(pwndActivateNext, (PWND)HWND_TOP, 0, 0, 0, 0, 02044 SWP_NOSIZE | SWP_NOMOVE | SWP_ASYNCWINDOWPOS); 02045 } 02046 } 02047 } 02048 ThreadUnlock(&tlpwndActivateNext); 02049 ThreadUnlock(&tlpwndCurrentActivate); 02050 break; 02051 02052 case VK_F6: 02053 if ((pwndCurrentActivate = pq->spwndActive) == NULL) 02054 pwndCurrentActivate = pq->ptiKeyboard->rpdesk->pDeskInfo->spwnd->spwndChild; 02055 02056 pwndActivateNext = pwndCurrentActivate; 02057 02058 /* 02059 * HACK! console sessions are all one thread but we want them 02060 * to act like different threads so if its a console thread (csrss.exe) 02061 * then ALT-F6 does nothing just like in Win 3.1 02062 * Note: we never get called with wParam == VK_F6 anyway. Win NT 3.51 02063 * doesn't seem to either, but Windows '95 does. BUG?? (IanJa) 02064 */ 02065 if (!(GETPTI(pwndActivateNext)->TIF_flags & TIF_CSRSSTHREAD)) { 02066 /* 02067 * on a alt-f6, we want to keep the switch within the thread. 02068 * We may want to rethink this because this will look strange 02069 * when you alt-f6 on a multi-threaded app we will not rotate 02070 * through the windows on the different threads. This works 02071 * fine on Win 3.x because it is single threaded. 02072 */ 02073 do { 02074 pwndActivateNext = NextTopWindow(pq->ptiKeyboard, pwndActivateNext, NULL, 02075 fDir ? NTW_PREVIOUS : 0); 02076 } while( (pwndActivateNext != NULL) && 02077 (GETPTI(pwndActivateNext) != pq->ptiKeyboard)); 02078 02079 if (pwndActivateNext != NULL) { 02080 02081 if (pwndActivateNext != pwndCurrentActivate) { 02082 /* 02083 * We're about to activate another window while the ALT key is down, 02084 * so let the current focus window know that it doesn't need the 02085 * menu underlines anymore 02086 */ 02087 pwndCurrentTopFocus = GetTopLevelWindow(pq->spwndFocus); 02088 if ((pwndCurrentTopFocus != NULL) && (pwndCurrentTopFocus->spmenu != NULL)) { 02089 ClearMF(pwndCurrentTopFocus->spmenu, MFUNDERLINE); 02090 } 02091 /* 02092 * The ALT key is down, so this window needs menu underlines 02093 */ 02094 if (pwndActivateNext->spmenu != NULL) { 02095 SetMF(pwndActivateNext->spmenu, MFUNDERLINE); 02096 } 02097 } 02098 02099 02100 ThreadLockAlwaysWithPti(ptiCurrent, pwndActivateNext, &tlpwndActivateNext); 02101 xxxSetWindowPos(pwndActivateNext, PWND_BOTTOM, 0, 0, 0, 0, 02102 SWP_DEFERDRAWING | SWP_NOSENDCHANGING | SWP_NOCHANGE | 02103 SWP_ASYNCWINDOWPOS); 02104 xxxSetForegroundWindow2(pwndActivateNext, NULL, SFW_SWITCH); 02105 ThreadUnlock(&tlpwndActivateNext); 02106 } 02107 } 02108 break; 02109 } 02110 }

VOID xxxOldNextWindow UINT  flags  ) 
 

Definition at line 2121 of file tmswitch.c.

References _CallMsgFilter(), _GetKeyState(), _GetNextQueueWindow(), _PostMessage(), ALT_ESCAPE, ALT_F6, BOOL, FALSE, tagSwitchWndInfo::fJournaling, Getpswi(), GETPTI, gpqForeground, gptiRit, grpdeskRitInput, gspwndAltTab, gspwndFullScreen, HW, InitSwitchWndInfo(), IsWinEventNotifyDeferredOK, Lock, msg, NextTopWindow(), NTW_PREVIOUS, NULL, tagDESKTOP::pDeskInfo, PtiCurrent, PtoH, PWND_BOTTOM, RevalidateHwnd, SCREEN_CAPTURE, Setpswi(), tagDESKTOPINFO::spwnd, tagQ::spwndActive, SWITCHWNDCLASS, SwitchWndCleanup(), TestWF, ThreadLockAlwaysWithPti, ThreadLockPool, ThreadLockWithPti, ThreadUnlock, ThreadUnlockPool, TRUE, UINT, VER40, VOID(), WEFTOPMOST, WFMINIMIZED, xxxCancelCoolSwitch(), xxxCapture(), xxxCreateWindowEx(), xxxDispatchMessage(), xxxMoveSwitchWndHilite(), xxxPeekMessage, xxxReleaseCapture(), xxxSendNotifyMessage(), xxxSetForegroundWindow(), xxxSetWindowPos(), xxxShowSwitchWindow(), xxxTranslateMessage(), and xxxWaitMessage().

Referenced by xxxSysCommand().

02123 { 02124 MSG msg; 02125 HWND hwndSel; 02126 PWND pwndNewSel; 02127 PWND pwndSel; 02128 BOOL fType = 0; 02129 BOOL fDrawIcon; 02130 WORD vk; 02131 TL tlpwndT; 02132 TL tlpwndSel; 02133 TL tlpwndSwitch; 02134 PSWINFO pswCurrent; 02135 PWND pwndSwitch; 02136 HWND hwndStop; 02137 HWND hwndNewSel; 02138 PTHREADINFO ptiCurrent = PtiCurrent(); 02139 PTHREADINFO ptiAltTab; 02140 UserAssert(IsWinEventNotifyDeferredOK()); 02141 02142 /* 02143 * HACK: We have a problem with direct-draw full apps where an alttab 02144 * window is created on a queue owned other than the RIT. This 02145 * shows up by alt-tabbing away from ROIDS.EXE during fullscreen. 02146 * 02147 * What is happening is on a ALT-TAB, from xxxSysCommand(), the 02148 * thread is not a rit. xxxSysCommand() calls xxxOldNextWindow 02149 * which finds that the current-thread doesn't have a switch 02150 * window, and then creates one on the current-thread-queue. 02151 * 02152 * The hack here is to make sure the calling thread is the RIT 02153 * before allowing any cool-switch creation. 02154 * 02155 * 21-Mar-1996 : Chriswil 02156 */ 02157 #if 0 02158 ptiAltTab = ptiCurrent; 02159 #else 02160 ptiAltTab = gptiRit; 02161 #endif 02162 02163 /* 02164 * Don't allow entering this routine when we're already in the AltTab 02165 * mode. The AltTab window may have been created via xxxNextWindow. 02166 */ 02167 if (gspwndAltTab != NULL) 02168 return; 02169 02170 if ((pwndSel = ptiCurrent->pq->spwndActive) == NULL) 02171 return; 02172 02173 ThreadLockWithPti(ptiCurrent, pwndSel, &tlpwndSel); 02174 xxxCapture(ptiCurrent, pwndSel, SCREEN_CAPTURE); 02175 02176 vk = (WORD)flags; 02177 msg.wParam = (UINT)flags; 02178 02179 pwndNewSel = NULL; 02180 02181 if (vk == VK_TAB) { 02182 02183 TL tlpSwitchInfo; 02184 02185 /* 02186 * Initialize the Switch window data structures 02187 */ 02188 pwndNewSel = InitSwitchWndInfo(&pswCurrent, 02189 pwndSel, 02190 _GetKeyState(VK_SHIFT) < 0); 02191 02192 if (pswCurrent == NULL) { 02193 /* 02194 * We were unable to initialize the data structure used by 02195 * the Switch window, so we will act like Alt+Esc. 02196 */ 02197 } else { 02198 02199 PWND pwndSwitch; 02200 02201 /* 02202 * We are doing a journal playback do use _GetKeyState to 02203 * test the keyboard 02204 */ 02205 pswCurrent->fJournaling = TRUE; 02206 02207 ThreadLockPool(ptiCurrent, pswCurrent, &tlpSwitchInfo); 02208 02209 /* 02210 * Attempt to create the Switch Window 02211 */ 02212 02213 pwndSwitch = 02214 xxxCreateWindowEx(WS_EX_TOOLWINDOW | WS_EX_WINDOWEDGE | WS_EX_DLGMODALFRAME, 02215 (PLARGE_STRING)SWITCHWNDCLASS, 02216 NULL, 02217 WS_POPUP | WS_BORDER | WS_DISABLED, 02218 0, 02219 0, 02220 10, 02221 10, 02222 NULL, 02223 NULL, 02224 NULL, 02225 NULL, 02226 VER40); 02227 02228 if (gspwndAltTab != NULL) { 02229 UserAssert(0); 02230 02231 _PostMessage(gspwndAltTab, WM_CLOSE, 0, 0); 02232 } 02233 02234 ThreadUnlockPool(ptiCurrent, &tlpSwitchInfo); 02235 02236 Lock(&gspwndAltTab, pwndSwitch); 02237 02238 02239 if (!(pwndSwitch = gspwndAltTab)) { 02240 02241 SwitchWndCleanup(&pswCurrent); 02242 02243 } else { 02244 /* 02245 * Lock the switch window 02246 */ 02247 ThreadLockAlwaysWithPti(ptiCurrent, pwndSwitch, &tlpwndSwitch); 02248 02249 /* 02250 * Save the switch window info 02251 */ 02252 Setpswi(pwndSwitch, pswCurrent); 02253 02254 // Don't we need to switch from full screen mode if needed? 02255 #if 0 02256 /* 02257 * If we're currently full screen tell console to switch to 02258 * the desktop to GDI mode; we can't do this on the RIT because 02259 * it can be slow. 02260 */ 02261 if (gspwndFullScreen != grpdeskRitInput->pDeskInfo->spwnd) { 02262 ThreadLockWithPti(pti, grpdeskRitInput->pDeskInfo->spwnd, &tlpwndT); 02263 xxxSendNotifyMessage(grpdeskRitInput->pDeskInfo->spwnd, WM_FULLSCREEN, GDIFULLSCREEN, (LONG)HW(grpdeskRitInput->pDeskInfo->spwnd)); 02264 ThreadUnlock(&tlpwndT); 02265 } 02266 #endif 02267 02268 /* 02269 * Show the switch window, this also will paint the window 02270 */ 02271 xxxShowSwitchWindow(gspwndAltTab); 02272 ThreadUnlock(&tlpwndSwitch); 02273 } 02274 } 02275 02276 } 02277 02278 if (!pwndNewSel) 02279 goto StartTab; 02280 02281 pwndSel = pwndNewSel; 02282 02283 while (TRUE) { 02284 02285 hwndSel = PtoH(pwndSel); 02286 /* 02287 * Wait for a message without getting it out of the queue. 02288 */ 02289 while (!xxxPeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE | PM_NOYIELD)) 02290 xxxWaitMessage(); 02291 02292 if ((pwndSel = RevalidateHwnd(hwndSel)) == NULL) 02293 pwndSel = ptiCurrent->pq->spwndActive; 02294 02295 if (_CallMsgFilter(&msg, MSGF_NEXTWINDOW)) { 02296 /* 02297 * Swallow the message if the hook processed it 02298 */ 02299 xxxPeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); 02300 continue; 02301 } 02302 02303 /* 02304 * If we are doing Alt+Tab and some other key comes in (other than 02305 * tab, escape or shift), then bomb out of this loop and leave that 02306 * key in the queue. 02307 */ 02308 if ((msg.message == WM_SYSKEYDOWN) && gspwndAltTab != NULL) { 02309 02310 vk = (WORD)msg.wParam; 02311 02312 if ((vk != VK_TAB) && (vk != VK_ESCAPE) && (vk != VK_SHIFT)) { 02313 pwndSel = ptiCurrent->pq->spwndActive; 02314 fType = 0; 02315 goto Exit; 02316 } 02317 } 02318 02319 switch (msg.message) { 02320 02321 case WM_CANCELJOURNAL: 02322 /* 02323 * If journalling was canceled we need to exit our loop and 02324 * remove the Alt+Tab window. We don't want to remove this 02325 * meesage because we want the app to know that journalling 02326 * was canceled. 02327 */ 02328 02329 /* > > > F A L L T H R O U G H < < < */ 02330 02331 case WM_LBUTTONDOWN: 02332 case WM_LBUTTONUP: 02333 case WM_RBUTTONDOWN: 02334 case WM_RBUTTONUP: 02335 case WM_MBUTTONDOWN: 02336 case WM_MBUTTONUP: 02337 case WM_XBUTTONDOWN: 02338 case WM_XBUTTONUP: 02339 /* 02340 * If mouse message, cancel and get out of loop. 02341 */ 02342 pwndSel = ptiCurrent->pq->spwndActive; 02343 fType = 0; 02344 goto Exit; 02345 02346 case WM_KEYUP: 02347 case WM_KEYDOWN: 02348 case WM_SYSCHAR: 02349 case WM_SYSKEYUP: 02350 case WM_MOUSEMOVE: 02351 /* 02352 * Swallow the message 02353 */ 02354 hwndSel = PtoH(pwndSel); 02355 xxxPeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); 02356 02357 if ((pwndSel = RevalidateHwnd(hwndSel)) == NULL) 02358 pwndSel = ptiCurrent->pq->spwndActive; 02359 02360 if (msg.message == WM_KEYUP || msg.message == WM_SYSKEYUP) { 02361 02362 vk = (WORD)msg.wParam; 02363 02364 /* 02365 * If alt-tab up, then exit. 02366 */ 02367 if (vk == VK_MENU) { 02368 /* 02369 * If doing Alt+Esc, wait for up of ESC to get out. 02370 */ 02371 if (gspwndAltTab == NULL) 02372 break; 02373 02374 fType = 0; 02375 goto Exit; 02376 02377 } else if (vk == VK_ESCAPE || vk == VK_F6) { 02378 /* 02379 * Get out on up transition of ESC or F6 keys. 02380 */ 02381 if (gspwndAltTab != NULL) { 02382 02383 pwndSel = ptiCurrent->pq->spwndActive; 02384 fType = 0; 02385 02386 } else { 02387 02388 fType = ((vk == VK_ESCAPE) ? ALT_ESCAPE : ALT_F6); 02389 } 02390 02391 goto Exit; 02392 } 02393 02394 } else if (msg.message == WM_KEYDOWN) { 02395 /* 02396 * Exit out loop is a stray key stroke comes through. In 02397 * particular look for VK_CONTROL. 02398 */ 02399 pwndSel = ptiCurrent->pq->spwndActive; 02400 fType = 0; 02401 goto Exit; 02402 } 02403 break; 02404 02405 case WM_SYSKEYDOWN: 02406 vk = (WORD)msg.wParam; 02407 02408 switch (vk) { 02409 02410 case VK_SHIFT: 02411 case VK_TAB: 02412 case VK_ESCAPE: 02413 case VK_F6: 02414 02415 hwndSel = PtoH(pwndSel); 02416 xxxPeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); 02417 02418 if ((pwndSel = RevalidateHwnd(hwndSel)) == NULL) 02419 pwndSel = ptiCurrent->pq->spwndActive; 02420 02421 if (!(vk == VK_TAB)) 02422 break; 02423 StartTab: 02424 if (vk == VK_ESCAPE) { 02425 pwndNewSel = _GetNextQueueWindow( 02426 pwndSel, 02427 _GetKeyState(VK_SHIFT) < 0, 02428 TRUE); 02429 02430 if (pwndNewSel == NULL) 02431 break; 02432 02433 fType = ALT_ESCAPE; 02434 pwndSel = pwndNewSel; 02435 02436 /* 02437 * Wait until ESC goes up to activate new window. 02438 */ 02439 break; 02440 } 02441 if (vk == VK_F6) { 02442 02443 PWND pwndFirst; 02444 PWND pwndSaveSel = pwndSel; 02445 02446 /* 02447 * Save the first returned window to act as a limit 02448 * to the search because NextTopWindow will return NULL 02449 * only if pwndSel is the only window that meets its 02450 * selection criteria. 02451 * 02452 * This prevents a hang that can occur in winword or 02453 * excel when then Alt-F4-F6 key combination is hit 02454 * and unsaved changes exist. 02455 */ 02456 pwndFirst = pwndNewSel = (PWND)NextTopWindow(ptiCurrent, pwndSel, NULL, 02457 _GetKeyState(VK_SHIFT) < 0 ? NTW_PREVIOUS : 0); 02458 02459 while (TRUE) { 02460 02461 /* 02462 * If pwndNewSel is NULL, pwndSel is the only candidate. 02463 */ 02464 if (pwndNewSel == NULL) 02465 break; 02466 02467 pwndSel = pwndNewSel; 02468 02469 /* 02470 * If the window is on the same thread, wait until 02471 * F6 goes up to activate new window. 02472 */ 02473 if (GETPTI(pwndSel) == ptiCurrent) 02474 break; 02475 02476 pwndNewSel = (PWND)NextTopWindow(ptiCurrent, pwndSel, NULL, 02477 _GetKeyState(VK_SHIFT) < 0 ? NTW_PREVIOUS : 0); 02478 02479 /* 02480 * If we've looped around, use the original window. 02481 * Wait until F6 goes up to activate new window. 02482 */ 02483 if (pwndNewSel == pwndFirst) { 02484 pwndSel = pwndSaveSel; 02485 break; 02486 } 02487 } 02488 break; 02489 } 02490 02491 /* 02492 * Here for the Alt+Tab case 02493 */ 02494 if ((pwndSwitch = gspwndAltTab) != NULL) { 02495 pswCurrent = Getpswi(pwndSwitch); 02496 ThreadLockWithPti(ptiCurrent, pwndSwitch, &tlpwndSwitch); 02497 hwndStop = NULL; 02498 do { 02499 02500 hwndNewSel = xxxMoveSwitchWndHilite( 02501 pwndSwitch, 02502 pswCurrent, 02503 _GetKeyState(VK_SHIFT) < 0); 02504 02505 if (!hwndStop) { 02506 hwndStop = hwndNewSel; 02507 } else { 02508 if (hwndStop == hwndNewSel) { 02509 pwndNewSel = NULL; 02510 break; 02511 } 02512 } 02513 pwndNewSel = RevalidateHwnd(hwndNewSel); 02514 } while (!pwndNewSel); 02515 ThreadUnlock(&tlpwndSwitch); 02516 pwndSel = pwndNewSel; 02517 02518 } else { 02519 02520 pwndNewSel = _GetNextQueueWindow( 02521 pwndSel, 02522 _GetKeyState(VK_SHIFT) < 0, 02523 FALSE); 02524 02525 if (pwndNewSel && pwndNewSel != pwndSel) { 02526 02527 if (!TestWF(pwndSel, WEFTOPMOST)) { 02528 /* 02529 * Force the old window to the bottom 02530 */ 02531 ThreadLockWithPti(ptiCurrent, pwndSel, &tlpwndT); 02532 xxxSetWindowPos(pwndSel, 02533 PWND_BOTTOM, 02534 0, 02535 0, 02536 0, 02537 0, 02538 SWP_NOMOVE | 02539 SWP_NOSIZE | 02540 SWP_NOACTIVATE | 02541 SWP_DEFERDRAWING | 02542 SWP_NOSENDCHANGING | 02543 SWP_ASYNCWINDOWPOS); 02544 ThreadUnlock(&tlpwndT); 02545 } 02546 02547 pwndSel = pwndNewSel; // Will be revalidated at top of loop 02548 } 02549 } 02550 break; 02551 02552 default: 02553 goto Exit; 02554 } 02555 break; 02556 02557 default: 02558 hwndSel = PtoH(pwndSel); 02559 xxxPeekMessage(&msg, NULL, msg.message, msg.message, PM_REMOVE); 02560 xxxTranslateMessage(&msg, 0); 02561 xxxDispatchMessage(&msg); 02562 02563 if ((pwndSel = RevalidateHwnd(hwndSel)) == NULL) 02564 pwndSel = ptiCurrent->pq->spwndActive; 02565 02566 break; 02567 } 02568 } 02569 02570 Exit: 02571 xxxReleaseCapture(); 02572 02573 fDrawIcon = (gspwndAltTab != NULL); 02574 02575 /* 02576 * If this is an Alt-Escape we also have to send the current window 02577 * to the bottom. 02578 */ 02579 if (fType == ALT_ESCAPE) { 02580 02581 PWND pwndActive; 02582 02583 if (gpqForeground) { 02584 02585 pwndActive = gpqForeground->spwndActive; 02586 02587 if (pwndActive && (pwndActive != pwndSel)) { 02588 ThreadLockWithPti(ptiCurrent, pwndActive, &tlpwndT); 02589 xxxSetWindowPos(pwndActive, 02590 PWND_BOTTOM, 02591 0, 02592 0, 02593 0, 02594 0, 02595 SWP_NOMOVE | 02596 SWP_NOSIZE | 02597 SWP_NOACTIVATE | 02598 SWP_DEFERDRAWING | 02599 SWP_NOSENDCHANGING | 02600 SWP_ASYNCWINDOWPOS); 02601 ThreadUnlock(&tlpwndT); 02602 } 02603 } 02604 } 02605 02606 if (pwndSel) { 02607 ThreadLockWithPti(ptiCurrent, pwndSel, &tlpwndT); 02608 xxxSetForegroundWindow(pwndSel, FALSE); 02609 02610 if (TestWF(pwndSel, WFMINIMIZED)) { 02611 02612 if ((fType == 0) && fDrawIcon) 02613 _PostMessage(pwndSel, WM_SYSCOMMAND, (UINT)SC_RESTORE, 0); 02614 02615 } 02616 ThreadUnlock(&tlpwndT); 02617 } 02618 02619 /* 02620 * destroy the alt-tab window 02621 */ 02622 xxxCancelCoolSwitch(); 02623 02624 ThreadUnlock(&tlpwndSel); 02625 }

VOID xxxPaintIconsInSwitchWindow PWND  ,
PSWINFO  ,
HDC  ,
INT  ,
INT  ,
INT  ,
BOOL  ,
BOOL  ,
PICON 
 

Definition at line 808 of file tmswitch.c.

References _DrawIconEx(), _GetAsyncKeyState(), _GetDCEx(), _GetKeyState(), _GetProp(), _ReleaseDC(), _ScrollDC(), tagSERVERINFO::atomIconProp, BOOL, CheckLock, CXICONSIZE, CXICONSLOT, cy, CYICONSIZE, CYICONSLOT, DrawIconCallBack(), DSW_GetTopLevelCreatorWindow(), FALSE, FillRect(), tagSwitchWndInfo::fJournaling, gpsi, HMValidateHandleNoRip(), tagSwitchWndInfo::iFirstTaskIndex, tagSwitchWndInfo::iNoOfColumns, tagSwitchWndInfo::iNoOfRows, INT, MAKEINTATOM, NextPrevPhwnd(), NextPrevTaskIndex(), NULL, tagSwitchWndInfo::pbwl, tagWND::pcls, PHWND, PICON, PROPF_INTERNAL, tagSwitchWndInfo::ptFirstRowStart, PtoH, RevalidateHwnd, tagBWL::rghwnd, SYSHBR, SYSICO, SYSMET, TestWF, ThreadLock, ThreadUnlock, TRUE, TSW_CalcRowAndCol(), TYPE_CURSOR, VOID(), WFWIN40COMPAT, and xxxSendMessageCallback().

Referenced by DrawIconCallBack(), xxxMoveSwitchWndHilite(), and xxxPaintSwitchWindow().

00818 { 00819 INT cx, cy, xStart; 00820 PHWND phwnd; 00821 BOOL fGetAndReleaseIt; 00822 INT iColumnIndex = 0; 00823 RECT rcScroll; 00824 PWND pwnd; 00825 TL tlpwnd; 00826 HICON hIcon; 00827 RECT rcIcon; 00828 00829 CheckLock(pwndAltTab); 00830 00831 /* 00832 * If we were not supplied a DC, get ghwndSwitch's and set a flag 00833 * so we remember to release it. 00834 */ 00835 if (fGetAndReleaseIt = (hdc == NULL)) 00836 hdc = _GetDCEx(pwndAltTab, NULL, DCX_USESTYLE); 00837 00838 cx = pswInfo->ptFirstRowStart.x; 00839 cy = pswInfo->ptFirstRowStart.y; 00840 00841 if (fScroll) { 00842 00843 rcScroll.left = cx; 00844 rcScroll.top = cy; 00845 rcScroll.right = cx + CXICONSLOT * pswInfo->iNoOfColumns; 00846 rcScroll.bottom = cy + CYICONSLOT * pswInfo->iNoOfRows; 00847 00848 _ScrollDC(hdc, 00849 0, 00850 (fUp ? -CYICONSLOT : CYICONSLOT), 00851 &rcScroll, 00852 &rcScroll, 00853 NULL, 00854 NULL); 00855 00856 iStartRow = (fUp ? pswInfo->iNoOfRows - 1 : 0); 00857 iNoOfIcons = pswInfo->iNoOfColumns; 00858 iStartTaskIndex = (fUp ? NextPrevTaskIndex(pswInfo, pswInfo->iFirstTaskIndex, 00859 (pswInfo->iNoOfRows - 1) * pswInfo->iNoOfColumns, TRUE) : 00860 pswInfo->iFirstTaskIndex); 00861 } 00862 00863 if (pIcon) { 00864 /* 00865 * If pIcon is given, this is to paint just one icon during callback. 00866 */ 00867 // BradG - Win95 Assert 00868 UserAssert(iNoOfIcons == 1); 00869 00870 /* 00871 * Due to earlier scrolling, the row number would have changed. So, 00872 * recalc the row and column from the iStartTaskIndex given. 00873 */ 00874 if (!TSW_CalcRowAndCol(pswInfo, iStartTaskIndex, &iStartRow, &iColumnIndex)) 00875 goto Cleanup; 00876 } 00877 00878 xStart = cx += (CXICONSLOT - CXICONSIZE) / 2; 00879 cx += iColumnIndex * CXICONSLOT; 00880 cy += ((CYICONSLOT - CYICONSIZE) / 2) + iStartRow * CYICONSLOT; 00881 phwnd = &(pswInfo->pbwl->rghwnd[iStartTaskIndex]); 00882 00883 /* 00884 * Draw all the icons one by one. 00885 */ 00886 while (iNoOfIcons--) { 00887 /* 00888 * If the Alt+Key is no longer down, abort painting icons. 00889 */ 00890 if ((pswInfo->fJournaling && _GetKeyState(VK_MENU) >= 0) || 00891 (!pswInfo->fJournaling && _GetAsyncKeyState(VK_MENU) >= 0)) 00892 goto Cleanup; 00893 00894 /* 00895 * Check if this window is still alive. (Some task could have 00896 * terminated in the background) 00897 */ 00898 if (pwnd = RevalidateHwnd(*phwnd)) { 00899 /* 00900 * Find the window's top-level owner 00901 */ 00902 pwnd = DSW_GetTopLevelCreatorWindow(pwnd); 00903 00904 /* 00905 * If we don't have an icon, find one 00906 */ 00907 if (!pIcon) { 00908 /* 00909 * Try window icon 00910 */ 00911 hIcon = (HICON)_GetProp(pwnd, MAKEINTATOM(gpsi->atomIconProp), PROPF_INTERNAL); 00912 if (hIcon) { 00913 pIcon = (PICON)HMValidateHandleNoRip(hIcon, TYPE_CURSOR); 00914 } 00915 00916 /* 00917 * If we don't have an icon yet, try the class icon 00918 */ 00919 if (!pIcon) { 00920 pIcon = pwnd->pcls->spicn; 00921 } 00922 00923 /* 00924 * If we don't have an icon yet, use WM_QUERYDRAGICON to ask 00925 * 3,x apps for their icon. 00926 */ 00927 if (!pIcon && !TestWF(pwnd, WFWIN40COMPAT)) { 00928 /* 00929 * The callback routine will paint the icon for 00930 * us, so just leave pIcon set to NULL 00931 */ 00932 ThreadLock(pwnd, &tlpwnd); 00933 xxxSendMessageCallback(pwnd, WM_QUERYDRAGICON, 0, 0, 00934 (SENDASYNCPROC)DrawIconCallBack, 00935 HandleToUlong(PtoH(pwndAltTab)), FALSE); 00936 ThreadUnlock(&tlpwnd); 00937 } else { 00938 /* 00939 * If we can't find an icon, so use the Windows icon 00940 */ 00941 if (!pIcon) { 00942 pIcon = SYSICO(WINLOGO); 00943 } 00944 } 00945 } 00946 } 00947 00948 if (pIcon) { 00949 _DrawIconEx(hdc, cx, cy, pIcon, SYSMET(CXICON), SYSMET(CYICON), 00950 0, SYSHBR(3DFACE), DI_NORMAL); 00951 } else if (fScroll) { 00952 /* 00953 * NOT IN WIN95 00954 * 00955 * No icon was available, do while we are waiting for the 00956 * application to paint it's icon, we need to "erase" the 00957 * background in case we have scrolled the window. 00958 */ 00959 rcIcon.left = cx; 00960 rcIcon.top = cy; 00961 rcIcon.right = cx + SYSMET(CXICON); 00962 rcIcon.bottom = cy + SYSMET(CYICON); 00963 FillRect(hdc, &rcIcon, SYSHBR(3DFACE)); 00964 } 00965 00966 /* 00967 * Check if we are done. 00968 */ 00969 if (iNoOfIcons <= 0) 00970 break; 00971 00972 /* 00973 * Reset hIcon for the next run through the loop 00974 */ 00975 pIcon = NULL; 00976 00977 /* 00978 * Move all pointers to the next task/icon. 00979 */ 00980 phwnd = NextPrevPhwnd(pswInfo, phwnd, TRUE); // Get next. 00981 00982 /* 00983 * Is it going to be in the same row; then adjust cx and cy. 00984 */ 00985 if (++iColumnIndex >= pswInfo->iNoOfColumns) { 00986 iColumnIndex = 0; 00987 cx = xStart; // Move to first column 00988 cy += CYICONSLOT; // Move to next row. 00989 iStartRow++; 00990 } else { 00991 /* 00992 * else, adjust cx; 00993 */ 00994 cx += CXICONSLOT; 00995 } 00996 00997 iStartTaskIndex = NextPrevTaskIndex(pswInfo, iStartTaskIndex, 1, TRUE); 00998 } 00999 01000 Cleanup: 01001 if (fGetAndReleaseIt) 01002 _ReleaseDC(hdc); 01003 }

VOID xxxPaintSwitchWindow PWND  pwndSwitch  ) 
 

Definition at line 1012 of file tmswitch.c.

References _GetAsyncKeyState(), _GetClientRect(), _GetDCEx(), _GetKeyState(), _ReleaseDC(), CheckLock, CopyInflateRect(), DrawEdge(), DrawSwitchWndHilite(), FALSE, FillRect(), tagSwitchWndInfo::fJournaling, gcxCaptionFontChar, gcyCaptionFontChar, Getpswi(), tagSwitchWndInfo::iCurCol, tagSwitchWndInfo::iCurRow, tagSwitchWndInfo::iFirstTaskIndex, InflateRect(), tagSwitchWndInfo::iTasksShown, NULL, tagSwitchWndInfo::rcTaskName, SYSHBR, TestWF, TRUE, VOID(), WFVISIBLE, and xxxPaintIconsInSwitchWindow().

Referenced by xxxSwitchWndProc().

01014 { 01015 LPRECT lprcRect; 01016 RECT rcRgn; 01017 HDC hdcSwitch; 01018 PSWINFO pswCurrent; 01019 CheckLock(pwndSwitch); 01020 01021 /* 01022 * If our window isn't visible, return 01023 */ 01024 if (!TestWF(pwndSwitch, WFVISIBLE)) 01025 return; 01026 01027 /* 01028 * Get the switch window information 01029 */ 01030 pswCurrent = Getpswi(pwndSwitch); 01031 if (!pswCurrent) 01032 return; 01033 01034 /* 01035 * Get the Switch windows DC so we can paint with it 01036 */ 01037 hdcSwitch = _GetDCEx(pwndSwitch, NULL, DCX_USESTYLE ); 01038 01039 /* 01040 * Paint the background of the Switch Screen. 01041 */ 01042 if ((pswCurrent->fJournaling && _GetKeyState(VK_MENU) >= 0) || 01043 (!pswCurrent->fJournaling && _GetAsyncKeyState(VK_MENU) >= 0)) 01044 goto PSWExit; 01045 01046 lprcRect = &(pswCurrent->rcTaskName); 01047 _GetClientRect(pwndSwitch, lprcRect); 01048 FillRect(hdcSwitch, lprcRect, SYSHBR(3DFACE)); 01049 01050 /* 01051 * Store this "caption" area back into the current switch 01052 * window data structure. 01053 */ 01054 InflateRect(lprcRect, -(gcxCaptionFontChar << 1), -(gcyCaptionFontChar)); 01055 lprcRect->top = lprcRect->bottom - gcyCaptionFontChar; 01056 01057 /* 01058 * Draw the sunken edge for showing the task names. 01059 */ 01060 if ((pswCurrent->fJournaling && _GetKeyState(VK_MENU) >= 0) || 01061 (!pswCurrent->fJournaling && _GetAsyncKeyState(VK_MENU) >= 0)) 01062 goto PSWExit; 01063 CopyInflateRect(&rcRgn, lprcRect, gcxCaptionFontChar >> 1, gcyCaptionFontChar >> 1); 01064 DrawEdge(hdcSwitch, &rcRgn, EDGE_SUNKEN, BF_RECT); 01065 01066 /* 01067 * Paint the icons 01068 */ 01069 if ((pswCurrent->fJournaling && _GetKeyState(VK_MENU) >= 0) || 01070 (!pswCurrent->fJournaling && _GetAsyncKeyState(VK_MENU) >= 0)) 01071 goto PSWExit; 01072 01073 xxxPaintIconsInSwitchWindow(pwndSwitch, 01074 pswCurrent, 01075 hdcSwitch, 01076 pswCurrent->iFirstTaskIndex, 01077 0, 01078 pswCurrent->iTasksShown, 01079 FALSE, 01080 FALSE, 01081 NULL); 01082 01083 /* 01084 * So, just draw the hilite. 01085 */ 01086 if ((pswCurrent->fJournaling && _GetKeyState(VK_MENU) >= 0) || 01087 (!pswCurrent->fJournaling && _GetAsyncKeyState(VK_MENU) >= 0)) 01088 goto PSWExit; 01089 01090 DrawSwitchWndHilite(pswCurrent, 01091 hdcSwitch, 01092 pswCurrent->iCurCol, 01093 pswCurrent->iCurRow, 01094 TRUE); 01095 01096 /* 01097 * Release the switch windows DC 01098 */ 01099 PSWExit: 01100 _ReleaseDC(hdcSwitch); 01101 }

BOOL xxxShowSwitchWindow PWND  pwndAltTab  ) 
 

Definition at line 1476 of file tmswitch.c.

References _GetAsyncKeyState(), _GetKeyState(), BOOL, CheckLock, tagSwitchWndInfo::cxSwitch, tagSwitchWndInfo::cySwitch, DbgPrint, FALSE, tagSwitchWndInfo::fJournaling, FWINABLE, GetPrimaryMonitor(), Getpswi(), tagSwitchWndInfo::iCurCol, tagSwitchWndInfo::iCurRow, tagSwitchWndInfo::iNoOfColumns, IsWinEventNotifyDeferredOK, NULL, PWND_TOPMOST, tagMONITOR::rcWork, TestWF, TRUE, WEF_USEPWNDTHREAD, WFVISIBLE, xxxSetWindowPos(), xxxUpdateWindow(), and xxxWindowEvent().

Referenced by xxxNextWindow(), and xxxOldNextWindow().

01478 { 01479 PSWINFO pswInfo; 01480 PMONITOR pMonitorSwitch = GetPrimaryMonitor(); 01481 CheckLock(pwndAltTab); 01482 UserAssert(IsWinEventNotifyDeferredOK()); 01483 01484 /* 01485 * Get the switch window information 01486 */ 01487 pswInfo = Getpswi(pwndAltTab); 01488 UserAssert(pswInfo != NULL); 01489 01490 /* 01491 * If the key is not down, don't bother to display Switch Window. 01492 */ 01493 if ((pswInfo->fJournaling && _GetKeyState(VK_MENU) >= 0) || 01494 (!pswInfo->fJournaling && _GetAsyncKeyState(VK_MENU) >= 0)) { 01495 #ifdef COOLSWITCHTRACE 01496 DbgPrint("CoolSwitch: Not displaying window because VM_MENU is up (contact bradg).\n"); 01497 #endif 01498 return FALSE; 01499 } 01500 01501 /* 01502 * Bring and position the window on top. 01503 */ 01504 xxxSetWindowPos(pwndAltTab, PWND_TOPMOST, 0,0,0,0, 01505 SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | SWP_NOREDRAW ); 01506 01507 if (!TestWF(pwndAltTab, WFVISIBLE)) { 01508 xxxSetWindowPos( 01509 pwndAltTab, 01510 PWND_TOPMOST, 01511 (pMonitorSwitch->rcWork.left + pMonitorSwitch->rcWork.right - pswInfo->cxSwitch) / 2, 01512 (pMonitorSwitch->rcWork.top + pMonitorSwitch->rcWork.bottom - pswInfo->cySwitch) / 2, 01513 pswInfo->cxSwitch, 01514 pswInfo->cySwitch, 01515 SWP_SHOWWINDOW | SWP_NOACTIVATE); 01516 } 01517 #ifdef COOLSWITCHTRACE 01518 UserAssert(TestWF(pwndAltTab, WFVISIBLE)); 01519 #endif 01520 xxxUpdateWindow(pwndAltTab); 01521 01522 if (FWINABLE()) { 01523 xxxWindowEvent(EVENT_SYSTEM_SWITCHSTART, pwndAltTab, OBJID_CLIENT, 01524 0, WEF_USEPWNDTHREAD); 01525 xxxWindowEvent(EVENT_OBJECT_FOCUS, pwndAltTab, OBJID_CLIENT, 01526 pswInfo->iCurRow * pswInfo->iNoOfColumns + pswInfo->iCurCol + 1, 01527 WEF_USEPWNDTHREAD); 01528 } 01529 01530 return TRUE; 01531 }

VOID xxxSwitchToThisWindow PWND  pwnd,
BOOL  fAltTab
 

Definition at line 253 of file tmswitch.c.

References _GetNextQueueWindow(), BOOL, CheckLock, FDIR_FORWARD, GETPTI, gpqForeground, PostEventMessage(), PWND_BOTTOM, QEVENT_POSTMESSAGE, tagQ::spwndActive, TestWF, ThreadLock, ThreadUnlock, TRUE, VOID(), WEFTOPMOST, WFBOTTOMMOST, WFMINIMIZED, xxxSetForegroundWindow(), and xxxSetWindowPos().

00256 { 00257 CheckLock(pwnd); 00258 00259 /* 00260 * If we need to, push old window to the bottom. 00261 */ 00262 if (gpqForeground && !fAltTab) { 00263 00264 BOOL fPush; 00265 PWND pwndActive; 00266 TL tlpwndActive; 00267 00268 /* 00269 * if ALT-ESC, and the window brought forward is the next one in the 00270 * list, we must be rotating the zorder forward, so push the current 00271 * window to the back 00272 */ 00273 pwndActive = gpqForeground->spwndActive; 00274 fPush = pwndActive && _GetNextQueueWindow(pwndActive, FDIR_FORWARD, !fAltTab); 00275 if (fPush && !TestWF(pwndActive, WEFTOPMOST) && !TestWF(pwndActive, WFBOTTOMMOST)) { 00276 ThreadLock(pwndActive, &tlpwndActive); 00277 xxxSetWindowPos(pwndActive, PWND_BOTTOM, 0, 0, 0, 0, 00278 SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE | SWP_ASYNCWINDOWPOS); 00279 ThreadUnlock(&tlpwndActive); 00280 } 00281 } 00282 00283 /* 00284 * Switch this new window to the foreground 00285 * This window can go away during the SetForeground call if it isn't 00286 * on the thread calling SwitchToThisWindow()! 00287 */ 00288 xxxSetForegroundWindow(pwnd, TRUE); 00289 00290 /* 00291 * Restore minimized windows if the Alt+Tab case 00292 */ 00293 if (fAltTab && TestWF(pwnd,WFMINIMIZED)) { 00294 00295 /* 00296 * We need to package up a special 'posted' queue message here. This 00297 * ensures that this message gets processed after the asynchronous 00298 * activation event occurs (via SetForegroundWindow). 00299 */ 00300 PostEventMessage(GETPTI(pwnd), GETPTI(pwnd)->pq, 00301 QEVENT_POSTMESSAGE, pwnd, WM_SYSCOMMAND, 00302 SC_RESTORE, 0 ); 00303 } 00304 }

LRESULT xxxSwitchWndProc PWND  pwnd,
UINT  message,
WPARAM  wParam,
LPARAM  lParam
 

Definition at line 1564 of file tmswitch.c.

References CheckLock, FNID_SWITCH, Getpswi(), IsWinEventNotifyDeferredOK, NULL, tagWND::pcls, PtiCurrent, SwitchWndCleanup(), ThreadLockWithPti, ThreadUnlock, VALIDATECLASSANDSIZE, xxxCancelCoolSwitch(), xxxDefWindowProc(), xxxPaintSwitchWindow(), xxxSetWindowPos(), and zzzSetCursor().

Referenced by InitializeClientPfnArrays(), and LW_RegisterWindows().

01569 { 01570 TL tlpwndActivate; 01571 PTHREADINFO ptiCurrent = PtiCurrent(); 01572 01573 CheckLock(pwnd); 01574 UserAssert(IsWinEventNotifyDeferredOK()); 01575 01576 VALIDATECLASSANDSIZE(pwnd, message, wParam, lParam, FNID_SWITCH, WM_CREATE); 01577 01578 switch (message) { 01579 case WM_CREATE: 01580 /* 01581 * When the queue was created, the cursor was set to the wait cursor. 01582 * We want to use the normal one. 01583 */ 01584 zzzSetCursor(pwnd->pcls->spcur); 01585 break; 01586 01587 case WM_CLOSE: 01588 /* 01589 * Hide this window without activating anyone else. 01590 */ 01591 xxxSetWindowPos(pwnd, NULL, 0, 0, 0, 0, SWP_HIDEWINDOW | 01592 SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER); 01593 01594 /* 01595 * Get us out of Alt+Tab mode. Since the alttab information 01596 * is stored in the gptiRit->pq, we will reference that insteatd 01597 * of the current-thread. 01598 */ 01599 xxxCancelCoolSwitch(); 01600 break; 01601 01602 case WM_ERASEBKGND: 01603 case WM_FULLSCREEN: 01604 ThreadLockWithPti(ptiCurrent, pwnd, &tlpwndActivate); 01605 xxxPaintSwitchWindow(pwnd); 01606 ThreadUnlock(&tlpwndActivate); 01607 return 0; 01608 01609 case WM_DESTROY: 01610 { 01611 /* 01612 * Get the switch window info for this window 01613 */ 01614 PSWINFO pswCurrent = Getpswi(pwnd); 01615 01616 01617 if (pswCurrent) 01618 SwitchWndCleanup(&pswCurrent); 01619 } 01620 break; 01621 } 01622 01623 return xxxDefWindowProc(pwnd, message, wParam, lParam); 01624 }


Generated on Sat May 15 19:45:46 2004 for test by doxygen 1.3.7