Je sais comment créer un ProgressBar fonctionnant avec le style PBS_MARQUEE, mais j'ai du mal à l'implémenter dans une situation où je veux l'animation de sélection tant que long_operation()
fonctionne, sans avoir à appeler SendMessage(hPB, PBM_STEPIT, 0, 0);
en continu de long_operation()
pour avancer l'animation.Comment faire fonctionner ProgressBar avec le style PBS_MARQUEE?
Voici une de mes tentatives infructueuses:
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();
}
Ce que je reçois avec le code ci-dessus est une barre de progression marquee sans animation tout continue à émettre des bips, puis un chapiteau d'animation normale quand il arrête. Pour autant que je sache, puisque long_operation()
bloque le thread, les files d'attente de messages sont également bloquées et le message de mise à jour 30ms par défaut n'est pas envoyé/reçu par le contrôle ProgressBar. Je pense qu'il doit y avoir une manière intuitive de le faire, mais je ne peux pas le comprendre.
De quoi s'agit-il?
Pas si sûr si std :: thread a déjà été accusé d'être intuitif. Mais c'est ce qu'il faut pour garder votre thread d'interface utilisateur capable de mettre à jour la barre. Un curseur sablier au lieu d'une barre de progression est assez intuitif. –
Décharge 'long_operation' sur un thread de travail. Cela peut être fait de plusieurs façons, par ex. en utilisant 'std :: thread',' std :: async', ou l'implémentation native de Windows ('CreateThread' /' _beginthreadex'). Notez en particulier que l'appel 'SendMessage' de' long_operation' implémente uniquement une solution partielle. Il empêche toujours l'envoi d'autres messages, ce qui provoque l'affichage de la boîte de dialogue, lorsqu'un utilisateur tente d'interagir avec lui, par exemple. – IInspectable
Qu'est-ce qui se passe, c'est que vous travaillez dans le thread UI, ce qui rend l'interface utilisateur ne répond pas. Résolvez ce problème en faisant le travail dans un thread d'arrière-plan. –