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

enumwin.c File Reference

#include "precomp.h"

Go to the source code of this file.

Defines

#define CHWND_BWLCREATE   32
#define BWLGROW   8

Functions

PBWL InternalBuildHwndList (PBWL pbwl, PWND pwnd, UINT flags)
PBWL InternalBuildHwndOwnerList (PBWL pbwl, PWND pwndStart, PWND pwndOwner)
BOOL xxxInternalEnumWindow (PWND pwndNext, WNDENUMPROC_PWND lpfn, LPARAM lParam, UINT flags)
PBWL BuildHwndList (PWND pwnd, UINT flags, PTHREADINFO pti)
BOOL ExpandWindowList (PBWL *ppbwl)
void FreeHwndList (PBWL pbwl)

Variables

PBWL pbwlCache


Define Documentation

#define BWLGROW   8
 

Definition at line 345 of file enumwin.c.

#define CHWND_BWLCREATE   32
 

Definition at line 89 of file enumwin.c.

Referenced by BuildHwndList().


Function Documentation

PBWL BuildHwndList (  PWND  pwnd,
UINT  flags,
PTHREADINFO  pti
) 
 

Definition at line 91 of file enumwin.c.

References BWL, BWL_ENUMIMELAST, BWL_ENUMOWNERLIST, BWL_REMOVEIMECHILD, CheckCritIn, CHWND_BWLCREATE, gpbwlList, InternalBuildHwndList(), InternalBuildHwndOwnerList(), IS_IME_ENABLED, NULL, pbwlCache, tagBWL::pbwlNext, tagBWL::phwndMax, tagBWL::phwndNext, PtiCurrent, tagBWL::ptiOwner, and tagBWL::rghwnd.

Referenced by _FindWindowEx(), ArrangeWindows(), AssociateInputContextEx(), CascadeWindowsEnum(), DestroyInputContext(), InitSwitchWndInfo(), InternalEnumWindows(), NtUserBuildHwndList(), StartTaskModalDialog(), UnmaximizeChildWindows(), xxxArrangeIconicWindows(), xxxCheckImeShowStatus(), xxxClientShutdown(), xxxDefWindowProc(), xxxDesktopRecalc(), xxxDWPPrint(), xxxInternalDoSyncPaint(), xxxInternalEnumWindow(), xxxMetricsRecalc(), xxxSendBSMtoDesktop(), and xxxShowOwnedWindows().

