Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > PostMessage - отправить record


Автор: Domoffou 11.11.2008, 02:15
Как можно отправить свою структуру данных (record) через PostMessage?
Я пробовал так:
Код

type
  MYSTRUCT = record
    par1: CARDINAL;
    par2: CARDINAL;
    par3: CARDINAL;
  end;
  PMYSTRUCT = ^MYSTRUCT;


Код

var
  E: MYSTRUCT;
begin
     E.par1:=123;
     E.par2:=321;
     E.par3:=333;

     PostMessage(HWND_BROADCAST, WM_SENTFROMHOOK, 0, Longint(@E)); // так не доходит
     SendMessage(HWND_BROADCAST, WM_SENTFROMHOOK, 0, Longint(@E)); // а так доходит!!!!!!!!!!!!!!!!
   end;
end; 

Автор: dumb 11.11.2008, 07:52
Цитата(Domoffou @  11.11.2008,  03:15 Найти цитируемый пост)
PostMessage(HWND_BROADCAST, WM_SENTFROMHOOK, 0, Longint(@E)); // так не доходит

и не дойдет. PostMessage, в отличие от SendMessage, только кладет сообщение в очередь. твоя структура является локальной переменной и лежит в стеке, который разрушается после выхода из процедуры. таким образом сообщение содержит указатель на недействительный кусок памяти.
мало того, по идее, и SendMessage не должен работать, т.к. ты передаешь указатель на область памяти в передающем процессе, а в принимающем процессе этот указатель смысла не имеет. но тут microsoft "подстелила соломки" - SendMessage копирует кусок памяти в адресное пространство получающего процесса. вообще же, корректным способом передачи является сообщение WM_COPYDATA в сочетании с SendMessage.

чтобы передавать через PostMessage, надо ужаться до двух DWORD'ов(cardinal) и засовывать их в wParam и lParam. иначе придется использовать MMF(memory mapped files).

Автор: CodeMonkey 11.11.2008, 10:25
Кто ловит это сообщение? Тот же процесс или нет? 
Для двух процессов это не должно работать даже с SendMessage по тем же причинам, что указал dumb: у двух разных процессов индивидуальные адресные пространства и указатель из одного из них не имеет смысла в другом. Чтобы можно было передать данные, нужно соединить часть адресных пространств. Делать это нужно через http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx или любые обёртки для него - например, тот же http://msdn.microsoft.com/en-us/library/ms649011(VS.85).aspx или http://msdn.microsoft.com/en-us/library/aa365152(VS.85).aspx или ещё 100 и один способ.

Цитата(dumb @  11.11.2008,  07:52 Найти цитируемый пост)
но тут microsoft "подстелила соломки" - SendMessage копирует кусок памяти в адресное пространство получающего процесса

Ээээ.... вообще-то SendMessage по-умолчанию ничего такого не делает. Только для специальных типов сообщений, например, WM_COPYDATA или WM_GETTEXT. Но уж точно не для пользовательского сообщения.

Автор: dumb 11.11.2008, 13:40
Цитата(CodeMonkey @  11.11.2008,  11:25 Найти цитируемый пост)
SendMessage по-умолчанию ничего такого не делает.
smile
было нечеткое воспоминание, что оно для каких-то "левых" сообщений копирует, и показания пациента(все врут (с) хаус), что мол "работает" - вот и предположилоС, что оно умничает на lParam. smile
каюсь, был неправ, обещаю исправиться. smile

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