Я пишу 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;
}
Существует ряд модальных операций, которые происходят в окнах. Модальные операции Win32 относятся к функциям, которые переводят приложение в "режим", запуская свой собственный цикл обработки событий, пока режим не завершится. Обычные режимы приложения включают операции перетаскивания, перемещения/размера, когда появляется диалог, требующий ввода данных, прежде чем приложение сможет продолжить работу.
Итак, что происходит: ваш цикл обработки сообщений НЕ запускается. Ваше окно получило сообщение WM_LBUTTONDOWN, которое вы передали в DefWindowProc. DefWindowProc определил, что пользователь пытается изменить размер или переместить окно интерактивно, и ввел модальную функцию изменения размера/перемещения. Эта функция находится в цикле обработки сообщений и следит за сообщениями мыши, чтобы перехватить их для обеспечения интерактивного изменения размера, и завершается только тогда, когда операция изменения размера завершена - обычно пользователь отпускает удерживаемую кнопку или нажимает escape.
Вы получите уведомление об этом - DefWindowProc посылает сообщения WM_ENTERSIZEMOVE и WM_EXITSIZEMOVE, когда он входит и выходит из цикла обработки модальных событий.
Чтобы продолжать генерировать "холостые" сообщения, обычно создают таймер (SetTimer) перед вызовом модальной функции - или при получении сообщения о том, что DefWindowProc входит в модальную функцию - модальный цикл будет продолжать посылать сообщения WM_TIMER... и вызывать idle proc из обработчика сообщений таймера. Уничтожьте таймер, когда модальная функция вернется.
Во время изменения размера 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() не создает и не потребляет никаких событий. Если это так, то все становится намного сложнее.