Come modificare il testo del riquadro della barra di stato da un thread in MFC?

 C Programming >> Programmazione C >  >> Tags >> MFC
Come modificare il testo del riquadro della barra di stato da un thread in MFC?


Ho una finestra di dialogo in MFC con un CStatusBar. In un thread separato, voglio cambiare il testo del riquadro della barra di stato. Tuttavia MFC si lamenta con affermazioni? Com'è fatto? Un codice di esempio sarebbe fantastico.


Risposte:


Puoi inviare un messaggio privato alla finestra del frame principale e "chiedere" di aggiornare la barra di stato. Il thread avrebbe bisogno dell'handle della finestra principale (non utilizzare l'oggetto CWnd in quanto non sarà thread-safe). Ecco un esempio 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 proviene dalla memoria poiché non ho accesso al compilatore qui a casa, quindi mi scuso ora per eventuali errori.


Invece di usare WM_USER potresti registrare il tuo messaggio di Windows:


UINT WM_MY_MESSAGE = ::RegisterWindowsMessage(_T("WM_MY_MESSAGE"));

Rendi quanto sopra un membro statico di CMainFrame per esempio.


Se l'utilizzo delle risorse di stringa è troppo semplice, fai in modo che il thread allochi la stringa nell'heap e assicurati che la funzione di aggiornamento di CMainFrame la elimini, ad 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.


Alcune risposte al 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;
}
UINT WM_MY_MESSAGE = ::RegisterWindowsMessage(_T("WM_MY_MESSAGE"));
// 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;
}