C++
VisualStudio
MFC

マルチスレッド作成(MFC)

More than 1 year has passed since last update.

MFCでのマルチスレッド作成にて、やったことをまとめておきます。

マルチスレッド作成

ワーカースレッドが終了したら対応関数を呼び出す処理を実装します。

用意するもの

  • スレッド関数(制御関数) static UINT ThreadProc(LPVOID pParam);
  • スレッド処理本体関数 void ThreadProc();
  • スレッド終了後処理関数 afx_msg LRESULT OnCompleteLoadXML(WPARAM wParam, LPARAM lParam );
  • スレッド用変数:CWinThread型

作成手順

  1. スレッド開始処理実装
  2. スレッド終了処理実装

まずヘッダーはこの通り。

MyDlg.h
class CmyDialog : public CDialog
{
//~もろもろ省略

/*変数*/
private:
    CWinThread* pThread;

/*関数*/
private:
    void collationReserve();
    void displayResultScreen();

public:
    static UINT ThreadProc(LPVOID pParam);
    void ThreadProc();
    afx_msg LRESULT OnCompleteLoadXML(WPARAM wParam, LPARAM lParam );
};

1.スレッド開始処理実装

MFCのマルチスレッドはAfxBeginThread関数で開始できます。
それぞれの関数について。

  • スレッド関数(制御関数)
MyDlg.cpp
UINT CmyDialog::ThreadProc(LPVOID pParam){
    CmyDialog* pFileView = dynamic_cast<CmyDialog*>(reinterpret_cast<CWnd*>(pParam));
    if (pFileView)
    {
        pFileView->ThreadProc();
    }
    return 0;
}

スレッド関数ではメンバ関数が呼び出せないため、処理本体関数を別に作成します。

  • スレッド処理本体
MyDlg.cpp
void CmyDialog::ThreadProc()
{
    collationReserve();
    //AfxGetMainWnd()->SendMessage(WM_USER_COMPLETE_LOAD_XML, (WPARAM)&firstIndex, (LPARAM)firstFilePath.GetString() );
    this->PostMessageA(WM_USER_COMPLETE_LOAD_XML);
}

処理の最後にSendMessage関数かPostMessage関数でメッセージを送ります。これでワーカースレッドの処理が完了したことを元スレッドに知らせます。

  • スレッド開始関数:AfxBeginThread
MyDlg.cpp
pThread = AfxBeginThread(ThreadProc, (LPVOID)this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED , NULL);
ASSERT(pThread);
if (pThread)
{
    pThread->m_pMainWnd = this;
    pThread->m_bAutoDelete = TRUE;
    // スレッド処理の開始
    pThread->ResumeThread();
}

そのまま呼び出してもスレッドは開始しますが設定を行うために処理を追加しています。

2.スレッド終了処理実装

スレッド終了時の処理を実装します。

  • メッセージマップ登録
MyDlg.cpp
BEGIN_MESSAGE_MAP(CmyDialog, CDialog)
    ON_BN_CLICKED(IDC_BUTTON1, &CmyDialog::OnBnClickedButton1)
    ON_WM_SHOWWINDOW()
    ON_WM_PAINT()
    ON_MESSAGE(WM_USER_COMPLETE_LOAD_XML, CmyDialog::OnCompleteLoadXML)// UserMessage
END_MESSAGE_MAP()

(cppファイル内にある)メッセージマップ内に追記します。

  • スレッド終了後処理関数
MyDlg.cpp
afx_msg LRESULT CmyDialog::OnCompleteLoadXML(WPARAM wParam, LPARAM lParam )
{
    displayResultScreen();
    //delete pThread;

    return 0;
}

スレッド終了後に行う処理を関数内に記載します。

参考

http://simplestar.syuriken.jp/tips/MFC_0010_HowToUseThread.html
http://oissu2.blog77.fc2.com/blog-entry-18.html