簡體   English   中英

我可以在MFC中有多個GUI線程嗎?

[英]Can I have multiple GUI threads in MFC?

我有一個基於MFC的大型應用程序,它包含主線程中一些可能非常慢的任務。 這可以給出應用程序在實際執行長任務時掛起的外觀。 從可用性的角度來看,我想向用戶提供更多關於進度的反饋,並且可以選擇以干凈的方式中止任務。 雖然將長任務分解為單獨的線程將是一個更好的長期解決方案,但我認為一個實用的短期解決方案是創建一個新的GUI線程,封裝在自己的對象中,包括進度條和取消按鈕,用於與CWait對象類似的方式。 主線程通過IsCancelled方法監視取消狀態,並在需要時通過throw完成。

這是一種合理的方法,如果有的話,那里有一些我可以使用的MFC代碼,或者我應該自己動手? 第一幅草圖看起來像這樣

class CProgressThread : public CWinThread
{
public:
    CProgressThread(int ProgressMax);      
    ~CProgressThread()
    void SetProgress(int Progress);
    BOOL IsCancelled();
private:
   CProgressDialog  *theDialog;
}

void MySlowTask()
{
   CProgressThread PT(MaxProgress);
   try
   {
       {
           {  // deep in the depths of my slow task
              PT.SetProgress(Progress);
              if (PT.IsCancelled())
                 throw new CUserHasHadEnough; 
           }
        }
    }
    catch (CUserHasHadEnough *pUserHasHadEnough)
    {
        // Clean-up
    }
}    

作為一項規則,我傾向於有一個GUI線程和許多工作線程,但這種方法可能會省去一堆重構和測試。 任何嚴重的潛在陷阱?

簡而言之,是的,您可以在MFC中擁有多個GUI線程。 但是除了創建的線程之外,您無法直接訪問GUI組件。 原因是因為MFC下的Win32存儲了每個線程的GUI處理程序。 這意味着一個線程中的處理程序對另一個線程不可見。 如果跳轉到CWinThread類源代碼,可以在那里找到處理程序映射屬性。

Windows(MFC)在工作線程和GUI線程之間沒有硬性差異。 一旦創建了消息隊列,就可以將任何線程更改為GUI線程,該消息隊列是在與消息相關的第一次調用之后創建的,例如GetMessage()。

在上面的代碼中,如果在一個線程中創建了進度條,而在另一個線程中調用了MySlowWork()。 您只能在不觸及Win32 GUI相關功能的情況下使用CProgressThread屬性,例如close,setText,SetProgress ......因為它們都需要GUI處理程序。 如果您確實調用了這些函數,則錯誤將無法找到指定的窗口,因為該處理程序不在線程處理程序映射中。

如果確實需要更改GUI,則需要將消息發送到該進度條所有者線程。 讓該線程通過PostThreadMessage自己處理消息(消息處理程序) ,詳細信息請參考MSDN

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM