我知道如何創建一個帶有PBS_MARQUEE風格的工作ProgressBar,但是我只需要運行一些long_operation()
而不需要從long_operation()
連續調用SendMessage(hPB, PBM_STEPIT, 0, 0);
來推進動畫,就可以實現它。如何使PBS_MARQUEE風格的ProgressBar工作?
這裏是我的失敗嘗試中的一種:
INT_PTR CALLBACK ProgressDlgProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) {
switch(message) {
case WM_INITDIALOG:
{
HWND hProgressBar = GetDlgItem(hWnd, IDC_PROGRESS1);
LONG_PTR style_flags = GetWindowLongPtr(hProgressBar, GWL_STYLE);
SetWindowLongPtr(hProgressBar, GWL_STYLE, style_flags | PBS_MARQUEE);
SendMessage(hProgressBar, (UINT)PBM_SETMARQUEE, (WPARAM)1, (LPARAM)NULL);
break;
}
}
return FALSE;
}
void long_operation() {
for(int i = 0; i < 9; ++i) {
for(int j = 0; j < 99999999; ++j)
;
Beep(5000, 100);
}
}
void do_operation() {
HWND hDlg = CreateDialog(Dll_globals::g_hInst,
MAKEINTRESOURCE(IDD_DIALOG4), // assume this contains a ProgressBar ctl
Dll_globals::g_hWndMain, ProgressDlgProc);
if(hDlg) {
ShowWindow(hDlg, SW_SHOW);
UpdateWindow(hDlg);
}
long_operation();
}
我得到與上面的代碼是一個大帳篷進度條沒有任何動畫,同時繼續發出蜂鳴聲,然後一個正常的動畫字幕時停止。
據我所知,由於long_operation()
阻塞了線程,消息隊列也被阻塞,並且默認的30ms更新消息不會被髮送到ProgressBar控件或被ProgressBar控件接收。
我覺得必須有一種直觀的方式來做到這一點,但我無法弄清楚。
這是怎麼回事?
不太確定std :: thread是否曾被指責爲直覺。但是,這是保持你的UI線程能夠更新欄的原因。沙漏光標而不是進度條非常直觀。 –
將'long_operation'卸載到工作線程上。這可以通過多種方式完成,例如,通過使用'std :: thread','std :: async'或Windows本地線程實現('CreateThread' /'_beginthreadex')。特別要注意的是,調用'long_operation'中的'SendMessage'只能實現部分解決方案。例如,當用戶嘗試與其交互時,它仍然阻止分派其他消息,導致對話框出現掛起。 – IInspectable
發生了什麼事是您正在UI線程中工作,導致UI無響應。通過在後臺線程中完成工作來解決該問題。 –