在MFC中显示消息框时出现问题

时间:2010-05-13 12:05:30

标签: winapi mfc progress-bar

我有一个简单的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 :(得分:0)

我不确定你想要达到什么样的行为 主要问题是您的主窗口必须处理消息才能正确行为,而您没有这样做。

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.
}

在我看来,您可以设置timer而不是使用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);
    }
}

答案 1 :(得分:0)

AfxMessageBox调用CWinApp上的MessageBox(可通过CWinApp获得)。因此我猜你发布的代码是在一个帖子中(也是由于你最近的帖子)。因此,当您调用AfxMessageBox时,它正在主线程上等待它实际显示。

如果你打电话

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

那么它有效吗?如果是这样,这很可能是你的问题......

编辑:这很难,因为我将原始循环移植到一个空的MFC应用程序中,它工作正常。问题必须存在于其他某些代码中......设置myCondition的线程是什么样的?