私はPBS_MARQUEEスタイルでの作業プログレスバーを作成する方法を知っているが、私はアニメーションを進めるためにlong_operation()
から連続SendMessage(hPB, PBM_STEPIT, 0, 0);
を呼び出さず、トラブル私がいる限り、いくつかのlong_operation()
実行などマーキーアニメーションをしたいような状況で、それを実装したのです。それが停止したときにビープ音が継続している間、私は上記のコードで何を得る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コントロールに送受信されません。
これを行うには直感的な方法が必要だと感じますが、わかりません。
これについてはどうすればよいですか?
std :: threadが直感的であると非難されたことがあまりにも確実ではない。しかし、これは、UIスレッドがバーを更新できるようにするために必要なことです。プログレスバーの代わりに砂時計のカーソルがかなり直感的です。 –
'long_operation'をワーカースレッドにオフロードします。これは多くの方法で行うことができる。 'std :: thread'、' std :: async'、またはWindowsのネイティブスレッドの実装( 'CreateThread' /' _beginthreadex')を使用します。特に、 'long_operation'から' SendMessage'を呼び出すことは、部分的な解決策を実装するだけです。それでも、他のメッセージのディスパッチを防ぎ、ユーザーが対話しようとしているときなどにダイアログがハングアップしているように見せかけます。 – IInspectable
何が起こっているのは、あなたがUIを応答しないようにするUIスレッドで作業しているということです。バックグラウンドスレッドで作業を行うことでその問題を解決してください。 –