Отправка и получение сообщений Windows - PullRequest
2 голосов
/ 29 июня 2010

Сообщения Windows - хороший способ уведомить приложение в ОС Windows. Это на самом деле хорошо работает, но мало что приходит мне в голову:

Как указать структурированные данные для lparam подпрограмм SendMessage (как это делают многие коды сообщений)? Я имею ввиду ... конечно параметр является указателем, но как процесс доступа к нему? Может быть, это выделяется DLL, загруженной процессами, отправляющими / получающими сообщение?

Возможно ли поделиться структурированными параметрами сообщения (между отправителем и получателем)? Они распределяются между операцией send и операцией peeking ? Если это так, то можно вернуть данные из вызывающей стороны, изменив структурированный параметр? Это может быть полезно с SendMessage, так как он выполняется синхронно, вместо подпрограммы PostMessage.

Другие сомнения ...

В чем отличия от PostMessage и SendNotifyMessage?

Возможно ли вызвать взаимоблокировку в случае, если приложение вызывает SendMessage для себя при обработке сообщения?

Ответы [ 2 ]

4 голосов
/ 29 июня 2010

Если сообщение является одним из сообщений стандартного окна - обычно с идентификатором сообщения от 0 до WM_USER, то логика диспетчеризации сообщений системного окна содержит код для упорядочения структуры для любых процессов, которым отправлено сообщение.

Сообщения выше WM_USER не обрабатываются таким образом - и это включает в себя все распространенные сообщения управления, представленные в Windows 95 - вы не можете завершить ни одно из сообщений LVM_ * (представление списка) или других новых сообщений управления для элемента управления в другом процессе и получить результат обратно.

WM_COPYDATA была специально введена как механизм общего назначения для пользовательского кода для маршалинга произвольных данных между процессами - вне WM_COPYDATA (или повторного использования других стандартных оконных сообщений) нет способа получить окна для автоматического маршалинга структурированных данных с использованием механизма очереди сообщений в другой процесс.

Если отправка и получение сообщений выполняется вашим собственным кодом, вы можете использовать dll для определения раздела совместно используемой памяти, вместо того, чтобы отправлять указатели (dll может быть по-разному базироваться в каждом процессе), отправляет смещения в совместно используемую память блок.

Если вы хотите обмениваться структурированными данными с внешними приложениями, которые не упорядочивают свои данные (например, для извлечения данных из списка или представления дерева), то вам нужно выполнить dll-инъекцию, чтобы вы могли отправлять и обрабатывать сообщение из «в» -процесс».


SendNofityMessage отличается от PostMessage, поскольку PostMessage всегда помещает сообщение в очередь сообщений, тогда как SendNotifyMessage действует как SendMessage для окон в одном и том же процессе. Затем, даже если целевое окно находится в другом процессе, сообщение отправляется ПРЯМО в оконный процесс, не помещенный в очередь опубликованных сообщений для получения через GetMessage или PeekMessage.


Наконец, возможно вызвать взаимоблокировку - однако в то время как в «блокирующем» sendmessage, ожидающем ответа другого потока, SendMessage будет отправлять сообщения, отправленные (не опубликованные) из других потоков, чтобы предотвратить взаимные блокировки. Это уменьшает большинство потенциальных взаимоблокировок, но все еще можно создавать взаимоблокировки, вызывая другие блокирующие apis или входя в модальные циклы обработки сообщений.

0 голосов
/ 29 июня 2010

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

Некоторые межпроцессные сообщения требуют, чтобы вы работали с HGLOBAL (например, сообщения буфера обмена). Другие требуют явного размера блока (например, с WM_COPYDATA). Третьи отправляют данные в заранее заданной структуре (например, строка с нулевым символом в конце) для поддержки сортировки.

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

SendMessage имеет некоторую (довольно сложную) логику для предотвращения взаимоблокировок, но вам все равно нужно быть осторожным.

...