PostMessage с приоритетом?

Можно ли установить приоритет сообщения, отправленного с помощью PostMessage (или любого другого связанного метода)?

IIRC, например, сообщение WM_PAINT обрабатывается только тогда, когда в очереди нет других сообщений. Можно ли добиться аналогичного поведения с пользовательскими сообщениями?

Если я использую WM_PAINT со специальными параметрами для доставки пользовательского сообщения окну (которым я управляю WndProc), будет ли оно вести себя аналогично?


person sold    schedule 25.11.2009    source источник


Ответы (2)


Я хотел, чтобы фоновый поток уведомлял основной о том, что результаты доступны для отображения пользователю. Но если вы просто отправите сообщение в основной поток, оно будет обработано немедленно.

Это привело к тому, что приложение не отвечало на сообщения рисования или ввода пользователя, потому что мое отправленное сообщение всегда имело приоритет.

Уловка, которую я использовал, заключалась в том, что я знал, что сообщения WM_TIMER имеют более низкий приоритет, чем сообщения WM_PAINT.

Поэтому вместо того, чтобы публиковать сообщение в основной форме, я бы установил таймер.

Сообщения таймера имеют более низкий приоритет, чем

  • другие опубликованные сообщения
  • сообщения WM_PAINT
person Ian Boyd    schedule 13.02.2016

Для WM_PAINT оконный код в DefWndProc просто устанавливает флаг, а затем проверяет этот флаг, только если очередь пуста при следующем вызове GetMessage. Некоторые сообщения мыши также объединяются (более старые удаляются, когда приходят новые).

Реальный ответ зависит от поведения, которого вы на самом деле хотите достичь.

Если вы пытаетесь избежать повторного входа, просто установите флажок для быстрого выхода, например:

////bool processing = false; // class/window instance variable
...
void HandleCustomMessage()
{
    ////if (processing)
    ////{
    ////    return;
    ////}

    ////processing = true;
    DoSomething();
    ////processing = false;
}

Если вам нужна реальная очередь с приоритетом, существует множество реализаций PQ. Добавьте элемент данных в PQ, а затем опубликуйте собственное сообщение (всегда с одним и тем же идентификатором). Затем настраиваемый обработчик сообщений запрашивает у PQ элемент с наивысшим приоритетом.


Другой вариант — перехватить цикл GetMessage, использовать вызов PeekMessage, чтобы узнать, не нужно ли что-то сделать, затем вызвать GetMessage, если сообщение доступно, или проверить свой PQ в противном случае. При таком подходе вам не нужно специальное сообщение.

person devstuff    schedule 25.11.2009
comment
Не уверен, что понимаю подход флага. Очереди пользовательского интерфейса являются однопоточными, поэтому вы все равно никогда не столкнетесь с условием (или, если вы имеете в виду предотвращение повторного входа в несколько очередей, я не понимаю, как это относится к расстановке приоритетов). Использование пользовательского сообщения + отдельного PQ — хорошая идея, хотя расстановка приоритетов не будет работать вместе с другими нестандартными сообщениями. Мне было интересно, есть ли для этого какой-то внутренний механизм? - person sold; 25.11.2009
comment
Упс, полусонный и забыл про единый UI-поток — удивительно, как быстро забываешь, когда не имеешь дело с этим каждый день. - person devstuff; 26.11.2009