2012-11-01 27 views
0

期間與GUI交互我有一個類層次結構:長處理

 
class BaseProcess 
{ 
    public virtual void Execute() = 0; 

}; 

class SubProcess : BaseProcess 
{ 
    public virtual void Execute() 
    { 
     //Do Something 

     //Need to call back to the GUI here, maybe to get a file path from a file selector 

     //Do Something Else 

     //Now want to update the GUI with the progress of the operation perhaps 

     //More processing 
    } 
}; 

假設創建一個子對象,並從GUI按鈕事件處理函數調用...

我的問題是什麼從Execute()函數與GUI進行交互的最佳方式是什麼? (還假設Execute()可能在不同的線程上運行)

我的想法是將一個回調傳遞到SubProcess對象,因爲這可以讓我發送信息到GUI,但是在這種情況下的文件選擇器,將數據返回到SubProcess對象的最佳方式是什麼?我希望解決方案儘可能通用,以便根據請求返回不同類型的數據。

注:請忽略任何代碼錯誤,我敲了樣品一起迅速只是爲了說明問題

更新:

對不起要清楚,這將是在Windows,MFC。我不知道這有多重要,因爲我認爲整體設計應該適用於大多數GUI框架?

+1

哪個gui框架? – UmNyobe

+1

線程。獲得一個線程來完成實際的工作,並在完成後告訴它將結果發回GUI。 – andre

+0

如果這是Windows,則可以使用SendMessage()。 –

回答

2
class SubProcess : BaseProcess 
{ 
    public virtual void Execute() 
    { 
     //Do Something 

     char file_name[MAX_PATH +1]; 
     myWindow->SendMessage(WM_GETFILE, max_path, (LPARAM)file_name); 

     //Do Something Else 

     myWindow->SendMessage(WM_UPDATE, 50); 

     //More processing 
    } 
}; 

並在窗口類:

#define WM_GETFILE (WM_USER+1) 
#define WM_UPDATE (WM_USER+2) 

BEGIN_MESSAGE_MAP(CMyWindow, CWnd) 
    ON_MESSAGE(WM_GETFILE, MyGetFileHandler) 
    ON_MESSAGE(WM_UPDATE, MyUpdateHandler) 
END_MESSAGE_MAP() 

LRESULT CMyWindow::MyGetFileHandler(WPARAM wParam, LPARAM lParam) 
{ 
} 
LRESULT CMyWindow::MyUpdateHandler(WPARAM wParam, LPARAM lParam) 
{ 
} 
+0

這幾乎就是我正在尋找的解決方案,謝謝 – TomP89

+0

你還應該使用'Event',這樣GUI線程可以在處理WM_GETFILE消息時提醒工作線程。消息處理程序將包含一個'SetEvent()',並且工作線程將'WaitForSingleObject()'直到事件被設置。 – japreiss

+0

@japreiss SendMessage()將阻塞,所以不需要事件。 –

0

取決於GUI。如果你在一個GUI允許你從不同線程控制它的系統上,那麼你可以從Execute()中直接進行GUI調用。如果GUI不允許這樣做,那麼您可以通過消息與主線程通信,使GUI調用到那裏,並將結果通知給Execute()線程。

一個GUI框架,使這個相當直接的實現是Qt,使用其signals and slots mechanism

實施 getFilePathupdate
0
class GuiCallback 
{ 
public: 
    string getFilePath() {/*show the dialog and return the path*/} 
    void update (/*arguments with data*/) {} 
}; 
class BaseProcess 
{ 
    public virtual void Execute(GuiCallback*) = 0; 

}; 

class SubProcess : BaseProcess 
{ 
    public virtual void Execute(GuiCallback* callback) 
    { 
     //Do Something 

     string path = callback->getFilePath(); 

     //Do Something Else 

     callback->update (...); 

     //More processing 
    } 
}; 

將取決於你使用什麼平臺/ GUI框架

+0

謝謝你的回答,不幸的是我想要比這更通用,所以我可以請求不同類型的數據,而不僅僅是字符串。 – TomP89

+0

@ TomP89,你可以聲明你喜歡的任何類型的函數,你可以在'GuiCallback'中選擇任何類型的返回類型 – 2012-11-01 13:57:41

1

的MFC技術我用前一段時間基於標準Idle Loop處理。

這是簡單的方法,因爲在主線程中運行,您的工作人員可以直接對GUI對象執行操作。

如果您經常從工作進程調用消息循環,則GUI將保持平穩運行。

如果你在開發週期中可以承受一些複雜性,你可以使用線程代替,但以我的經驗來說,它更難。