2008-12-24 5 views

Répondre

4

Vous pouvez envoyer un message privé à la fenêtre du cadre principal et le 'demander' pour mettre à jour la barre d'état. Le thread aurait besoin de la poignée de la fenêtre principale (n'utilisez pas l'objet CWnd car il ne sera pas thread-safe). Voici quelques exemples de code:

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

Le code est de la mémoire que je n'ai pas accès au compilateur ici à la maison, donc maintenant des excuses pour les erreurs éventuelles.

Au lieu d'utiliser WM_USER vous pouvez enregistrer votre propre message Windows:

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

Faire ce qui précède un membre statique de CMainFrame par exemple.

Si vous utilisez des ressources de chaîne est trop basique ont alors le fil d'allouer la chaîne sur le tas et assurez-vous que la fonction de mise à jour CMainFrame supprime, par exemple .:

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

Pas parfait, mais il est un bon début.

+0

La plage de messages WM_USER est la bonne réponse ici. RegisterWindowMessage est un peu lourd pour un message d'application privée, car il garantit l'unicité dans tout le système, et ce n'est pas nécessaire ici. – Joel

+1

La gamme de messages WM_APP est encore meilleure. –

2

Vous devez utiliser un message (avec Send- ou PostMessage) pour notifier le thread d'interface utilisateur que le texte de la barre d'état doit être mis à jour. N'essayez pas de mettre à jour les éléments de l'interface utilisateur à partir d'un thread de travail, cela risque de vous faire mal.

+0

Vous devriez PostMessage, pas SendMessage. La raison pour laquelle MFC et C# se plaignent de ces choses est que SendMessage est un appel bloquant et peut provoquer des blocages. – Joel

Questions connexes