我在MFC上与CSTATUSBAR有一个对话框。在单独的线程中,我想更改状态栏的窗格文本。但是,MFC对断言抱怨?如何完成?示例代码很棒。

有帮助吗?

解决方案

您可以将私人消息发布到主帧窗口并“要求”它以更新状态栏。线程将需要主窗口句柄(不要使用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 UPDATE函数删除它,例如:

// 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;
}

并不完美,但这是一个开始。

其他提示

也许这可以帮助您: 如何从MFC中的线程访问UI元素。

我本人没有编码C ++/MFC,但是我在C#中遇到了类似的问题,该问题被称为跨线程GUI更新。

您应该使用一条消息(带有发送或后期的消息)来通知UI线程,该线程应更新状态栏文本。不要试图从工人线程中更新UI元素,这必然会给您带来痛苦。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top