Win32: Мое Приложение замораживается, в то время как пользователь изменяет размер окна

Я пишу win32 приложение. Я реализовал цикл сообщения сам как это:

     bool programcontinue = true;
     while(programcontinue)
     {
              while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
              {
                       TranslateMessage(&Msg);
                       DispatchMessage(&Msg);
              }

              IdleProcess();
     }

В моем приложении существует окно изменяемого размера. Обычно, IdleProcess () называют несколько раз в секунду. Когда пользователь захватывает угол или край окна изменяемого размера, IdleProcess () не становится названным больше до разъединений абонентом кнопка мыши.

Что происходит здесь?

Я пытался обмениваться внутренним, в то время как с, если, но это не изменяет поведение. Походит, когда изменение размеров запускается, обработчик для того сообщения не возвращается, пока изменение размеров не сделано?

Существует ли способ изменить это и назвать IdleProcess () во время изменения размеров несколько раз в секунду?

Спасибо Marc

Править:

Что я подразумеваю под заменой внутреннего, в то время как с тем, если:

 bool programcontinue = true;
 while(programcontinue)
 {
          if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))  // <<<<
          {
                   TranslateMessage(&Msg);
                   DispatchMessage(&Msg);
          }

          IdleProcess();
 }

Мое окно Proc немного длинно, но я получаю то же поведение с маленьким тестовым приложением. Это идентично wndproc, который создает Мастер Проекта VS:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    switch (message)
    {
    case WM_COMMAND:
        wmId    = LOWORD(wParam);
        wmEvent = HIWORD(wParam);
        // Parse the menu selections:
        switch (wmId)
        {
        case IDM_ABOUT:
            DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
            break;
        case IDM_EXIT:
            DestroyWindow(hWnd);
            break;
        default:
            return DefWindowProc(hWnd, message, wParam, lParam);
        }
        break;
    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);
        // TODO: Add any drawing code here...
        EndPaint(hWnd, &ps);
        break;
    case WM_DESTROY:
        PostQuitMessage(0);
        break;
    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
8
задан marc40000 23 June 2010 в 15:21
поделиться

2 ответа

Существует ряд модальных операций, которые происходят в окнах. Модальные операции Win32 относятся к функциям, которые переводят приложение в "режим", запуская свой собственный цикл обработки событий, пока режим не завершится. Обычные режимы приложения включают операции перетаскивания, перемещения/размера, когда появляется диалог, требующий ввода данных, прежде чем приложение сможет продолжить работу.

Итак, что происходит: ваш цикл обработки сообщений НЕ запускается. Ваше окно получило сообщение WM_LBUTTONDOWN, которое вы передали в DefWindowProc. DefWindowProc определил, что пользователь пытается изменить размер или переместить окно интерактивно, и ввел модальную функцию изменения размера/перемещения. Эта функция находится в цикле обработки сообщений и следит за сообщениями мыши, чтобы перехватить их для обеспечения интерактивного изменения размера, и завершается только тогда, когда операция изменения размера завершена - обычно пользователь отпускает удерживаемую кнопку или нажимает escape.

Вы получите уведомление об этом - DefWindowProc посылает сообщения WM_ENTERSIZEMOVE и WM_EXITSIZEMOVE, когда он входит и выходит из цикла обработки модальных событий.

Чтобы продолжать генерировать "холостые" сообщения, обычно создают таймер (SetTimer) перед вызовом модальной функции - или при получении сообщения о том, что DefWindowProc входит в модальную функцию - модальный цикл будет продолжать посылать сообщения WM_TIMER... и вызывать idle proc из обработчика сообщений таймера. Уничтожьте таймер, когда модальная функция вернется.

14
ответ дан 5 December 2019 в 08:22
поделиться

Во время изменения размера Windows посылает довольно много сообщений вашей программе. Я этого не доказал, но описанное вами поведение мне знакомо. Я бы предложил вызывать вашу функцию IdleProcess() также в цикле while(...) для определенных событий, таких как WM_SIZING, которые ваше приложение будет часто получать во время изменения размера окна:

 bool programcontinue = true;
 while(programcontinue)
 {
          while (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE))
          {
                   TranslateMessage(&Msg);
                   DispatchMessage(&Msg);
                   if(Msg.message == WM_SIZING)
                       IdleProcess();
          }

          IdleProcess();
 }

Имейте в виду, что это предполагает, что IdleProcess() не создает и не потребляет никаких событий. Если это так, то все становится намного сложнее.

0
ответ дан 5 December 2019 в 08:22
поделиться
Другие вопросы по тегам:

Похожие вопросы: