📄 wildcard.cpp
字号:
// wildcard.cpp
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include "msc.h"
#include "filename.h"
#include "storestr.h"
#include "wildcard.h"
static volatile int IsAborted ;
#ifndef _CONSOLE
static int InitPeekMessage ( HWND *phDialog, int *pIsPeekMessageUnicode ) ;
static int PeekMessageProc ( HWND hDialog, int IsPeekMessageUnicode ) ;
#endif
//////////////////////////////
// ANSI斉 //
//////////////////////////////
typedef struct {
WIN32_FIND_DATAA *pFindData ;
int ( __cdecl *CompareFunction ) ( const char **, const char ** ) ;
#ifndef _CONSOLE
HWND hDialog ;
int IsPeekMessageUnicode ;
#endif
} DATAA ;
// 撪晹娭悢
static WILDCARDA *DoSearchWildcardA ( WILDCARDA *Wildcard, const char *szSearchPath, unsigned long dwFlags, int ( CALLBACK *Callback ) ( const char *szSearchPath, WIN32_FIND_DATAA *FindData, int nDepth, LPARAM lParam ), LPARAM lParam, int nDepth, DATAA *pData ) ;
static int IsHaveAnyFileA ( const char *szFileName, int IsSearchHidden, int IsExcludeDir ) ;
static int IsValidAnsiLongFileName ( const char *szLongPathName, const char *szShortFileName ) ;
// 儚僀儖僪僇乕僪傪専嶕偟僼傽僀儖柤僶僢僼傽偵僼傽僀儖柤傪弌椡偡傞乮ANSI斉乯
// 僴儞僪儖傪暵偠傞偵偼 CloseWildcard () 傪屇傃弌偡偙偲
// 僼傽僀儖柤傪庢傝弌偡偵偼 GetFirstFile () 偍傛傃 GetNextFile () 傪屇傃弌偡偙偲
// 専嶕偟偨梫慺偺屄悢偼 GetFileCount () 傪傛傃偩偡偙偲
// 僴儞僪儖傪暵偠傞傑偱偼丄僼傽僀儖傪捛壛偟偰専嶕偡傞偙偲偑偱偒傞
// Wildcard : 儚僀儖僪僇乕僪専嶕僴儞僪儖乮 NULL 偺偲偒偼怴偨偵妱傝摉偰乯
// szSearchPath : 専嶕偡傞僼傽僀儖柤乮儚僀儖僪僇乕僪偍傛傃僷僗柤娷傓壜乯
// szSearchMode 偵専嶕儌乕僪傪巜掕偡傞乮徻嵶偼 wildcard.h 傪尒傛乯
// 僐乕儖僶僢僋娭悢偺栠傝抣偑 0 側傜攔彍丄晧抣側傜拞巭偡傞
// 儚僀儖僪僇乕僪専嶕僴儞僪儖傪曉偡
// 僼傽僀儖偑尒偮偐傜側偐偭偨偲偒偼 NULL 傪曉偡
// 僶僢僼傽偺妋曐偵幐攕偟偨偲偒丄傑偨偼 AbortWildcard 偵傛傝拞巭偝傟偨偲偒偼丄
// 僶僢僼傽傪僋儕傾偟 WILDCARD_ERROR 傪曉偡
WILDCARDA *WINAPI SearchWildcardA ( WILDCARDA *Wildcard, const char *szSearchPath, unsigned long dwFlags, int ( CALLBACK *Callback ) ( const char *szSearchPath, WIN32_FIND_DATAA *FindData, int nDepth, LPARAM lParam ), LPARAM lParam ) {
if ( ! GetFileNameA ( szSearchPath ) ) return Wildcard ;
DATAA Data = { 0 } ;
WIN32_FIND_DATAA 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 = CompareStoredStringsNumericalA ;
if ( dwFlags & WILD_SORT_REVERSE ) Data.CompareFunction = CompareStoredStringsNumericalRevA ;
}
else {
if ( dwFlags & WILD_SORT ) Data.CompareFunction = CompareStoredStringsLocaleA ;
if ( dwFlags & WILD_SORT_REVERSE ) Data.CompareFunction = CompareStoredStringsLocaleRevA ;
}
return DoSearchWildcardA ( Wildcard, szSearchPath, dwFlags, Callback, lParam, 0, & Data ) ;
}
// SearchWildcardA() 偺壓惪偗娭悢
// 嵞婣屇傃弌偟偝傟傞
static WILDCARDA *DoSearchWildcardA ( WILDCARDA *Wildcard, const char *szSearchPath, unsigned long dwFlags, int ( CALLBACK *Callback ) ( const char *szSearchPath, WIN32_FIND_DATAA *FindData, int nDepth, LPARAM lParam ), LPARAM lParam, int nDepth, DATAA *pData ) {
if ( Wildcard == WILDCARD_ERROR ) return (WILDCARDA*) WILDCARD_ERROR ;
WIN32_FIND_DATAA *const pFindData = pData->pFindData ;
int IsNoMoreSearchSub = 0 ;
#ifndef _CONSOLE
static int nCountAll ;
#endif
char *szFileName = strdup_expand ( szSearchPath, MAX_PATH, MAX_PATH + 1 ) ; // 僒僽僨傿儗僋僩儕専嶕偱 \ 傪壛偊傞偨傔
if ( ! szFileName ) {
CloseWildcardA ( Wildcard ) ;
return (WILDCARDA*) WILDCARD_ERROR ;
}
// 偙偺僨傿儗僋僩儕偺僼傽僀儖傪専嶕
HANDLE hFindFile = FindFirstFileA ( 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 ( ! strcmp ( pFindData->cFileName, "." ) || ! strcmp ( pFindData->cFileName, ".." ) ) {
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 ;
}
}
// 儘儞僌僼傽僀儖柤偲僔儑乕僩僼傽僀儖柤偺偳偪傜傪桪愭
char *szPriorName = ( dwFlags & WILD_SHORTNAME ) ? pFindData->cAlternateFileName : pFindData->cFileName ;
char *szAlternateName = ( dwFlags & WILD_SHORTNAME ) ? pFindData->cFileName : pFindData->cAlternateFileName ;
// 儘儞僌僼傽僀儖柤偲僔儑乕僩僼傽僀儖柤傪専嵏
if ( ! *szPriorName && *szAlternateName ) szPriorName = szAlternateName ;
// 昗弨埲奜偺暥帤僐乕僪偑巊傢傟偰偄側偄偐専嵏
if ( ! ( dwFlags & WILD_SHORTNAME ) && *szAlternateName ) {
if ( strchr ( szPriorName, '?' ) ) szPriorName = szAlternateName ;
else if ( ! IsNT () && strchr ( szPriorName, '_' ) ) {
ChangeFileNameA ( szFileName, szPriorName ) ;
if ( ! IsValidAnsiLongFileName ( szFileName, szAlternateName ) ) szPriorName = szAlternateName ;
}
}
// 嬻偺僨傿儗僋僩儕偐専嵏
if ( pFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) {
if ( dwFlags & ( WILD_NO_EMPTY_DIR | WILD_ONLY_EMPTY_DIR ) ) {
ChangeFileNameA ( szFileName, szPriorName ) ;
if ( ( dwFlags & WILD_NO_EMPTY_DIR ) && ! IsHaveAnyFileA ( szFileName, dwFlags & WILD_SEARCH_HIDDEN, 1 ) ) continue ;
if ( ( dwFlags & WILD_ONLY_EMPTY_DIR ) && IsHaveAnyFileA ( 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 = (WILDCARDA*) malloc ( sizeof(WILDCARDA) ) ;
if ( ! Wildcard ) { IsErrorInLoop = 1 ; break ; }
memzero ( Wildcard, sizeof(WILDCARDA) ) ;
}
// 婎弨僨傿儗僋僩儕柤傪弌椡
if ( IsFirst ) {
IsFirst = 0 ;
if ( ! ( dwFlags & WILD_NO_PIVOT_DIR ) ) {
ChangeFileNameA ( szFileName, NULL ) ;
if ( ! ( dwFlags & WILD_WITHPATH ) ) {
if ( ! *szFileName && Wildcard->StoredNames ) Wildcard->StoredNames = StoreStringsA ( Wildcard->StoredNames, ".\\" ) ;
else Wildcard->StoredNames = StoreStringsA ( Wildcard->StoredNames, szFileName ) ;
if ( Wildcard->StoredNames == STOREDSTRINGS_ERROR ) { IsErrorInLoop = 1 ; break ; }
}
}
MarkSortStartA ( Wildcard->StoredNames ) ;
}
// 僷僗柤傕弌椡偡傞応崌
if ( dwFlags & WILD_WITHPATH ) {
ChangeFileNameA ( szFileName, szPriorName ) ;
// 堦抳偟偨僼傽僀儖柤傪弌椡
Wildcard->StoredNames = StoreStringsA ( Wildcard->StoredNames, szFileName ) ;
}
// 僷僗柤傪弌椡偟側偄応崌
else {
// 堦抳偟偨僼傽僀儖柤傪弌椡
Wildcard->StoredNames = StoreStringsA ( Wildcard->StoredNames, szPriorName ) ;
}
if ( Wildcard->StoredNames == STOREDSTRINGS_ERROR ) { IsErrorInLoop = 1 ; break ; }
} while ( FindNextFileA ( hFindFile, pFindData ) ) ;
FindClose ( hFindFile ) ;
// 僄儔乕傑偨偼拞巭
if ( IsErrorInLoop ) {
CloseWildcardA ( Wildcard ) ;
free ( szFileName ) ;
return (WILDCARDA*) WILDCARD_ERROR ;
}
// 僼傽僀儖柤傪僜乕僩
if ( Wildcard && pData->CompareFunction && SortStoredStringsA ( Wildcard->StoredNames, pData->CompareFunction ) ) {
CloseWildcardA ( Wildcard ) ;
free ( szFileName ) ;
return (WILDCARDA*) WILDCARD_ERROR ;
}
}
// 僒僽僨傿儗僋僩儕傪専嶕偟丄嵞婣屇傃弌偟傪峴側偆
if ( dwFlags & WILD_SEARCH_SUB && ! IsNoMoreSearchSub ) {
ChangeFileNameA ( szFileName, "*" ) ;
unsigned long dwFlagsSub = WILD_SEARCH_FOLDER | WILD_NO_PIVOT_DIR | ( dwFlags & WILD_SHORTNAME ) ;
if ( dwFlags & WILD_SEARCH_HIDDENSUB ) dwFlagsSub |= WILD_SEARCH_HIDDEN ;
WILDCARDA *WildcardSub = DoSearchWildcardA ( NULL, szFileName, dwFlagsSub, NULL, NULL, 0, pData ) ;
if ( WildcardSub == WILDCARD_ERROR ) {
CloseWildcardA ( Wildcard ) ;
free ( szFileName ) ;
return (WILDCARDA*) WILDCARD_ERROR ;
}
// 僨傿儗僋僩儕偑懚嵼偟偨応崌
if ( WildcardSub ) {
for ( const char *szString = GetFirstFileA ( WildcardSub ) ; szString ; szString = GetNextFileA ( WildcardSub ) ) {
strcpy ( szFileName, szSearchPath ) ;
ChangeFileNameA ( szFileName, szString ) ;
strcat ( szFileName, "\\" ) ;
strcat ( szFileName, GetFileNameA ( szSearchPath ) ) ;
// 嵞婣屇傃弌偟
Wildcard = DoSearchWildcardA ( Wildcard, szFileName, dwFlags, Callback, lParam, nDepth + 1, pData ) ;
if ( Wildcard == WILDCARD_ERROR ) break ;
}
CloseWildcardA ( WildcardSub ) ;
}
}
free ( szFileName ) ;
return Wildcard ;
}
// 僼傽僀儖柤僶僢僼傽傪夝曻乮ANSI斉乯
// SearchWildcard () 傪巊偭偨偲偒偼僾儘僙僗偺廔椆傑偱偵昁偢 CloseWildcard () 傪屇傃弌偡偙偲
void WINAPI CloseWildcardA ( WILDCARDA *Wildcard ) {
if ( ! Wildcard || Wildcard == WILDCARD_ERROR ) return ;
if ( Wildcard->StoredNames && Wildcard->StoredNames != STOREDSTRINGS_ERROR ) FreeStoredStringsA ( Wildcard->StoredNames ) ;
free ( Wildcard ) ;
return ;
}
// 僼傽僀儖柤僶僢僼傽偺僼傽僀儖偺屄悢傪曉偡乮ANSI斉乯
size_t WINAPI GetFileCountA ( WILDCARDA *Wildcard ) {
if ( Wildcard == NULL || Wildcard == WILDCARD_ERROR ) return 0 ;
return GetStringCountA ( Wildcard->StoredNames ) ;
}
// 僼傽僀儖柤僶僢僼傽偐傜嵟弶偺僼傽僀儖柤傪曉偡乮ANSI斉乯
// 僼傽僀儖偑側偗傟偽丄NULL 傪曉偡
const char *WINAPI GetFirstFileA ( WILDCARDA *Wildcard ) {
if ( Wildcard == NULL || Wildcard == WILDCARD_ERROR ) return NULL ;
return GetFirstStringA ( Wildcard->StoredNames ) ;
}
// 僼傽僀儖柤僶僢僼傽偐傜師偺僼傽僀儖柤傪曉偡乮ANSI斉乯
// 僼傽僀儖偑側偗傟偽丄NULL 傪曉偡
// GetFirstFile () 傪屇傃弌偡慜側傜偽丄摦嶌偼晄掕
const char *WINAPI GetNextFileA ( WILDCARDA *Wildcard ) {
if ( Wildcard == NULL || Wildcard == WILDCARD_ERROR ) return NULL ;
return GetNextStringA ( Wildcard->StoredNames ) ;
}
// 僼傽僀儖傗僨傿儗僋僩儕偑偁傞側傜 0 埲奜傪丄側偗傟偽 0 傪曉偡
static int IsHaveAnyFileA ( const char *szFileName, int IsSearchHidden, int IsExcludeDir ) {
int nResult = 0 ;
char *szSearchPath = strdup_expand ( szFileName, (size_t) -1, 8 ) ;
if ( ! szSearchPath ) return nResult ;
strcat ( szSearchPath, "\\*" ) ;
WIN32_FIND_DATAA FindData ;
HANDLE hFindFile = FindFirstFileA ( 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 ( ! strcmp ( FindData.cFileName, "." ) || ! strcmp ( FindData.cFileName, ".." ) ) continue ;
nResult = 1 ;
break ;
} while ( FindNextFileA ( hFindFile, & FindData ) ) ;
FindClose ( hFindFile ) ;
}
free ( szSearchPath ) ;
return nResult ;
}
// 儘儞僌僼傽僀儖柤偑桳岠偐偳偆偐専嵏
// szLongPathName 偼僷僗柤晅偒偱丄szShortFileName 偼僼傽僀儖柤偺傒偱巜掕
static int IsValidAnsiLongFileName ( const char *szLongPathName, const char *szShortFileName ) {
WIN32_FIND_DATAA FindData ;
int nRetValue = 0 ;
HANDLE hFindFile = FindFirstFileA ( szLongPathName, & FindData ) ;
if ( hFindFile != INVALID_HANDLE_VALUE ) {
if ( ! strcmp ( FindData.cAlternateFileName, szShortFileName ) ) nRetValue = 1 ;
if ( FindNextFileA ( hFindFile, & FindData ) ) nRetValue = 0 ;
FindClose ( hFindFile ) ;
}
return nRetValue ;
}
//////////////////////////////
// UNICODE斉 //
//////////////////////////////
typedef struct {
WIN32_FIND_DATAW *pFindData ;
int ( __cdecl *CompareFunction ) ( const wchar_t **, const wchar_t ** ) ;
#ifndef _CONSOLE
HWND hDialog ;
int IsPeekMessageUnicode ;
#endif
} DATAW ;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -