MFCマルチスレッド符号化--ユーザインタフェーススレッド(四)
次に、ユーザインタフェースのマルチスレッドプログラミングの一例を説明する.
ダイアログ・ボックス・ベースのエンジニアリングMultiThreadTestを作成し、ダイアログ・ボックスIDD_MultiThreadTest_DIALOGにボタンIDCを追加UI_THREAD、タイトルは「ユーザインタフェーススレッド」.プロジェクトを右クリックし、「New Class...」を選択してプロジェクトにベースクラスをCWinThread派生スレッドクラスCUIThreadに追加します.プロジェクトに新しいダイアログIDDを追加UITHREADDLG、タイトルは「スレッドダイアログ」.ダイアログIDD_UITHREADDLGは、CDialogベースのクラスCUIThreadDlgを作成します.ClassWizardを使用してCUIThreadDlgクラスにWM_を追加LUTTONDOWNメッセージの処理関数OnLBEttonDownは以下の通りです.
CUIThread.hに追加
#include "CUIThreadDlg.h"
CUIThreadクラスにprotected変数CUIThreadlg m_を追加dlg:
CUIThreadクラスのヘッダファイルは次のとおりです.
InitInstance()関数とExitInstance()関数をそれぞれ再ロードします.
メモリの漏洩を避けるため、CUIThreadDlgにWM_を追加DESTROYメッセージ処理関数:
注意:UIthread.hにおけるクラスCUIThread()のコンストラクション関数の特性をprotectedからpublicに変更する.
ユーザインタフェーススレッドの実行順序はアプリケーションのメインスレッドと同じであり、まずユーザインタフェーススレッドクラスのInitInstance()関数を呼び出し、TRUEに戻るとスレッドのRun()関数を呼び出し続け、この関数は標準的なメッセージループを実行し、WM_を受信するとQUITメッセージ後に中断し、メッセージループ中にRun()関数がスレッド空きを検出した場合(メッセージなし)、OnIdle()関数も呼び出され、最後にRun()関数が戻り、MFCがExitInstance()関数を呼び出してリソースをクリーンアップする.
インタフェースなしでメッセージループを持つスレッドを作成できます.たとえば、CWinThreadから新しいクラスを派生し、InitInstance関数でタスクを完了してFALSEに戻ることができます.これは、InitInstance関数のタスクのみを実行し、メッセージループを実行しないことを意味します.この方法で、ワーカースレッドの機能を完了することができます.
プロジェクトケースコードダウンロード:MFCユーザーインタフェースマルチスレッドプロジェクトケース
ダイアログ・ボックス・ベースのエンジニアリングMultiThreadTestを作成し、ダイアログ・ボックスIDD_MultiThreadTest_DIALOGにボタンIDCを追加UI_THREAD、タイトルは「ユーザインタフェーススレッド」.プロジェクトを右クリックし、「New Class...」を選択してプロジェクトにベースクラスをCWinThread派生スレッドクラスCUIThreadに追加します.プロジェクトに新しいダイアログIDDを追加UITHREADDLG、タイトルは「スレッドダイアログ」.ダイアログIDD_UITHREADDLGは、CDialogベースのクラスCUIThreadDlgを作成します.ClassWizardを使用してCUIThreadDlgクラスにWM_を追加LUTTONDOWNメッセージの処理関数OnLBEttonDownは以下の通りです.
void CUIThreadDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
AfxMessageBox(" ");
CDialog::OnLButtonDown(nFlags, point);
}
CUIThread.hに追加
#include "CUIThreadDlg.h"
CUIThreadクラスにprotected変数CUIThreadlg m_を追加dlg:
CUIThreadクラスのヘッダファイルは次のとおりです.
#include "CUIThreadDlg.h"
// CUIThread thread
class CUIThread : public CWinThread
{
DECLARE_DYNCREATE(CUIThread)
// Attributes
public:
// Operations
public:
CUIThread(); // constructor used by dynamic creation
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CUIThread)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL
// Implementation
protected:
virtual ~CUIThread();
CUIThreadDlg m_dlg;
// Generated message map functions
//{{AFX_MSG(CUIThread)
// NOTE - the ClassWizard will add and remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
InitInstance()関数とExitInstance()関数をそれぞれ再ロードします.
BOOL CUIThread::InitInstance()
{
// TODO: perform and per-thread initialization here
m_dlg.Create(IDD_UITHREADDLG);
m_dlg.ShowWindow(SW_SHOW);
m_pMainWnd = &m_dlg;
return TRUE;
}
int CUIThread::ExitInstance()
{
// TODO: perform any per-thread cleanup here
m_dlg.DestroyWindow();
return CWinThread::ExitInstance();
}
メモリの漏洩を避けるため、CUIThreadDlgにWM_を追加DESTROYメッセージ処理関数:
void CUIThreadDlg::OnDestroy()
{
CDialog::OnDestroy();
delete this;
}
ダブルクリックボタンIDC_UI_THREAD、メッセージ応答関数を追加する:void CMultiThreadTestDlg::OnBtnUithread()
{
CWinThread *pThread = AfxBeginThread(RUNTIME_CLASS(CUIThread));
}
注意:UIthread.hにおけるクラスCUIThread()のコンストラクション関数の特性をprotectedからpublicに変更する.
ユーザインタフェーススレッドの実行順序はアプリケーションのメインスレッドと同じであり、まずユーザインタフェーススレッドクラスのInitInstance()関数を呼び出し、TRUEに戻るとスレッドのRun()関数を呼び出し続け、この関数は標準的なメッセージループを実行し、WM_を受信するとQUITメッセージ後に中断し、メッセージループ中にRun()関数がスレッド空きを検出した場合(メッセージなし)、OnIdle()関数も呼び出され、最後にRun()関数が戻り、MFCがExitInstance()関数を呼び出してリソースをクリーンアップする.
インタフェースなしでメッセージループを持つスレッドを作成できます.たとえば、CWinThreadから新しいクラスを派生し、InitInstance関数でタスクを完了してFALSEに戻ることができます.これは、InitInstance関数のタスクのみを実行し、メッセージループを実行しないことを意味します.この方法で、ワーカースレッドの機能を完了することができます.
プロジェクトケースコードダウンロード:MFCユーザーインタフェースマルチスレッドプロジェクトケース