Come cambiare il testo riquadro di barra di stato da un thread in MFC?
-
23-08-2019 - |
Domanda
ho una finestra di dialogo in MFC con un CStatusBar. In un thread separato, voglio cambiare il testo riquadro di barra di stato. Tuttavia MFC si lamenta con asserisce? Com'è fatto? Un esempio di codice sarebbe grande.
Soluzione
Si potrebbe inviare un messaggio privato alla finestra telaio principale e 'chiedere' per aggiornare la barra di stato. Il filo avrebbe bisogno l'handle della finestra principale (non utilizzare l'oggetto CWnd in quanto non sarà thread-safe). Ecco alcuni esempi di codice:
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;
}
Il codice è dalla memoria come io non ho accesso a compilatore qui a casa, quindi mi scuso ora per eventuali errori.
Invece di usare WM_USER
si potrebbe registrare il proprio messaggio di Windows:
UINT WM_MY_MESSAGE = ::RegisterWindowsMessage(_T("WM_MY_MESSAGE"));
Fare la di sopra di un membro statico di CMainFrame
per esempio.
Se utilizza risorse di stringa è troppo di base quindi hanno il filo allocare la stringa sul mucchio e assicurarsi che la funzione di aggiornamento CMainFrame elimina, per esempio:.
// 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;
}
Non è perfetto, ma è un inizio.
Altri suggerimenti
Forse questo può aiutare: Come accedere elementi dell'interfaccia utente da un thread in MFC.
Non fare il codice C ++ / MFC me, ma avevo sperimentato il problema simile in C # che è conosciuto come aggiornamento cross-thread GUI.
Si dovrebbe usare un messaggio (sia con Invia- o PostMessage) per notificare il thread dell'interfaccia utente che la barra di testo di stato dovrebbe essere aggiornato. Non cercare di aggiornare gli elementi dell'interfaccia utente da un thread di lavoro, è destinato a dare dolore.