[英]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.