📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
編集の要約なし |
|||
| 58行目: | 58行目: | ||
class CFileView : public CDockablePane | class CFileView : public CDockablePane | ||
{ | { | ||
private: | |||
CWinThread *m_pLoadXMLThread; // スレッドオブジェクトへのポインタ | |||
CCriticalSection m_csDataAccess; // クリティカルセクション (排他制御用) | |||
volatile bool m_bThreadRunning; // スレッド実行中フラグ | |||
// ワーカースレッドで使用するメンバ変数 | |||
CString m_strXMLFilePath; // XMLファイルのパス | |||
int m_nLoadProgress; // 読み込み進捗(0-100) | |||
CArray<CString> m_arrXMLData; // 読み込んだXMLデータ | |||
bool m_bLoadSuccess; // 読み込み成功フラグ | |||
public: | |||
// 静的なワーカースレッド制御関数 | |||
static UINT LoadXMLThreadFunc(void *pParam); | |||
// ワーカースレッド本体 | |||
void LoadXMLThreadFunc(); | |||
// メッセージハンドラ | |||
afx_msg LRESULT OnCompleteLoadXML(WPARAM wParam, LPARAM lParam); | |||
afx_msg LRESULT OnProgressUpdate(WPARAM wParam, LPARAM lParam); | |||
DECLARE_MESSAGE_MAP() | |||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
| 84行目: | 91行目: | ||
BEGIN_MESSAGE_MAP(CFileView, CDockablePane) | BEGIN_MESSAGE_MAP(CFileView, CDockablePane) | ||
ON_MESSAGE(WM_USER_COMPLETE_LOAD_XML, &CFileView::OnCompleteLoadXML) | ON_MESSAGE(WM_USER_COMPLETE_LOAD_XML, &CFileView::OnCompleteLoadXML) | ||
ON_MESSAGE(WM_USER_PROGRESS_UPDATE, &CFileView::OnProgressUpdate) | |||
END_MESSAGE_MAP() | END_MESSAGE_MAP() | ||
// | // ボタン押下時 | ||
void CFileView::OnButtonClick() | void CFileView::OnButtonClick() | ||
{ | { | ||
| 94行目: | 102行目: | ||
return; | return; | ||
} | } | ||
// メンバ変数の初期化 | |||
m_strXMLFilePath = _T("C:\\Data\\sample.xml"); | |||
m_nLoadProgress = 0; | |||
m_bLoadSuccess = FALSE; | |||
m_arrXMLData.RemoveAll(); | |||
// スレッド実行中フラグを設定 | // スレッド実行中フラグを設定 | ||
| 99行目: | 113行目: | ||
// XML読み込み処理スレッド関数を実行 | // XML読み込み処理スレッド関数を実行 | ||
// | // thisポインタを渡すことで、静的関数内でメンバ変数にアクセス可能にする | ||
m_pLoadXMLThread = ::AfxBeginThread( | m_pLoadXMLThread = ::AfxBeginThread( | ||
LoadXMLThreadFunc, // スレッド関数 | LoadXMLThreadFunc, // スレッド関数 | ||
this, // パラメータ (thisポインタ) | this, // パラメータ (thisポインタ) | ||
THREAD_PRIORITY_NORMAL, // スレッドの優先度 | THREAD_PRIORITY_NORMAL, // スレッドの優先度 | ||
0, // スタックサイズ (0 | 0, // スタックサイズ (0: デフォルト) | ||
CREATE_SUSPENDED, // 作成フラグ | CREATE_SUSPENDED, // 作成フラグ | ||
NULL // セキュリティ属性 | NULL // セキュリティ属性 | ||
| 115行目: | 129行目: | ||
m_pLoadXMLThread->m_pMainWnd = this; | m_pLoadXMLThread->m_pMainWnd = this; | ||
// | // 自動削除を無効化(手動でdeleteする) | ||
m_pLoadXMLThread->m_bAutoDelete = FALSE; | m_pLoadXMLThread->m_bAutoDelete = FALSE; | ||
| 138行目: | 152行目: | ||
} | } | ||
// 静的なワーカースレッド制御関数 | // @breif 静的なワーカースレッド制御関数 | ||
// | // @param この制御関数が定義されているクラスへのポインタ(void*型) | ||
// | // @return スレッドの終了コード | ||
// | |||
// @note 静的関数であるため、メンバ変数を直接使用することはできない | |||
// しかし、引数として渡されたthisポインタをキャストすることにより、クラスのメンバ変数およびメンバ関数にアクセスすることが可能となる | |||
UINT CFileView::LoadXMLThreadFunc(void *pParam) | UINT CFileView::LoadXMLThreadFunc(void *pParam) | ||
{ | { | ||
UINT nResult = 0; | UINT nResult = 0; | ||
// void* | // void* から CWnd* にキャストした後、CFileView*にダイナミックキャスト | ||
CFileView *pFileView = dynamic_cast<CFileView*>(reinterpret_cast<CWnd*>(pParam)); | CFileView *pFileView = dynamic_cast<CFileView*>(reinterpret_cast<CWnd*>(pParam)); | ||
if (pFileView) { | if (pFileView) { | ||
try { | try { | ||
// pFileViewポインタを通じてメンバ変数にアクセス可能 | |||
// 例: pFileView->m_strXMLFilePath | |||
// pFileView->m_nLoadProgress | |||
// pFileView->m_arrXMLData | |||
// 実処理はワーカースレッド本体の関数で行う | // 実処理はワーカースレッド本体の関数で行う | ||
pFileView->LoadXMLThreadFunc(); | pFileView->LoadXMLThreadFunc(); | ||
| 160行目: | 182行目: | ||
TRACE(_T("スレッドエラー: %s\n"), szError); | TRACE(_T("スレッドエラー: %s\n"), szError); | ||
e->Delete(); | e->Delete(); | ||
// メンバ変数に失敗フラグを設定 | |||
pFileView->m_bLoadSuccess = FALSE; | |||
nResult = 1; // エラー終了 | nResult = 1; // エラー終了 | ||
} | } | ||
catch (...) { | catch (...) { | ||
TRACE(_T("スレッドで不明なエラーが発生しました。\n")); | TRACE(_T("スレッドで不明なエラーが発生しました。\n")); | ||
pFileView->m_bLoadSuccess = FALSE; | |||
nResult = 1; // エラー終了 | nResult = 1; // エラー終了 | ||
} | } | ||
| 172行目: | 198行目: | ||
// ワーカースレッド本体の関数 | // ワーカースレッド本体の関数 | ||
// 非静的メンバ関数であるため、メンバ変数を自由に使用できる | |||
void CFileView::LoadXMLThreadFunc() | void CFileView::LoadXMLThreadFunc() | ||
{ | { | ||
// | // メンバ変数を使用してXMLファイルのパスを取得 | ||
CString strFilePath = m_strXMLFilePath; | |||
TRACE(_T("XMLファイルの読み込み開始: %s\n"), strFilePath); | |||
// | // 時間のかかる処理をシミュレート | ||
// | for (int i = 0; i < 10; i++) { | ||
// 中断要求の確認 | |||
if (!m_bThreadRunning) { | |||
TRACE(_T("処理が中断されました。\n")); | |||
return; | |||
} | |||
// | // 進捗状況をメンバ変数に設定 | ||
{ | |||
CSingleLock lock(&m_csDataAccess, TRUE); | |||
m_nLoadProgress = (i + 1) * 10; // 10%, 20%, ..., 100% | |||
} | |||
// 進捗状況をメインウインドウに通知 | |||
AfxGetMainWnd()->PostMessage( | |||
WM_USER_PROGRESS_UPDATE, | |||
(WPARAM)m_nLoadProgress, | |||
0 | |||
); | |||
// 実際の処理(例: XMLノードの読み込み) | |||
// ...略 | |||
// ダミーデータをメンバ変数の配列に追加 | |||
CString strData; | |||
strData.Format(_T("XMLデータ_%d"), i + 1); | |||
{ | |||
CSingleLock lock(&m_csDataAccess, TRUE); | |||
m_arrXMLData.Add(strData); | |||
} | |||
::Sleep(500); // 処理のシミュレート | |||
} | |||
// 読み込み成功フラグを設定 | |||
{ | { | ||
CSingleLock lock(&m_csDataAccess, TRUE); | CSingleLock lock(&m_csDataAccess, TRUE); | ||
m_bLoadSuccess = TRUE; | |||
m_nLoadProgress = 100; | |||
} | } | ||
TRACE(_T("XMLファイルの読み込み完了 - データ数: %d\n"), m_arrXMLData.GetCount()); | |||
// XMLファイルの読み込みが完了したメッセージを送信 | // XMLファイルの読み込みが完了したメッセージを送信 | ||
// | // メンバ変数の値をメッセージパラメータとして渡す | ||
AfxGetMainWnd()->SendMessage( | AfxGetMainWnd()->SendMessage( | ||
WM_USER_COMPLETE_LOAD_XML, | WM_USER_COMPLETE_LOAD_XML, | ||
(WPARAM) | (WPARAM)m_arrXMLData.GetCount(), // 読み込んだデータ数 | ||
(LPARAM) | (LPARAM)m_strXMLFilePath.GetString() // ファイルパス | ||
); | ); | ||
} | } | ||
// メッセージハンドラ: XML読み込み完了時の処理 | // メッセージハンドラ : 進捗状況更新 | ||
LRESULT CFileView::OnProgressUpdate(WPARAM wParam, LPARAM lParam) | |||
{ | |||
int nProgress = (int)wParam; | |||
// プログレスバーの更新等 | |||
CString strMsg; | |||
strMsg.Format(_T("読み込み中... %d%%"), nProgress); | |||
// 画面に表示 | |||
// ... | |||
return 0; | |||
} | |||
// メッセージハンドラ : XML読み込み完了時の処理 | |||
LRESULT CFileView::OnCompleteLoadXML(WPARAM wParam, LPARAM lParam) | LRESULT CFileView::OnCompleteLoadXML(WPARAM wParam, LPARAM lParam) | ||
{ | { | ||
int | int nDataCount = (int)wParam; | ||
LPCTSTR pFilePath = reinterpret_cast<LPCTSTR>(lParam); | LPCTSTR pFilePath = reinterpret_cast<LPCTSTR>(lParam); | ||
| 208行目: | 283行目: | ||
UpdateData(TRUE); | UpdateData(TRUE); | ||
// | // メンバ変数から読み込み結果を取得 | ||
CString msg; | if (m_bLoadSuccess) { | ||
CString msg; | |||
AfxMessageBox( | msg.Format(_T("XMLファイルの読み込みが完了しました。\n") | ||
_T("ファイル: %s\n") | |||
_T("データ数: %d\n") | |||
_T("進捗: %d%%"), | |||
pFilePath, nDataCount, m_nLoadProgress); | |||
AfxMessageBox(msg); | |||
// 読み込んだデータをリストボックス等に表示 | |||
for (int i = 0; i < m_arrXMLData.GetCount(); i++) { | |||
// リストボックスに追加 | |||
// m_listBox.AddString(m_arrXMLData[i]); | |||
} | |||
} | |||
else { | |||
AfxMessageBox(_T("XMLファイルの読み込みに失敗しました。")); | |||
} | |||
UpdateData(FALSE); | UpdateData(FALSE); | ||