#pragma twice

KAB-studio > プログラミング > #pragma twice > 298 Version 14.31 スレッドからダイアログに表示する

#pragma twice 298 Version 14.31 スレッドからダイアログに表示する

前のページへ 表紙・目次へ 次のページへ

 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 スレッドからダイアログに表示する、の続き >
につづく!
ま、次回は説明をバリバリってことね
そゆこと
 
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
RSSに登録
del.icio.us 登録する
Yahoo!ブックマーク 詳細を表示 users
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
 
このページは、Visual C++ 6.0を用いた C++ 言語プログラミングの解説を行う#pragma twiceの一コンテンツです。
詳しい説明は#pragma twiceのトップページをご覧ください。