Как изменить текст панели состояния строки из потока в MFC? - PullRequest
6 голосов
/ 24 декабря 2008

У меня есть диалог в MFC с CStatusBar. В отдельной теме я хочу изменить текст панели состояния. Однако MFC жалуется с утверждениями? Как это сделать? Пример кода был бы отличным.

Ответы [ 3 ]

5 голосов
/ 24 декабря 2008

Вы можете опубликовать личное сообщение в главном окне фрейма и «попросить» его обновить строку состояния. Потоку потребуется дескриптор главного окна (не используйте объект 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;
}

Не идеально, но это начало.

3 голосов
/ 24 декабря 2008

Может быть, это может вам помочь: Как получить доступ к элементам пользовательского интерфейса из потока в MFC.

Я сам не кодирую C ++ / MFC, но у меня возникла похожая проблема в C #, известном как обновление многопоточного графического интерфейса.

2 голосов
/ 24 декабря 2008

Вы должны использовать сообщение (либо с Send-, либо с PostMessage), чтобы уведомить поток пользовательского интерфейса о необходимости обновления текста строки состояния. Не пытайтесь обновить элементы пользовательского интерфейса из рабочего потока, это может причинить вам боль.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...