У вас уже было несколько ответов, но ни один из них не упомянул тревожную часть вашего вопроса:
tMyMessage = record
mode: byte;
//...some other fields...
end;
Обратите внимание, что вы не можете делать все то, что вы можете считать само собой разумеющимся всреда .NET, когда вы используете Delphi или какую-либо другую оболочку для собственной обработки сообщений Windows.Вы можете ожидать, что сможете передавать случайные структуры данных обработчику событий, но это не сработает.Причина заключается в необходимости управления памятью.
В .NET вы можете быть уверены, что структуры данных, на которые больше нет ссылок, будут удалены из-за сборки мусора.В Delphi у вас нет такой свободы действий, вам нужно убедиться, что любой выделенный блок памяти также освобожден правильно.
В Windows получатель сообщения является либо дескриптором окна (a HWND
) который вы SendMessage()
или PostMessage()
, или это поток, к которому вы PostThreadMessage()
.В обоих случаях сообщение может содержать только два элемента данных, оба из которых имеют ширину машинного слова, первый тип WPARAM
, второй тип LPARAM
).Вы не можете просто отправить или опубликовать произвольную запись в качестве параметра сообщения.
Все типы записей сообщений, используемые Delphi, имеют в основном одинаковую структуру, которая соответствует приведенному выше ограничению размера данных.
ЕслиВы хотите отправить данные в другой поток, который состоит из более чем двух 32-битных переменных, и тогда все становится сложнее.Из-за ограничений размера значений, которые могут быть отправлены, вы не сможете отправить всю запись, а только ее адрес.Для этого вы должны динамически распределить структуру данных в потоке-отправителе, передать адрес в качестве одного из параметров сообщения и переинтерпретировать тот же параметр в потоке-получателе, что и адрес переменной того же типа, а затем использовать данные взапись и освободите динамически распределяемую структуру памяти.
Таким образом, в зависимости от объема данных, которые необходимо отправить обработчику событий, вам может потребоваться изменить запись tMyMessage
.Это можно заставить работать, но это сложнее, чем необходимо, потому что проверка типа недоступна для данных вашего события.
Я бы посоветовал решить это немного по-другому.Вы знаете, какие данные вам нужно передать из рабочих потоков в поток GUI.Просто создайте структуру данных, в которую вы помещаете данные параметров вашего события, вместо того, чтобы отправлять их вместе с сообщением.Сделайте эту очередь поточно-ориентированной, то есть защитите ее критическим разделом, чтобы добавление или удаление из очереди было безопасно даже при попытке одновременно из разных потоков.
Чтобы запросить новую обработку событий, просто добавьте данные втвоя очередьОтправлять сообщение в принимающий поток можно только тогда, когда первый элемент данных добавлен в ранее пустую очередь.Затем принимающий поток должен получить и обработать сообщение и продолжить извлекать элементы данных из очереди и вызывать соответствующие обработчики событий, пока очередь снова не станет пустой.Для лучшей производительности очередь должна быть заблокирована как можно короче, и она определенно должна быть снова временно разблокирована, пока вызывается обработчик события.