00095 { 00096 PBWL pbwl; 00097 00098 CheckCritIn(); 00099 00100 if ((pbwl = pbwlCache) != NULL) { 00101 00102 /* 00103 * We're using the cache now; zero it out. 00104 */ 00105 #if DBG 00106 pbwlCachePrev = pbwlCache; 00107 #endif 00108 pbwlCache = NULL; 00109 00110 #if DBG 00111 { 00112 PBWL pbwlT; 00113 /* 00114 * pbwlCache shouldn't be in the global linked list. 00115 */ 00116 for (pbwlT = gpbwlList; pbwlT != NULL; pbwlT = pbwlT->pbwlNext) { 00117 UserAssert(pbwlT != pbwl); 00118 } 00119 } 00120 #endif 00121 } else { 00122 00123 /* 00124 * sizeof(BWL) includes the first element of array. 00125 */ 00126 pbwl = (PBWL)UserAllocPool(sizeof(BWL) + sizeof(PWND) * CHWND_BWLCREATE, 00127 TAG_WINDOWLIST); 00128 if (pbwl == NULL) 00129 return NULL; 00130 00131 pbwl->phwndMax = &pbwl->rghwnd[CHWND_BWLCREATE - 1]; 00132 } 00133 pbwl->phwndNext = pbwl->rghwnd; 00134 00135 /* 00136 * We'll use ptiOwner as temporary storage for the thread we're 00137 * scanning for. It will get reset to the proper thing at the bottom 00138 * of this routine. 00139 */ 00140 pbwl->ptiOwner = pti; 00141 00142 #ifdef OWNERLIST 00143 if (flags & BWL_ENUMOWNERLIST) { 00144 pbwl = InternalBuildHwndOwnerList(pbwl, pwnd, NULL); 00145 } else { 00146 pbwl = InternalBuildHwndList(pbwl, pwnd, flags); 00147 } 00148 #else 00149 pbwl = InternalBuildHwndList(pbwl, pwnd, flags); 00150 #endif 00151 00152 /* 00153 * If phwndNext == phwndMax, it indicates that the pbwl has failed to expand. 00154 * The list is no longer valid, so we should just bail. 00155 */ 00156 if (pbwl->phwndNext >= pbwl->phwndMax) { 00157 UserAssert(pbwl->phwndNext == pbwl->phwndMax); 00158 /* 00159 * Even if we had picked pbwl from the global single cache (pbwlCache), 00160 * it should have already been unlinked from the global link list when it was put in the cache. 00161 * So we should just free it without manupilating the link pointers. 00162 * If we have allocated the pwbl for ourselves, we can simply free it. 00163 * In both cases, we should just call UserFreePool(). 00164 * As the side effect, it may make some room by providing a free pool block. 00165 */ 00166 UserFreePool(pbwl); 00167 return NULL; 00168 } 00169 00170 /* 00171 * Stick in the terminator. 00172 */ 00173 *pbwl->phwndNext = (HWND)1; 00174 00175 #ifdef FE_IME 00176 if (flags & BWL_ENUMIMELAST) { 00177 UserAssert(IS_IME_ENABLED()); 00178 /* 00179 * For IME windows. 00180 * Rebuild window list for EnumWindows API. Because ACCESS 2.0 assumes 00181 * the first window that is called CallBack Functions in the task is 00182 * Q-Card Wnd. We should change the order of IME windows 00183 */ 00184 pbwl = InternalRebuildHwndListForIMEClass(pbwl, 00185 (flags & BWL_REMOVEIMECHILD) == BWL_REMOVEIMECHILD); 00186 } 00187 #endif 00188 00189 /* 00190 * Finally link this guy into the list. 00191 */ 00192 pbwl->ptiOwner = PtiCurrent(); 00193 pbwl->pbwlNext = gpbwlList; 00194 gpbwlList = pbwl; 00195 00196 00197 /* 00198 * We should have given out the cache if it was available 00199 */ 00200 UserAssert(pbwlCache == NULL); 00201 00202 return pbwl; 00203 }

BOOL ExpandWindowList (  PBWL *  ppbwl  ) 
 

Definition at line 213 of file enumwin.c.

References BOOL, BWL_CHWNDMORE, BYTE, FALSE, NULL, tagBWL::phwndNext, PWND, and TRUE.

Referenced by InternalBuildHwndList().

00215 { 00216 PBWL pbwl; 00217 PBWL pbwlT; 00218 HWND *phwnd; 00219 00220 pbwl = *ppbwl; 00221 phwnd = pbwl->phwndNext; 00222 00223 /* 00224 * Map phwnd to an offset. 00225 */ 00226 phwnd = (HWND *)((BYTE *)phwnd - (BYTE *)pbwl); 00227 00228 /* 00229 * Increase size of BWL by 8 slots. (8 + 1) is 00230 * added since phwnd is "sizeof(HWND)" less 00231 * than actual size of handle. 00232 */ 00233 pbwlT = (PBWL)UserReAllocPool((HANDLE)pbwl, 00234 PtrToUlong(phwnd) + sizeof(PWND), 00235 PtrToUlong(phwnd) + (BWL_CHWNDMORE + 1) * sizeof(PWND), 00236 TAG_WINDOWLIST); 00237 00238 /* 00239 * Did alloc succeed? 00240 */ 00241 if (pbwlT != NULL) 00242 pbwl = pbwlT; /* Yes, use new block. */ 00243 00244 /* 00245 * Map phwnd back into a pointer. 00246 */ 00247 phwnd = (HWND *)((ULONG_PTR)pbwl + (ULONG_PTR)phwnd); 00248 00249 /* 00250 * Did ReAlloc() fail? 00251 */ 00252 if (pbwlT == NULL) { 00253 RIPMSG0(RIP_WARNING, "ExpandWindowList: out of memory."); 00254 return FALSE; 00255 } 00256 00257 /* 00258 * Reset phwndMax. 00259 */ 00260 pbwl->phwndNext = phwnd; 00261 pbwl->phwndMax = phwnd + BWL_CHWNDMORE; 00262 00263 *ppbwl = pbwl; 00264 00265 return TRUE; 00266 }

void FreeHwndList (  PBWL  pbwl  ) 
 

Definition at line 417 of file enumwin.c.

References CheckCritIn, FALSE, gpbwlList, NULL, pbwlCache, tagBWL::pbwlNext, tagBWL::phwndMax, and tagBWL::rghwnd.

Referenced by _FindWindowEx(), AssociateInputContextEx(), DestroyInputContext(), InitSwitchWndInfo(), NtUserBuildHwndList(), SwitchWndCleanup(), xxxArrangeIconicWindows(), xxxCheckImeShowStatus(), xxxClientShutdown(), xxxDefWindowProc(), xxxDesktopRecalc(), xxxDestroyThreadInfo(), xxxDWPPrint(), xxxInternalDoSyncPaint(), xxxInternalEnumWindow(), xxxMetricsRecalc(), xxxSendBSMtoDesktop(), and xxxShowOwnedWindows().

00419 { 00420 PBWL *ppbwl; 00421 PBWL pbwlT; 00422 00423 CheckCritIn(); 00424 00425 /* 00426 * We should never have an active bwl that is the free cached bwl 00427 */ 00428 UserAssert(pbwl != pbwlCache); 00429 00430 /* 00431 * Unlink this bwl from the list. 00432 */ 00433 for (ppbwl = &gpbwlList; *ppbwl != NULL; ppbwl = &(*ppbwl)->pbwlNext) { 00434 if (*ppbwl == pbwl) { 00435 *ppbwl = pbwl->pbwlNext; 00436 00437 /* 00438 * If the cache is empty or this pbwl is larger than the 00439 * cached one, save the pbwl there. 00440 */ 00441 if (pbwlCache == NULL) { 00442 pbwlCache = pbwl; 00443 } else if ((pbwl->phwndMax - pbwl->rghwnd) > 00444 (pbwlCache->phwndMax - pbwlCache->rghwnd)) { 00445 pbwlT = pbwlCache; 00446 pbwlCache = pbwl; 00447 UserFreePool((HANDLE)pbwlT); 00448 } else { 00449 UserFreePool((HANDLE)pbwl); 00450 } 00451 return; 00452 } 00453 } 00454 00455 /* 00456 * Assert if we couldn't find the pbwl in the list... 00457 */ 00458 UserAssert(FALSE); 00459 }

PBWL InternalBuildHwndList (  PBWL  pbwl,
PWND  pwnd,
UINT  flags
) 
 

Definition at line 347 of file enumwin.c.

References BWL_ENUMCHILDREN, BWL_ENUMLIST, ExpandWindowList(), GETPTI, HWq, n, NULL, tagBWL::phwndMax, tagBWL::phwndNext, tagBWL::ptiOwner, tagWND::spwndChild, and tagWND::spwndNext.

Referenced by BuildHwndList().

00351 { 00352 /* 00353 * NOTE: pbwl->phwndNext is used as a place to keep 00354 * the phwnd across calls to InternalBuildHwndList(). 00355 * This is OK since we don't link pbwl into the list 00356 * of pbwl's until after we've finished enumerating windows. 00357 */ 00358 00359 while (pwnd != NULL) { 00360 /* 00361 * Make sure it matches the thread id, if there is one. 00362 */ 00363 if (pbwl->ptiOwner == NULL || pbwl->ptiOwner == GETPTI(pwnd)) { 00364 UserAssert(pbwl->phwndNext < pbwl->phwndMax); 00365 *pbwl->phwndNext = HWq(pwnd); 00366 pbwl->phwndNext++; 00367 if (pbwl->phwndNext == pbwl->phwndMax) { 00368 #if EMULATE_EXPAND_FAILURE 00369 static int n = 0; 00370 if (++n % 32 == 0) { 00371 RIPMSG0(RIP_WARNING, "InternalBuildHwndList: emulating ExpandWindowList failure."); 00372 break; 00373 } 00374 #endif 00375 if (!ExpandWindowList(&pbwl)) 00376 break; 00377 } 00378 } 00379 00380 /* 00381 * Should we step through the Child windows? 00382 */ 00383 if ((flags & BWL_ENUMCHILDREN) && pwnd->spwndChild != NULL) { 00384 pbwl = InternalBuildHwndList(pbwl, pwnd->spwndChild, BWL_ENUMLIST | BWL_ENUMCHILDREN); 00385 /* 00386 * If ExpandWindowList() failed in the recursive call, 00387 * we should just bail. 00388 */ 00389 if (pbwl->phwndNext >= pbwl->phwndMax) { 00390 UserAssert(pbwl->phwndNext == pbwl->phwndMax); 00391 RIPMSG1(RIP_WARNING, "InternalBuildHwndList: failed to expand BWL in enumerating children. pbwl=%#p", pbwl); 00392 break; 00393 } 00394 UserAssert(pbwl->phwndNext < pbwl->phwndMax); 00395 } 00396 00397 /* 00398 * Are we enumerating only one window? 00399 */ 00400 if (!(flags & BWL_ENUMLIST)) 00401 break; 00402 00403 pwnd = pwnd->spwndNext; 00404 } 00405 00406 return pbwl; 00407 }

PBWL InternalBuildHwndOwnerList (  PBWL  pbwl,
PWND  pwndStart,
PWND  pwndOwner
) 
 

Referenced by BuildHwndList().

BOOL xxxInternalEnumWindow (  PWND  pwndNext,
WNDENUMPROC_PWND  lpfn,
LPARAM  lParam,
UINT  flags
) 
 

Definition at line 40 of file enumwin.c.

References BOOL, BuildHwndList(), CheckLock, FALSE, FreeHwndList(), NULL, RevalidateHwnd, tagBWL::rghwnd, ThreadLockAlways, ThreadUnlock, TRUE, and WNDENUMPROC_PWND.

Referenced by CancelInputState(), xxxActivateThisWindow(), xxxDeactivate(), xxxHelpLoop(), and xxxSetClassIcon().

00045 { 00046 HWND *phwnd; 00047 PWND pwnd; 00048 PBWL pbwl; 00049 BOOL fSuccess; 00050 TL tlpwnd; 00051 00052 CheckLock(pwndNext); 00053 00054 if ((pbwl = BuildHwndList(pwndNext, flags, NULL)) == NULL) 00055 return FALSE; 00056 00057 fSuccess = TRUE; 00058 for (phwnd = pbwl->rghwnd; *phwnd != (HWND)1; phwnd++) { 00059 00060 /* 00061 * Lock the window before we pass it off to the app. 00062 */ 00063 if ((pwnd = RevalidateHwnd(*phwnd)) != NULL) { 00064 00065 /* 00066 * Call the application. 00067 */ 00068 ThreadLockAlways(pwnd, &tlpwnd); 00069 fSuccess = (*lpfn)(pwnd, lParam); 00070 ThreadUnlock(&tlpwnd); 00071 if (!fSuccess) 00072 break; 00073 } 00074 } 00075 00076 FreeHwndList(pbwl); 00077 00078 return fSuccess; 00079 }


Variable Documentation

PBWL pbwlCache
 

Definition at line 17 of file enumwin.c.

Referenced by BuildHwndList(), FreeHwndList(), and Win32kNtUserCleanup().


Generated on Sat May 15 19:43:32 2004 for test by doxygen 1.3.7