簡體   English   中英

如何在單獨的線程中創建帶有進度條的MFC對話框?

[英]How to create a MFC dialog with a progress bar in a separate thread?

我的應用程序可能需要一段時間才能連接到數據庫。 這個連接使用單個庫函數調用,即我不能在其中放入進度更新並進行回調或類似的操作。

我的想法是在連接到數據庫之前在單獨的線程中創建一個帶有進度條的對話框。 此對話框將使用CProgressCtrl::StepIt()不斷更改進度狀態,以便用戶看到發生的事情。
在設置完對話框並執行其操作之后,我想從主線程調用數據庫連接函數。 連接功能完成后,我想停止進度條線程。

讓我畫一幅畫:

CMyApp::       ProgressThread
InitInstance()      .
    |               .
    |               .
    +-Create Dialog-+
    |               |
    |             Animate
 Connect          Progress
    to             Bar
    DB              |
    |               |
    +-Destroy Dlg---+
    |               .
    |               .

那可能嗎? 如果有,怎么樣?

也許整個事情也可以使用計時器。 可能會簡單得多,但我也無法做到這一點。

  1. 我知道CProgressCtrl::SetMarquee()可能正是我需要的,但我不能使用它因為應用程序沒有Unicode支持。
  2. 我可以將數據庫連接調用移動到一個單獨的線程中,但這樣看起來像代碼的大量更改和連接錯誤的額外處理。

更新2
我按照AlexEzh和Javier De Pedro建議的方式工作:將DB stuf放入自己的線程中。
最初我擔心如何處理錯誤,但它實際上與之前的情況非常相似。

  1. 在主線程中,我創建了一個帶有連接參數的結構,結果標志和thread-running-flag。 后者最初設置為true
  2. 我創建一個線程並將該結構作為參數傳遞。
  3. 我創建了一個在主線程中顯示進度條的對話框。
  4. 同樣在主線程中,有一個循環在設置thread-running-flag時運行。 它調用CMyDialog::Animate()調用CProgressCtrl::StepIt()然后調用Sleep()
  5. 該線程執行db-connection代碼並在完成false running-flag設置為false
  6. 當主線程退出循環時,它可以完全像以前一樣處理錯誤。

缺點:將鼠標移到窗口上不起作用。 它是看不見的。 因此,不能使用取消按鈕或其他交互式對話元素。 但是,我可以忍受這一點。

既然您喜歡這個圖表,現​​在的樣子如下:

CMyApp::        WorkerThread
InitInstance()      .
    |               .
    |               .
Create Dialog       .
    |               .
    +-Start Thread--+
    |               |
    |             Connect
 Animate            to
 Progress           DB
   Bar              |
    |               |
    +-Thread Ends---+
    |               .
 Destroy Dlg        .
    |               .

我希望文章有關與進度條創建自己的線程啟動畫面可能會有所幫助。 我在解決MFC消息隊列級別的線程鎖定問題時編寫了它。

  1. 使用AfxBeginThread創建工作線程。
  2. 在該線程中創建一個CProgressCtrl並調用Create ,將對話框作為CProgressCtrl的父級傳遞,使用選取框樣式進行控制。
  3. 在Thread中創建一個消息等待循環:

    MSG消息;
    while(GetMessage(&Msg,NULL,0,0))
    {
    的TranslateMessage(MSG);
    DispatchMessage函數(MSG);
    }

  4. 消息循環需要檢查全局標志以查看是否退出循環。

將DB連接邏輯移動到單獨的線程仍然更安全。 使用對話框線程上的DB,您將能夠重新繪制進度條,但不能重新繪制對話框中的其他控件。

您是否嘗試將SendMessagePBM_SETMARQUEE而不是SetMarquee一起使用。 我從來沒有嘗試過,但它應該有效。

在我看來,實現你想要做的最簡單的方法是在ui線程中同時創建ProgressBar和DB連接,並使用OnTimer在進度條中調用StepIt 您還可以在ui線程中創建進度條,並使用自定義消息為工作線程修改進度狀態。

無論如何,我同意AlexEzh的說法,最好的辦法就是讓整個非UI工作在工作線程中。

創建一個成員變量as

CProgressCtrl m_progress;

使用進度條ID在DoDataExcchange中的DDX_Control中添加m_progress

在按鈕單擊功能下添加以下代碼。

m_progress.setRange(0,100);
m_progress.SetPos(1);

暫無
暫無

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

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