Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > C/C++: Системное программирование и WinAPI > Как обрабатывать windows - сообщений в консольном приложении C++


Автор: Lun2 11.06.22, 14:41
Добрый вечер!

У меня имеется рабочее консольное приложение.
Мне необходима обработка некоторых Windows-сообщений, чтобы асинхронно ловить некоторые сообщения DirectShow, которые он выдает в виде Windows-сообщений. Поэтому я хочу определить для себя наименее затратный способ сделать это (обработку сообщений).

Я нашел статейку, которая показывает, как создать окно.

Вопрос1: Правильно ли я понимаю, что этот пример в статье подойдет для создания окна, подключения оконной процедуре и получения сообщений ?

Пример заканчивается стандартным циклом:
C++


<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
     while (GetMessage(&msg, 0, 0, 0)) {
        TranslateMessage(&msg);  
        DispatchMessage(&msg);  
      }


Я вижу 2 варианта - (1) по этому примеру создать окно в основном потоке, а чтобы программа продолжила работу - все продолжение вынести в отдельный поток,
или наоборот (2) - создание окна и это цикл сделать в отдельном потоке, чтобы они не мешали основной программе.

Вопрос2: варианты (1) и (2) - одинаково рабочие или один из них невозможен, вызовет какие-то проблемы ?

Прошу подсказать максимально подробно, насколько это для Вас возможно, как решить задачу по перехвату сообщений в консольном приложении.

Автор: Eric-S 11.06.22, 17:31
Цитата Lun2 @
по этому примеру создать окно в основном потоке, а чтобы программа продолжила работу - все продолжение вынести в отдельный поток

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

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

Это верно для обычных windows приложений. Должно быть верно и для всех прочих приложений.

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

Автор: Lun2 12.06.22, 11:27
Eric-S, все же я хотел бы уточнить в отношении этого:

"Цикл обработки сообщений, предполагает, что он работает в главном потоке приложения. Поэтому, считаю, такой вариант наиболее корректным.
Опять же, стандартно подразумевается, что фоновая работа выполняется в дополнительных потоках".

Это что-то типа "good practice" или требование MS.
Я напрямую таких ограничений не нашел, хотя может быть плохо искал...
Сейчас в моем примере создание окна осущ-ся в основном потоке, а цикл обработки сообщений - в дополнительном.
Насколько я понял, в таком случае и оконная процедура будет вызываться в дополнительном ?

Автор: Eric-S 12.06.22, 12:50
Цитата Lun2 @
Это что-то типа "good practice" или требование MS.

Это классическая практика, которую использует большинство разработчиков в простых приложениях.

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

Добавлено
Цитата Lun2 @
Сейчас в моем примере создание окна осущ-ся в основном потоке, а цикл обработки сообщений - в дополнительном.
Насколько я понял, в таком случае и оконная процедура будет вызываться в дополнительном ?

В том-то и проблема, что межпотоковое взаимодействие вносит путаницу. Кто и как обеспечивает синхронизацию? Вот у вас окно создаётся в главном потоке. А кто и как обеспечивает согласование этого окна с другим потоком? Увы, я не знаю, а поэтому не скажу.

Ваша оконная процедура, вызывается функциями цикла обработки сообщений. Соответственно, она будет вызываться в том потоке, в котором работают эти самые функции.

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

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)