Version 14.31
スレッドからダイアログに表示する
「さて、今回は残りの3つ」
・検索対象フォルダの表示
・検索結果の表示
・検索終了時にキャンセルダイアログを閉じる機能
「この3つを一気に解決します」
『え”、そんな簡単にできるの?』
「知識的にはこれまでのものを応用するだけだからね。ただ、細かいところ
は気を付けなきゃいけないけど……さて、まずはソースコードからいつも見
てる SearchDlgDlg.cpp の方はこんな感じ」
// SearchDlgDlg.cpp
// 略 ...
// CountMatchFile() と StartCountMatchFile() は削除。
void CSearchDlgDlg::OnSearchStart()
{
// 【検索中】ダイアログを表示します。
CSearchingDlg cDlg;
cDlg.DoModal();
// 結果を出力します。
m_cMatchNumStr.Format( "%d", GetMatchNum() );
UpdateData( FALSE );
}
『……へ? 削除?』
「そう。検索機能本体は、 SearchDlgDlg.cpp の方に移します」
『え、なんで?』
「これから追加する機能のうち」
・検索対象フォルダの表示
・検索終了時にキャンセルダイアログを閉じる機能
「は【検索中】ダイアログ、つまり SearchDlgDlg.cpp の方だから」
『同じファイルの方がやりやすいってこと?』
「そういうこと。それしないと、この前みたいに関数作って呼び出すってし
なきゃいけないから」
『う、めんどい……』
「で、その SearchDlgDlg.cpp 」
// ダイアログのウィンドウハンドル。
HWND g_hSearchingDlgWnd = NULL;
// エディットボックスのウィンドウハンドル。
HWND g_hEditFolderWnd = NULL;
// ストッパー。
bool g_bIsStop = false;
// このストッパーをオンにする関数。
void SetStopOn()
{
g_bIsStop = true;
}
// 一致数。
int g_iMatchNum = 0;
// 一致数を取得します。
int GetMatchNum()
{
return g_iMatchNum;
}
/*
指定したフォルダからファイルを検索します。
戻り値として一致数を返します。
*/
int CountMatchFile
( const char * const p_pchFolderPath
, const char * const p_pchFileName
)
{
int iNum = 0;
// ストップポイント1。
if( g_bIsStop == true )
{
return 0;
}
// 検索するフォルダをカレントディレクトリにします。
BOOL bRes;
bRes = SetCurrentDirectory( p_pchFolderPath );
if( bRes == FALSE )
{
// フォルダが存在しません。
return -1;
}
// フォルダが存在するのでウィンドウタイトルをセットします。
if( ::IsWindow( g_hEditFolderWnd ) )
{
// ウィンドウが存在するので表示します。
::SetWindowText( g_hEditFolderWnd, p_pchFolderPath );
}
CStringArray cFolderStrAry;
// 最初のファイルを取得します。
WIN32_FIND_DATA stWin32FindData;
HANDLE hHandle = NULL;
hHandle = FindFirstFile( "*", &stWin32FindData );
do
{
// ストップポイント2。
if( g_bIsStop == true )
{
return iNum;
}
if( stWin32FindData.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY )
{
// フォルダなので取っておきます。
cFolderStrAry.Add( stWin32FindData.cFileName );
}
else if( _stricmp
( stWin32FindData.cFileName
, p_pchFileName
) == 0 )
{
// ファイル名が一致しました。
++iNum;
TRACE( "%s\n", p_pchFolderPath );
}
// 次のファイルを取得します。
}while( FindNextFile( hHandle, &stWin32FindData ) );
// ハンドルを閉じます。
FindClose( hHandle );
// フォルダに対して再帰呼び出しをします。
for( int iF1 = 0; iF1 < cFolderStrAry.GetSize(); ++iF1 )
{
if (
( cFolderStrAry.GetAt( iF1 ) == "." ) ||
( cFolderStrAry.GetAt( iF1 ) == ".." )
)
{
// . と .. はスキップします。
continue;
}
// フォルダを連結します。
CString cPathStr = p_pchFolderPath;
if (
( cPathStr.GetAt
( cPathStr.GetLength() - 1 ) != '\\' ) ||
(
( cPathStr.GetAt
( cPathStr.GetLength() - 1 ) == '\\' ) &&
( _mbsbtype
( (const unsigned char *)(LPCTSTR)cPathStr
, cPathStr.GetLength() - 1
) == 2 )
)
)
{
// 最後に \ がなければくっつけます。
cPathStr += "\\";
}
cPathStr += cFolderStrAry.GetAt( iF1 );
// 再帰呼び出しします。
iNum += CountMatchFile( cPathStr, p_pchFileName );
}
return iNum;
}
void StartCountMatchFile( void *p_p )
{
// 検索を開始します。
g_bIsStop = false;
int iCount = 0;
iCount = CountMatchFile( "D:\\", "readme.txt" );
// 結果をセットします。
g_iMatchNum = iCount;
// ダイアログを閉じます。
if( ::IsWindow( g_hSearchingDlgWnd ) )
{
// ウィンドウが存在するので閉じます。
::SendMessage
( g_hSearchingDlgWnd
, WM_COMMAND
, MAKEWPARAM( IDCANCEL, 0 )
, 0
);
}
}
void CSearchingDlg::OnCancel()
{
// 検索をストップさせます。
SetStopOn();
CDialog::OnCancel();
}
BOOL CSearchingDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// ダイアログのウィンドウハンドルをセットします。
g_hSearchingDlgWnd = GetSafeHwnd();
// エディットボックスのウィンドウハンドルをセットします。
g_hEditFolderWnd = ::GetDlgItem( GetSafeHwnd(), IDC_E_FOLDER );
// 検索開始します。
HANDLE hThread;
hThread
= (HANDLE)_beginthread( StartCountMatchFile, 0, NULL );
return TRUE;
}
『長!』
「さらに、 SearchDlgDlg.h に関数宣言をひとつ追加」
// SearchDlgDlg.h
// 略...
class CSearchingDlg : public CDialog
{
// 略...
};
// この下の行を追加。
int GetMatchNum();
『あー、この前やった他のファイルから呼び出すってヤツね』
「というわけで次回に続く!」
『ええっ!?』
/*
Preview Next Story!
*/
『コードの紹介だけー?』
「それだけなのに、行数かなりオーバーしてるし」
『なんか計画性ないわねー』
「ごめん……」
『というわけで次回』
< Version 14.32 スレッドからダイアログに表示する、の続き >
「につづく!」
『ま、次回は説明をバリバリってことね』
「そゆこと」