Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > Delphi программирование > Общие вопросы Delphi
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 22.12.2010, 08:35   #1
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию Передача сложной структуры пользовательским сообщением?

Здравствуйте, уважаемые!
Подскажите, как передать сложную структуру пользовательским сообщенем через SendMessage?

Пример структуры:
Код:
  TMyRec = packed record
    ParamA:integer;
    ParamB:string;
  end;
Отсылаю так:
Код:
var
  a:integer;
  b:string;
  M:TMyRec;
begin
  a:=1234;
  b:='safsdg';
  M.ParamA:=a;
  M.ParamB:=b;
  SendMessage(MainFormA.Handle,WM_MyMsg,1,Integer(@M));
end;
А вот получить никак не получается... Привести типы никак не могу, ругается на Invalid typecast...
Подскажите как правильно? WM_COPYDATA не интересует.
Заранее благодарен!
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}
Johnson вне форума Ответить с цитированием
Старый 22.12.2010, 08:45   #2
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию

извиняюсь, ответ нашел сам)

Структура:
Код:
  TMyRec = packed record
    ParamA:integer;
    ParamB:string;
  end;
  PMyRec = ^TMyRec;

Посылка:
Код:
procedure TMainFormA.Button2Click(Sender: TObject);
var
  a:integer;
  b:string;
  M:TMyRec;
begin
  a:=1234;
  b:='safsdg';
  M.ParamA:=a;
  M.ParamB:=b;
  SendMessage(MainFormA.Handle,WM_MyMsg,1,Integer(@M));
end;

Прием:
Код:
procedure TMainFormA.MyMsgProc(var Mes: TMessage);   // Message WM_MyMsg
var
  x:integer;
begin
  X:= PMyRec( Mes.LParam )^.ParamA;
  Memo1.Lines.Add('пришла мессага '+BoolToStr( bool(Mes.WParam) , true)+' '+IntToStr(X) );
end;
Тему можно закрыть...
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}
Johnson вне форума Ответить с цитированием
Старый 22.12.2010, 09:05   #3
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Кому посылаем-то? Это будет работать только в рамках одного процесса.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 22.12.2010, 09:06   #4
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию

Это я экспериментировал с мессагами. В дальнейшем мессаги будут слаться из библиотеки, внедренной в другой процесс.
Навроде того:
Код:
SendMessage(FindWindow('TDLLInjectForm',nil),WM_PInfoAll,Integer(@InfoAlMes),Integer(@M));
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}

Последний раз редактировалось Johnson; 22.12.2010 в 09:08.
Johnson вне форума Ответить с цитированием
Старый 22.12.2010, 09:39   #5
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

Тогда это не будет работать. SizeOf(String) = 4. Всегда. Вне зависимости от содержимого (данных) строки.

Как несложно сообразить, передав эти 4 байта в другой процесс вы не передадите все прочие Length(String) * SizeOf(Char) байт данных.

Домашнее задание: объяснить, почему это работает в одном процессе.

Мат-часть:
http://www.transl-gunsmoker.ru/2009/...tml#references
http://www.transl-gunsmoker.ru/2009/09/pchars.html
http://wm-help.net/books-online/book/59464/59464-6.html
http://wm-help.net/books-online/book.../59464-16.html
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 22.12.2010, 09:40   #6
GunSmoker
Старожил
 
Регистрация: 13.08.2009
Сообщений: 2,581
По умолчанию

P.S. Решение: нужно сериализовать структуру в поток. Проще всего это сделать используя TPersistent вместо записей.
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
GunSmoker вне форума Ответить с цитированием
Старый 22.12.2010, 09:59   #7
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию

Да уже разобрался... Придётся всётаки использовать WM_COPYDATA
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}
Johnson вне форума Ответить с цитированием
Старый 23.12.2010, 06:30   #8
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию

Чтот никак не получается с WM_COPYDATA

отправляю примерно так:

Код:
procedure Tmain_form.Button1Click(Sender: TObject);
var
wnd: HWND;
cd: tCopyDataStruct;
M: tR;
begin
   wnd := findWindow(nil, 'EXELORED');
   r.s := edit1.Text;
   cd.dwData := 0;
   cd.cbData := sizeOf(r);
   cd.lpData := @r;
   sendMessage(wnd, WM_COPYDATA, application.Handle, longint(@cd));
end;
получать пытась:
Код:
procedure Tmain_form.cpd(var m: TWMCopyData);
var
pR: ^tR;
begin
   pR := m.CopyDataStruct.lpData;
   label1.Caption:=pR^.s;
   edit1.Text := pR^.s;
end;
но на получении строки выкидывает с Access Volation
что делаю не так?
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}
Johnson вне форума Ответить с цитированием
Старый 23.12.2010, 07:18   #9
igh0st
Форумчанин
 
Аватар для igh0st
 
Регистрация: 05.07.2010
Сообщений: 136
По умолчанию

А я бы предложил XML
igh0st вне форума Ответить с цитированием
Старый 23.12.2010, 08:04   #10
Johnson
кривокодер ;)
Форумчанин
 
Аватар для Johnson
 
Регистрация: 20.06.2008
Сообщений: 707
По умолчанию

Эмм а причем тут XML??

прошлый раз писал по памяти и по примерам... щас вот код под рукой...
Итак. Структура записи:

Код:
  TL2InfoMsg = packed record
    CurrentProcessId:Cardinal;
    CurrentThreadId:Cardinal;
    S:string;
  end;
Отсылка:
Код:
  M.CurrentProcessId:=GetCurrentProcessId;
  M.CurrentThreadId:=GetCurrentThreadId;
  M.S:='Testing';

  copyDataStruct.dwData := 1;
  copyDataStruct.cbData := SizeOf(M) ;
  copyDataStruct.lpData := @M ;

  gWnd:=FindWindow('TDLLInjectForm',nil);
  if gWnd<>0 then SendMessage(gWnd, WM_COPYDATA, 1234, Longint(@copyDataStruct)) ;
Отсылает без проблем.

Прием:
Код:
procedure TDLLInjectForm.WMCopyData(var Msg: TWMCopyData);
var
  M:^TL2InfoMsg;
  S:String;
begin
  Memo1.Lines.Add('Пришла мессага WM_COPYDATA');
  M := Msg.CopyDataStruct.lpData ;
  S:=M^.S;
end;
При S:=M^.S; выкидывает с AV...
В чем я не прав? Никак не могу сообразить...

При бряке перед этой строкой вижу, что CurrentProcessId показывает правильно (как в диспетчере задач). ИД потока тоже правильный... А вот S пишет Inaccesable value

ЗЫ: если строку объявить ShortString (S:string[255] то передается нормально...
"А как написать праграму?, "ришыти задачьку очинь нада" ©с форума. Жить становится интереснее, жить становится веселее...
{Быть или не быть} {Неуспешный суицид}
Johnson вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Создание сложной структуры XML artemavd Общие вопросы Delphi 24 19.11.2010 19:57
построение XML сложной структуры с помощью nativeXML adben Общие вопросы Delphi 2 29.07.2010 07:06
символьные данные сложной структуры и имя массива как параметр функции EkaterinaA Помощь студентам 3 22.02.2009 21:36
Сохранение в файл сложной динамической структуры _Инженер_ Общие вопросы Delphi 24 20.10.2008 09:38