2016-10-11 16 views
0

我的應用程序需要在InitInstance()創造一些昂貴的東西。我想通知用戶有關進度,所以我決定在InitInstance()方法中創建一個無模式對話框。無模式對話框中的應用:: InitInstance中()

我的問題是,對話框沒有繪製。它剛好在

CStartStopDlg dlg(_T("Start")); 
dlg.Create(IDD_START_STOP_DLG); 
dlg.ShowWindow(SW_SHOW); 

// expensive stuff 

m_pMainWnd->ShowWindow(SW_SHOW); 
m_pMainWnd->UpdateWindow(); 

即使當我在此行之後放置睡眠時,它也會更新對話框。問題是,MainFrame使用我創建的資源,所以我不能重新排列這些行。

如何解決這個問題?


編輯: 昂貴的東西是連接攝像頭,連接到io的硬件,連接到數據庫和創建工作線程。應用程序對象擁有所有這些東西,大型機及其視圖等使用它。由於這些東西與應用程序中的文檔無關。

根據以太網負載,需要不同的時間來連接。

模式對話框不需要響應。我只想像Adobe Reader的啓動對話框那樣。

UpdateWindow()的提示是一個正確的方向,我添加了一個調用這個函數,因爲我更新了狀態。這解決了我的問題。

+0

對於要繪製的對話框,應用程序必須屈服,並且即使您調用dlg.UpdateWindow()或什麼,在執行「昂貴的東西」時對話框也不會響應用戶輸入。也許在不同的線程中創建對話框?另一種實現方式是在另一個線程下執行「昂貴的東西」,在應用程序初始化後計劃(例如使用定時器); UI元素應該被禁用,直到「昂貴的東西」完成。 –

回答

2

這聽起來像你的「昂貴的東西」是計算綁定,不允許任何UI線程(S)的更新。這些類型的問題通常通過利用單獨的線程來提供進度反饋來解決。你可能想看看Using Worker Threads的一些使用線程來解決這類問題的背景。

+0

*「這聽起來像你的'昂貴的東西'是計算綁定」* - 問題中沒有任何跡象表明這一點,如果是這樣的話,它無論如何都是無關緊要的。重要的細節是,它是**同步**。恐怕,爲了掩蓋缺乏洞察力而流行的流行語不會在這裏飛來飛去。這個建議答案的其餘部分是非常模糊的,它值得*「這個答案沒有用」*投票。 – IInspectable

+0

@Indusableable雖然我可以尊重你的意見,但我常常驚訝於你如何迴應本網站上的許多人。至少有一個人認爲我的回答很有幫助,但是,如果你不瞭解我的第一件事,你就會詆譭我。現在是時候看看鏡子,看看那些討厭的連線來自哪裏。 – rrirower

+0

我不知道,爲什麼你開始在個人層面上採取這個。我評論了答案的質量(並且你可以放棄**一票**,這通常是OP說「*謝謝」*的一種方式,但不作爲質量的指示)。這個建議的答案從一個錯誤的假設開始,並試圖提出解決方案(如果有的話,這些解決方案只發生巧合應用)。如果你感到驚訝,我留下評論,說我爲什麼低估了提出的答案,繼續前進,並驚訝你想要的一切。不過,我可以在將來爲你制定一個例外。 – IInspectable

3

CStartStopDlg dlg(_T("Start"));創建一個owned對話框,因爲pParentWnd被隱式設置爲NULL(見CDialog::CDialog)。該對話框由主應用程序窗口擁有。擁有的窗口的

一個特點是,當他們的主人是隱藏的,他們是隱藏的。所以直到你撥打m_pMainWnd->ShowWindow(SW_SHOW);,你所擁有的對話框也不會出現。

有很多方法可以解決這個問題。

  1. 顯而易見的解決方案是立即顯示主應用程序窗口。但是,這可能不實際(並且不能解決阻塞UI線程的問題)。
  2. 卸載昂貴初始化到一個工作線程:
    這是必需的,使得在UI線程可以服務進來的消息,例如作爲用戶交互的結果。您需要在工作線程和GUI線程之間實現某種通信。將自定義消息(WM_APP + x)發佈到主應用程序窗口通常就足夠了。
  3. 推遲昂貴的初始化:
    InitInstance不應該做任何比啓動此應用程序實例所需的更多的操作。任何昂貴的操作都應推遲到用戶可以看到UI(並可能取消該操作)的點。
    一個常用的方法是爲此創建一個一次性定時器。由於WM_TIMER消息是低優先級的,因此這些消息只會在處理完所有其他消息後纔會到達,並且應用程序處於可操作狀態。此時,您可以將昂貴的初始化卸載到工作線程,並顯示一個對話框,直到完成。