CStatusBar を使用して MFC にダイアログがあります。別のスレッドで、ステータス バーのペイン テキストを変更したいと考えています。しかし、MFC はアサートに文句を言いますか? それはどのように行われますか?サンプルコードは素晴らしいでしょう。
3 に答える
メインフレームウィンドウにプライベートメッセージを投稿し、ステータスバーを更新するように「依頼」することができます。スレッドにはメインウィンドウハンドルが必要です(スレッドセーフではないため、CWndオブジェクトは使用しないでください)。サンプルコードは次のとおりです。
static UINT CMainFrame::UpdateStatusBarProc(LPVOID pParam);
void CMainFrame::OnCreateTestThread()
{
// Create the thread and pass the window handle
AfxBeginThread(UpdateStatusBarProc, m_hWnd);
}
LRESULT CMainFrame::OnUser(WPARAM wParam, LPARAM)
{
// Load string and update status bar
CString str;
VERIFY(str.LoadString(wParam));
m_wndStatusBar.SetPaneText(0, str);
return 0;
}
// Thread proc
UINT CMainFrame::UpdateStatusBarProc(LPVOID pParam)
{
const HWND hMainFrame = reinterpret_cast<HWND>(pParam);
ASSERT(hMainFrame != NULL);
::PostMessage(hMainFrame, WM_USER, IDS_STATUS_STRING);
return 0;
}
自宅ではコンパイラにアクセスできないため、コードはメモリからのものです。エラーが発生したことをお詫びします。
使用する代わりにWM_USER
、独自のWindowsメッセージを登録できます。
UINT WM_MY_MESSAGE = ::RegisterWindowsMessage(_T("WM_MY_MESSAGE"));
たとえば、上記をの静的メンバーにCMainFrame
します。
文字列リソースの使用が基本的すぎる場合は、スレッドに文字列をヒープに割り当てさせ、CMainFrame更新関数が文字列を削除することを確認します。例:
// Thread proc
UINT CMainFrame::UpdateStatusBarProc(LPVOID pParam)
{
const HWND hMainFrame = reinterpret_cast<HWND>(pParam);
ASSERT(hMainFrame != NULL);
CString* pString = new CString;
*pString = _T("Hello, world!");
::PostMessage(hMainFrame, WM_USER, 0, reinterpret_cast<LPARAM>(pString));
return 0;
}
LRESULT CMainFrame::OnUser(WPARAM, LPARAM lParam)
{
CString* pString = reinterpret_cast<CString*>(lParam);
ASSERT(pString != NULL);
m_wndStatusBar.SetPaneText(0, *pString);
delete pString;
return 0;
}
完璧ではありませんが、それは始まりです。
メッセージ(Send-またはPostMessageのいずれか)を使用して、ステータスバーのテキストを更新する必要があることをUIスレッドに通知する必要があります。ワーカースレッドからUI要素を更新しようとしないでください。それはあなたに苦痛を与えるに違いありません。
多分これはあなたを助けることができます: MFC のスレッドから UI 要素にアクセスする方法。
私自身は C++/MFC のコーディングはしていませんが、クロススレッド GUI アップデートとして知られる C# で同様の問題を経験したことがあります。