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