📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

編集の要約なし
 
58行目: 58行目:
  class CFileView : public CDockablePane
  class CFileView : public CDockablePane
  {
  {
    private:
private:
      CWinThread     *m_pLoadXMLThread;    // スレッドオブジェクトへのポインタ
    CWinThread       *m_pLoadXMLThread;    // スレッドオブジェクトへのポインタ
      CCriticalSection m_csDataAccess;     // クリティカルセクション (排他制御用)
    CCriticalSection m_csDataAccess;       // クリティカルセクション (排他制御用)
      volatile bool   m_bThreadRunning;    // スレッド実行中フラグ
    volatile bool     m_bThreadRunning;    // スレッド実行中フラグ
   
   
     public:
     // ワーカースレッドで使用するメンバ変数
      // 静的なワーカースレッド制御関数
    CString          m_strXMLFilePath;    // XMLファイルのパス
      static UINT LoadXMLThreadFunc(void *pParam);
    int              m_nLoadProgress;     // 読み込み進捗(0-100)
    CArray<CString>  m_arrXMLData;        // 読み込んだXMLデータ
    bool              m_bLoadSuccess;      // 読み込み成功フラグ
   
   
      // ワーカースレッド本体
public:
      void LoadXMLThreadFunc();
    // 静的なワーカースレッド制御関数
    static UINT LoadXMLThreadFunc(void *pParam);
   
   
      // メッセージハンドラ
    // ワーカースレッド本体
      afx_msg LRESULT OnCompleteLoadXML(WPARAM wParam, LPARAM lParam);
    void LoadXMLThreadFunc();
   
   
      DECLARE_MESSAGE_MAP()
    // メッセージハンドラ
    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読み込み処理スレッド関数を実行
     // CREATE_SUSPENDED : 一時停止状態でスレッドを作成
     // 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する)
       // 自動削除を無効化(手動で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*からCWnd*にキャスト後、CFileView*にダイナミックキャスト
     // 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ファイルのパスを取得
     // 例: XMLファイルの読み込み
     CString strFilePath = m_strXMLFilePath;
   
   
     CString firstFilePath = _T("C:\\Data\\sample.xml");
     TRACE(_T("XMLファイルの読み込み開始: %s\n"), strFilePath);
    int firstIndex = 0;
   
   
     // 時間の掛かる処理を実行
     // 時間のかかる処理をシミュレート
     // ...略
     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;
     } // lock変数のスコープを抜けると自動的にアンロック
     }
    TRACE(_T("XMLファイルの読み込み完了 - データ数: %d\n"), m_arrXMLData.GetCount());
   
   
     // XMLファイルの読み込みが完了したメッセージを送信
     // XMLファイルの読み込みが完了したメッセージを送信
     // SendMessageは同期的に処理される (戻り値を受け取れる)
     // メンバ変数の値をメッセージパラメータとして渡す
     AfxGetMainWnd()->SendMessage(
     AfxGetMainWnd()->SendMessage(
       WM_USER_COMPLETE_LOAD_XML,
       WM_USER_COMPLETE_LOAD_XML,
       (WPARAM)&firstIndex,
       (WPARAM)m_arrXMLData.GetCount(),     // 読み込んだデータ数
       (LPARAM)firstFilePath.GetString()
       (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 *pIndex = reinterpret_cast<int*>(wParam);
     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) {
    msg.Format(_T("XMLファイルの読み込みが完了しました。\nIndex: %d\nPath: %s"), *pIndex, pFilePath);
      CString msg;
     AfxMessageBox(msg);
      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);