📄 wildcard.cpp
字号:
// 撪晹娭悢
static WILDCARDW *DoSearchWildcardW ( WILDCARDW *Wildcard, const wchar_t *szSearchPath, unsigned long dwFlags, int ( CALLBACK *Callback ) ( const wchar_t *szSearchPath, WIN32_FIND_DATAW *FindData, int nDepth, LPARAM lParam ), LPARAM lParam, int nDepth, DATAW *pData ) ;
static int IsHaveAnyFileW ( const wchar_t *szFileName, int IsSearchHidden, int IsExcludeDir ) ;
// 儚僀儖僪僇乕僪傪専嶕偟僼傽僀儖柤僶僢僼傽偵僼傽僀儖柤傪弌椡偡傞乮UNICODE斉乯
// 僴儞僪儖傪暵偠傞偵偼 CloseWildcard () 傪屇傃弌偡偙偲
// 僼傽僀儖柤傪庢傝弌偡偵偼 GetFirstFile () 偍傛傃 GetNextFile () 傪屇傃弌偡偙偲
// 専嶕偟偨梫慺偺屄悢偼 GetFileCount () 傪傛傃偩偡偙偲
// 僴儞僪儖傪暵偠傞傑偱偼丄僼傽僀儖傪捛壛偟偰専嶕偡傞偙偲偑偱偒傞
// Wildcard : 儚僀儖僪僇乕僪専嶕僴儞僪儖乮 NULL 偺偲偒偼怴偨偵妱傝摉偰乯
// szSearchPath : 専嶕偡傞僼傽僀儖柤乮儚僀儖僪僇乕僪偍傛傃僷僗柤娷傓壜乯
// szSearchMode 偵専嶕儌乕僪傪巜掕偡傞乮徻嵶偼 wildcard.h 傪尒傛乯
// 僐乕儖僶僢僋娭悢偺栠傝抣偑 0 側傜攔彍丄晧抣側傜拞巭偡傞
// 儚僀儖僪僇乕僪専嶕僴儞僪儖傪曉偡
// 僼傽僀儖偑尒偮偐傜側偐偭偨偲偒偼 NULL 傪曉偡
// 僶僢僼傽偺妋曐偵幐攕偟偨偲偒丄傑偨偼 AbortWildcard 偵傛傝拞巭偝傟偨偲偒偼丄
// 僶僢僼傽傪僋儕傾偟 WILDCARD_ERROR 傪曉偡
WILDCARDW *WINAPI SearchWildcardW ( WILDCARDW *Wildcard, const wchar_t *szSearchPath, unsigned long dwFlags, int ( CALLBACK *Callback ) ( const wchar_t *szSearchPath, WIN32_FIND_DATAW *FindData, int nDepth, LPARAM lParam ), LPARAM lParam ) {
if ( ! GetFileNameW ( szSearchPath ) ) return Wildcard ;
DATAW Data = { 0 } ;
WIN32_FIND_DATAW FindData ;
Data.pFindData = & FindData ;
#ifndef _CONSOLE
if ( dwFlags & WILD_PEEKMESSAGE ) InitPeekMessage ( & Data.hDialog, & Data.IsPeekMessageUnicode ) ;
#endif
IsAborted = 0 ;
// 僼傽僀儖偐僨傿儗僋僩儕偐偺巜掕偑側偗傟偽僼傽僀儖傪巜掕
if ( ! ( dwFlags & WILD_SEARCH_FILE ) && ! ( dwFlags & WILD_SEARCH_FOLDER ) ) dwFlags |= WILD_SEARCH_FILE ;
if ( ( dwFlags & WILD_NO_EMPTY_DIR ) && ( dwFlags & WILD_ONLY_EMPTY_DIR ) ) dwFlags &= ~ ( WILD_NO_EMPTY_DIR | WILD_ONLY_EMPTY_DIR ) ;
// 僜乕僩梡娭悢傪慖戰
if ( dwFlags & WILD_XP_STYLE ) {
if ( dwFlags & WILD_SORT ) Data.CompareFunction = CompareStoredStringsNumericalW ;
if ( dwFlags & WILD_SORT_REVERSE ) Data.CompareFunction = CompareStoredStringsNumericalRevW ;
}
else {
if ( dwFlags & WILD_SORT ) Data.CompareFunction = CompareStoredStringsLocaleW ;
if ( dwFlags & WILD_SORT_REVERSE ) Data.CompareFunction = CompareStoredStringsLocaleRevW ;
}
return DoSearchWildcardW ( Wildcard, szSearchPath, dwFlags, Callback, lParam, 0, & Data ) ;
}
// SearchWildcardW() 偺壓惪偗娭悢
// 嵞婣屇傃弌偟偝傟傞
static WILDCARDW *DoSearchWildcardW ( WILDCARDW *Wildcard, const wchar_t *szSearchPath, unsigned long dwFlags, int ( CALLBACK *Callback ) ( const wchar_t *szSearchPath, WIN32_FIND_DATAW *FindData, int nDepth, LPARAM lParam ), LPARAM lParam, int nDepth, DATAW *pData ) {
if ( Wildcard == WILDCARD_ERROR ) return (WILDCARDW*) WILDCARD_ERROR ;
WIN32_FIND_DATAW *const pFindData = pData->pFindData ;
int IsNoMoreSearchSub = 0 ;
#ifndef _CONSOLE
static int nCountAll ;
#endif
wchar_t *szFileName = wcsdup_expand ( szSearchPath, MAX_LONG_PATH, MAX_PATH + 1 ) ; // 僒僽僨傿儗僋僩儕専嶕偱 \ 傪壛偊傞偨傔
if ( ! szFileName ) {
CloseWildcardW ( Wildcard ) ;
return (WILDCARDW*) WILDCARD_ERROR ;
}
// 偙偺僨傿儗僋僩儕偺僼傽僀儖傪専嶕
HANDLE hFindFile = FindFirstFileW ( szSearchPath, pFindData ) ;
if ( hFindFile != INVALID_HANDLE_VALUE ) {
int IsFirst = 1 ;
int IsErrorInLoop = 0 ;
do {
#ifndef _CONSOLE
if ( ! ( ++ nCountAll & 0xFF ) ) {
if ( dwFlags & WILD_PEEKMESSAGE ) PeekMessageProc ( pData->hDialog, pData->IsPeekMessageUnicode ) ;
}
#endif
if ( IsAborted ) { IsErrorInLoop = 1 ; break ; }
if ( ! wcscmp ( pFindData->cFileName, L"." ) || ! wcscmp ( pFindData->cFileName, L".." ) ) {
if ( ! ( dwFlags & WILD_SEARCH_CURDIR ) ) continue ;
}
else {
if ( pFindData->dwFileAttributes & ( FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM ) ) {
if ( ! ( dwFlags & WILD_SEARCH_HIDDEN ) ) continue ;
}
if ( pFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
if ( ! ( dwFlags & WILD_SEARCH_FOLDER ) ) continue ;
}
else {
if ( ! ( dwFlags & WILD_SEARCH_FILE ) ) continue ;
}
}
// 儘儞僌僼傽僀儖柤偲僔儑乕僩僼傽僀儖柤偺偳偪傜傪桪愭
wchar_t *szPriorName = ( dwFlags & WILD_SHORTNAME ) ? pFindData->cAlternateFileName : pFindData->cFileName ;
wchar_t *szAlternateName = ( dwFlags & WILD_SHORTNAME ) ? pFindData->cFileName : pFindData->cAlternateFileName ;
// 儘儞僌僼傽僀儖柤偲僔儑乕僩僼傽僀儖柤傪専嵏
if ( ! *szPriorName && *szAlternateName ) szPriorName = szAlternateName ;
// 嬻偺僨傿儗僋僩儕偐専嵏
if ( pFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
if ( dwFlags & ( WILD_NO_EMPTY_DIR | WILD_ONLY_EMPTY_DIR ) ) {
ChangeFileNameW ( szFileName, szPriorName ) ;
if ( ( dwFlags & WILD_NO_EMPTY_DIR ) && ! IsHaveAnyFileW ( szFileName, dwFlags & WILD_SEARCH_HIDDEN, 1 ) ) continue ;
if ( ( dwFlags & WILD_ONLY_EMPTY_DIR ) && IsHaveAnyFileW ( szFileName, dwFlags & WILD_SEARCH_HIDDEN, 0 ) ) continue ;
}
}
// 僐乕儖僶僢僋娭悢傪屇傃弌偡
if ( Callback ) {
int nCallbackRetvalue = Callback ( szSearchPath, pFindData, nDepth, lParam ) ;
if ( nCallbackRetvalue == 0 ) continue ;
if ( nCallbackRetvalue < 0 ) { IsNoMoreSearchSub = 1 ; break ; }
}
// 儚僀儖僪僇乕僪峔憿懱偺儊儌儕傪妋曐
if ( ! Wildcard ) {
Wildcard = (WILDCARDW*) malloc ( sizeof(WILDCARDW) ) ;
if ( ! Wildcard ) { IsErrorInLoop = 1 ; break ; }
memzero ( Wildcard, sizeof(WILDCARDW) ) ;
}
// 婎弨僨傿儗僋僩儕柤傪弌椡
if ( IsFirst ) {
IsFirst = 0 ;
if ( ! ( dwFlags & WILD_NO_PIVOT_DIR ) ) {
ChangeFileNameW ( szFileName, NULL ) ;
if ( ! ( dwFlags & WILD_WITHPATH ) ) {
if ( ! *szFileName && Wildcard->StoredNames ) Wildcard->StoredNames = StoreStringsW ( Wildcard->StoredNames, L".\\" ) ;
else Wildcard->StoredNames = StoreStringsW ( Wildcard->StoredNames, szFileName ) ;
if ( Wildcard->StoredNames == STOREDSTRINGS_ERROR ) { IsErrorInLoop = 1 ; break ; }
}
}
MarkSortStartW ( Wildcard->StoredNames ) ;
}
// 僷僗柤傕弌椡偡傞応崌
if ( dwFlags & WILD_WITHPATH ) {
ChangeFileNameW ( szFileName, szPriorName ) ;
// 堦抳偟偨僼傽僀儖柤傪弌椡
Wildcard->StoredNames = StoreStringsW ( Wildcard->StoredNames, szFileName ) ;
}
// 僷僗柤傪弌椡偟側偄応崌
else {
// 堦抳偟偨僼傽僀儖柤傪弌椡
Wildcard->StoredNames = StoreStringsW ( Wildcard->StoredNames, szPriorName ) ;
}
if ( Wildcard->StoredNames == STOREDSTRINGS_ERROR ) { IsErrorInLoop = 1 ; break ; }
} while ( FindNextFileW ( hFindFile, pFindData ) ) ;
FindClose ( hFindFile ) ;
// 僄儔乕傑偨偼拞巭
if ( IsErrorInLoop ) {
CloseWildcardW ( Wildcard ) ;
free ( szFileName ) ;
return (WILDCARDW*) WILDCARD_ERROR ;
}
// 僼傽僀儖柤傪僜乕僩
if ( Wildcard && pData->CompareFunction && SortStoredStringsW ( Wildcard->StoredNames, pData->CompareFunction ) ) {
CloseWildcardW ( Wildcard ) ;
free ( szFileName ) ;
return (WILDCARDW*) WILDCARD_ERROR ;
}
}
// 僒僽僨傿儗僋僩儕傪専嶕偟丄嵞婣屇傃弌偟傪峴側偆
if ( dwFlags & WILD_SEARCH_SUB && ! IsNoMoreSearchSub ) {
ChangeFileNameW ( szFileName, L"*" ) ;
unsigned long dwFlagsSub = WILD_SEARCH_FOLDER | WILD_NO_PIVOT_DIR | ( dwFlags & WILD_SHORTNAME ) ;
if ( dwFlags & WILD_SEARCH_HIDDENSUB ) dwFlagsSub |= WILD_SEARCH_HIDDEN ;
WILDCARDW *WildcardSub = DoSearchWildcardW ( NULL, szFileName, dwFlagsSub, NULL, NULL, 0, pData ) ;
if ( WildcardSub == WILDCARD_ERROR ) {
CloseWildcardW ( Wildcard ) ;
free ( szFileName ) ;
return (WILDCARDW*) WILDCARD_ERROR ;
}
// 僨傿儗僋僩儕偑懚嵼偟偨応崌
if ( WildcardSub ) {
for ( const wchar_t *szString = GetFirstFileW ( WildcardSub ) ; szString ; szString = GetNextFileW ( WildcardSub ) ) {
wcscpy ( szFileName, szSearchPath ) ;
ChangeFileNameW ( szFileName, szString ) ;
wcscat ( szFileName, L"\\" ) ;
wcscat ( szFileName, GetFileNameW ( szSearchPath ) ) ;
// 嵞婣屇傃弌偟
Wildcard = DoSearchWildcardW ( Wildcard, szFileName, dwFlags, Callback, lParam, nDepth + 1, pData ) ;
if ( Wildcard == WILDCARD_ERROR ) break ;
}
CloseWildcardW ( WildcardSub ) ;
}
}
free ( szFileName ) ;
return Wildcard ;
}
// 僼傽僀儖柤僶僢僼傽傪夝曻乮UNICODE斉乯
// SearchWildcard () 傪巊偭偨偲偒偼僾儘僙僗偺廔椆傑偱偵昁偢 CloseWildcard () 傪屇傃弌偡偙偲
void WINAPI CloseWildcardW ( WILDCARDW *Wildcard ) {
if ( ! Wildcard || Wildcard == WILDCARD_ERROR ) return ;
if ( Wildcard->StoredNames && Wildcard->StoredNames != STOREDSTRINGS_ERROR ) FreeStoredStringsW ( Wildcard->StoredNames ) ;
free ( Wildcard ) ;
return ;
}
// 僼傽僀儖柤僶僢僼傽偺僼傽僀儖偺屄悢傪曉偡乮UNICODE斉乯
size_t WINAPI GetFileCountW ( WILDCARDW *Wildcard ) {
if ( Wildcard == NULL || Wildcard == WILDCARD_ERROR ) return 0 ;
return GetStringCountW ( Wildcard->StoredNames ) ;
}
// 僼傽僀儖柤僶僢僼傽偐傜嵟弶偺僼傽僀儖柤傪曉偡乮UNICODE斉乯
// 僼傽僀儖偑側偗傟偽丄NULL 傪曉偡
const wchar_t *WINAPI GetFirstFileW ( WILDCARDW *Wildcard ) {
if ( Wildcard == NULL || Wildcard == WILDCARD_ERROR ) return NULL ;
return GetFirstStringW ( Wildcard->StoredNames ) ;
}
// 僼傽僀儖柤僶僢僼傽偐傜師偺僼傽僀儖柤傪曉偡乮UNICODE斉乯
// 僼傽僀儖偑側偗傟偽丄NULL 傪曉偡
// GetFirstFile () 傪屇傃弌偡慜側傜偽丄摦嶌偼晄掕
const wchar_t *WINAPI GetNextFileW ( WILDCARDW *Wildcard ) {
if ( Wildcard == NULL || Wildcard == WILDCARD_ERROR ) return NULL ;
return GetNextStringW ( Wildcard->StoredNames ) ;
}
// 僼傽僀儖傗僨傿儗僋僩儕偑偁傞側傜 0 埲奜傪丄側偗傟偽 0 傪曉偡
static int IsHaveAnyFileW ( const wchar_t *szFileName, int IsSearchHidden, int IsExcludeDir ) {
int nResult = 0 ;
wchar_t *szSearchPath = wcsdup_expand ( szFileName, (size_t) -1, 8 ) ;
if ( ! szSearchPath ) return nResult ;
wcscat ( szSearchPath, L"\\*" ) ;
WIN32_FIND_DATAW FindData ;
HANDLE hFindFile = FindFirstFileW ( szSearchPath, & FindData ) ;
if ( hFindFile != INVALID_HANDLE_VALUE ) {
do {
if ( IsExcludeDir && ( FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) ) continue ;
if ( ! IsSearchHidden && FindData.dwFileAttributes & ( FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM ) ) continue ;
if ( ! wcscmp ( FindData.cFileName, L"." ) || ! wcscmp ( FindData.cFileName, L".." ) ) continue ;
nResult = 1 ;
break ;
} while ( FindNextFileW ( hFindFile, & FindData ) ) ;
FindClose ( hFindFile ) ;
}
free ( szSearchPath ) ;
return nResult ;
}
//////////////////////////////
// PEEK MESSAGE //
//////////////////////////////
#ifndef _CONSOLE
static int InitPeekMessage ( HWND *phDialog, int *pIsPeekMessageUnicode ) {
HWND hWnd = GetActiveWindow () ;
if ( hWnd ) {
if ( IsNT () ) {
wchar_t szClassName [ MAX_PATH ] ;
GetClassNameW ( hWnd, szClassName, MAX_PATH ) ;
if ( ! wcscmp ( szClassName, L"#32770" ) ) *phDialog = hWnd ;
*pIsPeekMessageUnicode = IsWindowUnicode ( hWnd ) ;
}
else {
char szClassName [ MAX_PATH ] ;
GetClassNameA ( hWnd, szClassName, MAX_PATH ) ;
if ( ! strcmp ( szClassName, "#32770" ) ) *phDialog = hWnd ;
*pIsPeekMessageUnicode = IsWindowUnicode ( hWnd ) ;
}
}
else {
*pIsPeekMessageUnicode = IsNT () ;
}
return 0 ;
}
// 儊僢僙乕僕儖乕僾傪傑傢偡
static int PeekMessageProc ( HWND hDialog, int IsPeekMessageUnicode ) {
MSG Msg ;
if ( IsPeekMessageUnicode ) {
while ( PeekMessageW ( & Msg, NULL, 0, 0, PM_REMOVE ) ) {
if ( ! hDialog || ! IsDialogMessageW ( hDialog, & Msg ) ) {
TranslateMessage ( & Msg ) ;
DispatchMessageW ( & Msg ) ;
}
}
}
else {
while ( PeekMessageA ( & Msg, NULL, 0, 0, PM_REMOVE ) ) {
if ( ! hDialog || ! IsDialogMessageA ( hDialog, & Msg ) ) {
TranslateMessage ( & Msg ) ;
DispatchMessageA ( & Msg ) ;
}
}
}
return 0 ;
}
#endif
//////////////////////////////
// 嫟捠娭悢 //
//////////////////////////////
// 拞巭傪柦偠傞
int WINAPI AbortWildcard ( void ) {
IsAborted = 1 ;
return 0 ;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -