Проблема с отображением окна сообщения в MFC - PullRequest
0 голосов
/ 13 мая 2010

У меня есть простая программа MFC, которая отображает индикатор выполнения .. Я использовал приведенный ниже код для отображения индикатора выполнения ..

HWND dialogHandle = CreateWindowEx(0,WC_DIALOG,L"Proccessing...",WS_OVERLAPPEDWINDOW|WS_VISIBLE,
                    600,300,280,120,NULL,NULL,NULL,NULL);
HWND progressBarHandle =  CreateWindowEx(NULL,PROGRESS_CLASS,NULL,WS_CHILD|WS_VISIBLE|PBS_MARQUEE,40,20,200,20,
            dialogHandle,(HMENU)IDD_PROGRESS,NULL,NULL);

while(FALSE == testResult)
    {
        MSG msg;
         SendMessage(progressBarHandle, PBM_SETRANGE, 0, MAKELPARAM( 0, 100 ) );
        SendMessage(progressBarHandle,PBM_SETPOS,0,0);
        ShowWindow(progressBarHandle,SW_SHOW);
        Sleep(50);
             if(TRUE == myCondition)//myCondition is a bool variable which is decalred globally
            {

                DestroyWindow(dialogHandle);
                 AfxMessageBox(L"Test Success");
             }
        }

когда я выполняю приведенный выше код ... окно сообщения отображается только после события наведения мыши. Например, если я перемещаю мышь, окно сообщения будет отображаться, если нет, то оно не будет отображаться, пока я не перемещу мышь. А также во время работы индикатора выполнения, если я пытаюсь переместить окно индикатора выполнения .. оно отображает фон окна в месте смещения, а также в новом регионе или иногда в его застревании. Пожалуйста, помогите мне с этим!

EDIT2: прокачка сообщений.

while(PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE) && (FALSE == testResult))
    {
       if(msg.message == WM_QUIT)
      {
        DestroyWindow(dialogHandle);
        return TRUE;
       }
      SendMessage(progressBarHandle, PBM_SETRANGE, 0, MAKELPARAM( 0, 100 ) );
      SendMessage(progressBarHandle,PBM_SETPOS,0,0);
       ShowWindow(progressBarHandle,SW_SHOW);
        TranslateMessage(&msg);
        DispatchMessage(&msg);
        //return 1;
    }

Ответы [ 2 ]

0 голосов
/ 13 мая 2010

AfxMessageBox вызывает MessageBox на CWinApp (доступно через CWinApp). Таким образом, я собираюсь догадаться, что код, который вы опубликовали, находится в ветке (также из-за ваших последних сообщений). Поэтому, когда вы вызываете AfxMessageBox, он ожидает в главном потоке, чтобы он действительно отображался.

Если вы позвоните

 MessageBox( NULL, L"Test Success", NULL, MB_OK );

это работает тогда? Если это так, то это, скорее всего, ваша проблема ...

Редактировать: Хм, это сложно, потому что я перенес ваш оригинальный цикл в пустое приложение MFC, и он работал нормально. Проблема должна существовать в каком-то другом фрагменте кода где-то ... Как выглядит поток, который устанавливает myCondition?

0 голосов
/ 13 мая 2010

Я не уверен, какого поведения вы пытаетесь достичь.
Основная проблема заключается в том, что ваше главное окно должно обрабатывать сообщения, чтобы вел себя правильно, а вы этого не делаете.

while (FALSE == testResult) {
    MSG msg;
    // Here you `reset` the progress bar, one each turn, why?
    SendMessage(progressBarHandle, PBM_SETRANGE, 0, MAKELPARAM( 0, 100 ) );
    SendMessage(progressBarHandle,PBM_SETPOS,0,0);
    ShowWindow(progressBarHandle,SW_SHOW);
    Sleep(50); // <-- here you PAUSE main thread for 50 milliseconds

    // myCondition is a bool variable which is decalred globally
    if (TRUE == myCondition) {
          DestroyWindow(dialogHandle);
          AfxMessageBox(L"Test Success");
     }

    // Here you'll loop, and you don't give the main thread a chance to
    // process the message queue.
}

По моему мнению, вместо использования Sleep(50); вы можете установить таймер и использовать его обратный вызов для обновления индикатора выполнения. Это наивное решение, но вы можете попробовать.

Редактировать: Возможно это? Я не проверял это.

while (FALSE == testResult) {
    MSG msg;
    // Here you `reset` the progress bar, one each turn, why?
    SendMessage(progressBarHandle, PBM_SETRANGE, 0, MAKELPARAM( 0, 100 ) );
    SendMessage(progressBarHandle,PBM_SETPOS,0,0);
    ShowWindow(progressBarHandle,SW_SHOW);
    Sleep(50); // <-- here you PAUSE main thread for 50 milliseconds

    // myCondition is a bool variable which is decalred globally
    if (TRUE == myCondition) {
        AfxMessageBox(L"Test Success")
        DestroyWindow(dialogHandle);
        return TRUE;
    }

    // Process the message queue
    while(PeekMessage(&msg,NULL,NULL,NULL,PM_NOREMOVE)) {
       if(msg.message == WM_QUIT) {
           DestroyWindow(dialogHandle);
           return TRUE;
       }
       TranslateMessage(&msg);
       DispatchMessage(&msg);
    }
}
...