Q.○○というファイラー(よそ様のソフト)でワイルドカード検索をした場合にヒットしないことがあるのですが、原因がお分かりになるでしょうか?
A.・・・(心の声:そのソフトの作者に聞けや!知るかボケェ!)
// デリミタで区切られたテキストを分解して配列に格納する
//(うちの仕様にあわせた空も分割版、PathMatchSpecXだけで使うならコメント解除した方が効率良いでしょう)
// pArray : 分割後の配列
// strString : 分割対象文字列
// cTarget : デリミタ
int TokenSearch(CStringArray *pArray, CString strString, TCHAR cTarget)
{
int nMax = strString.GetLength();
if (nMax == 0)
return 0;
wchar_t *szToken = new wchar_t[nMax + 1];
szToken[0] = 0;
int nCounter = 0;
for (int i = 0; i < nMax; i++)
{
if (strString[i] == '\0')
break;
if (strString[i] == cTarget)
{
//if (szToken[0] != 0)
pArray->Add(szToken);
nCounter = 0;
}
else
szToken[nCounter++] = strString[i];
szToken[nCounter] = 0;
}
//if (szToken[0] != 0)
pArray->Add(szToken);
delete []szToken;
return (int)pArray->GetSize();
}
// ワイルドカードパターンマッチ(複数条件指定不可)
// lpszString : 検索文字列
// lpszSpec : ワイルドカードを含む文字列
BOOL _MatchSpec(LPCWSTR lpszString, LPCWSTR lpszSpec)
{
//どこかNGになるまで再帰でチェック、パス前提の文字分布で頻出順に判定
switch (*lpszSpec)
{
case '\0'://終端なので成功で再帰を抜ける
return (*lpszString == '\0');
case '*'://次の候補が一致か、文字列終端でない&比較の次が一致
return _MatchSpec(lpszString, lpszSpec + 1) || ((*lpszString != '\0') && _MatchSpec(lpszString + 1, lpszSpec));
case '?'://終端でない&それぞれの次が一致
return (*lpszString != '\0') && _MatchSpec(lpszString + 1, lpszSpec + 1);
default:
return (*lpszString == *lpszSpec) && _MatchSpec(lpszString + 1, lpszSpec + 1);
}
}
//セパレータ付きのワイルドカード文字列のパターンマッチ、PathMatchSpec()の置換え用
//Windows8でPathMatchSpecが嘘(首とかマッチしない)を返す対策
BOOL PathMatchSpecX(LPCWSTR szCheckString, LPCWSTR szWildcard)
{
//全部小文字で判定
CString strWildCard = szWildcard;
strWildCard.MakeLower();
CString strCheckString = szCheckString;
strCheckString.MakeLower();
CStringArray arr;
int nCount = ::TokenSearch(&arr, strWildCard, ';');//ワイルドカード指定文字列を;で分割、Web検索風味ならスペース分割とかでも良いかと
for (int i = 0; i < nCount; i++)
{
if (_MatchSpec(strCheckString, arr.GetAt(i)))
return TRUE;
}
return FALSE;
}