Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.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 |
Это классическая практика, которую использует большинство разработчиков в простых приложениях. У ms я тоже не встречал. Наоборот, есть оговорки, что возможно создание разных циклов обработки сообщений для разных потоков. И есть даже специальные функции, отправляющие сообщения в другие потоки. Так что запретов нет и вы, конечно же, можете сделать цикл обработки сообщений в любом потоке. Добавлено Цитата Lun2 @ Сейчас в моем примере создание окна осущ-ся в основном потоке, а цикл обработки сообщений - в дополнительном. Насколько я понял, в таком случае и оконная процедура будет вызываться в дополнительном ? В том-то и проблема, что межпотоковое взаимодействие вносит путаницу. Кто и как обеспечивает синхронизацию? Вот у вас окно создаётся в главном потоке. А кто и как обеспечивает согласование этого окна с другим потоком? Увы, я не знаю, а поэтому не скажу. Ваша оконная процедура, вызывается функциями цикла обработки сообщений. Соответственно, она будет вызываться в том потоке, в котором работают эти самые функции. Но функция SendMessage вызывает процедуру обработки сообщений почти напрямую и конечно же в своём потоке. Следовательно вызывать SendMessage надо в потоке цикла сообщений или же использовать другую функцию, которая обеспечивает межпотоковое взаимодействие. |