Модераторы: Snowy, bartram, MetalFan, bems, Poseidon, Riply
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Ошибка с WM_COPYDATA 
:(
    Опции темы
Red Wind
Дата 5.11.2005, 22:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



Столкнулся с необходимостью получения данных из dll. Для этого я использую SendMessage WM_COPYDATA. Но в получающей прогрмме я не могу корректно прочитать полученные данные. Как я понял, прога обращаеться не в ту что нужно область памяти. Т.к. если посылать сообщение только внутри проги, а не из dll или из другого приложения всё отлично работает. Скажите пожалуйста, в чём я допустил ошибку.

Код


type
  MsgType = packed record
    s:string;
    i:integer;
  end;
  PMsgType = ^MsgType;

//Отправитель
procedure SentData;
var cd : TCopyDataStruct;
    m:MsgType;
begin
  m.s:='MyStr';
  m.i:=107114;
  cd.cbData:=SizeOf(m);
  cd.lpData:=@m;
  SendMessage(FindWindow(nil,'Form1'),WM_COPYDATA,0,Integer(@cd));
end;

// Получатель
procedure TForm1.WMCopyData(var Msg: TMessage);
var   pcd : PCopyDataStruct;
      a:PMsgType;
begin
  pcd:=PCopyDataStruct(Msg.lParam);
  a:=PMsgType(pcd.lpData);
  ListBox1.Items.Add(a^.s);
end;


PM MAIL ICQ   Вверх
Snowy
Дата 5.11.2005, 23:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 30
Всего: 484



Код

var    
  cd: TCopyDataStruct;    
  s:  PChar;    
  wnd: HWND;    
begin    
  wnd:=FindWindow(nil, 'The Window');    
  s:='Дорогое окно, шлю тебе эту строку с наилучшими пожеланиями';    
  cd.dwData:=107114;    
  cd.cbData:=Length(s);    
  cd.lpData:=@s;    
  SendMessage(wnd,WM_COPYDATA, 0 ,dword(@cd));    
end;

Добавлено @ 23:31
Попробуй слать PChar, а не стринг.
Со стрингом будут проблемы из-за его устройства.

Это сообщение отредактировал(а) Snowy - 5.11.2005, 23:31
PM MAIL   Вверх
Snowy
Дата 5.11.2005, 23:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 11363
Регистрация: 13.10.2004
Где: Питер

Репутация: 30
Всего: 484



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

PM MAIL   Вверх
Демо
Дата 6.11.2005, 00:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Данные должны быть переданы непрерывной структурой.
String - это указатель. Работать с с динамическими строками надо соответственно.

Вот пример:

Код

procedure TForm1.Button1Click(Sender: TObject);
type
    TRec=packed record
       i: Integer;
       LenStr: Integer;
       Buf: array of Char;
    end;
var
    cd: TCopyDataStruct;
    Rec: TRec;
    s: String;
begin
    s := 'Тестовая строка';
    Rec.i := 107114;
    Rec.LenStr := Length(s);
    SetLength(Rec.Buf,Rec.LenStr);
    Move(s[1],Rec.Buf[0],Rec.LenStr);
    cd.dwData := 0;
    cd.cbData := SizeOf(Integer)*2+Length(Rec.Buf);
    cd.lpData := @Rec;
    SendMessage(Form1.Handle,WM_COPYDATA,0,Integer(Pointer(@cd)));
end;

procedure TForm1.onWMCOPYDATA(var Msg: TMessage);
type
    PRec=^TRec;
    TRec=packed record
       i: Integer;
       LenStr: Integer;
       Buf: array of Char;
    end;
var
    pcd: PCopyDataStruct;
    Rec: PRec;
    s: String;
begin
    pcd := Pointer(Msg.lParam);
    Rec := Pointer(pcd^.lpData);
    SetLength(s,Rec^.LenStr);
    Move(Rec^.Buf[0],s[1],Rec^.LenStr);
    Memo1.Lines.Add('i='+IntToStr(Rec^.i)+',buf='+s);
end;



--------------------
    
PM MAIL ICQ Skype   Вверх
p0s0l
Дата 6.11.2005, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Г-н Посол
****


Профиль
Группа: Экс. модератор
Сообщений: 3668
Регистрация: 13.7.2003
Где: 58°38' с.ш. 4 9°41' в.д.

Репутация: 14
Всего: 112



Цитата
String - это указатель. Работать с с динамическими строками надо соответственно.
А разве Array of Char - это не указатель ? smile

Правильно делается так:
Код

type
  PMsgType = ^TMsgType;
  TMsgType = packed record
     i : integer;
     BufLen : integer;
     Buf : array [0..0] of char;
  end;

...

var
  cd : TCopyDataStruct;
  msg : PMsgType;
  s : string;

begin
  s := 'MyStr';
  cd.cbData := SizeOf(msg^) + Length(s)-1;
  GetMem (msg, cd.cbData);
  cd.lpData := msg;

  msg.i := 107114;
  msg.BufLen := Length(s);
  Move (PChar(s)^, msg.Buf, msg.BufLen);

  SendMessage(FindWindow(nil,'Form1'),WM_COPYDATA,0,Integer(@cd));
  FreeMem (msg);
end;


Если же нужно переслать только 1 число и 1 строку, то проще сделать так, как предложил Snowy, только немного изменив:
Код
var
  cd: TCopyDataStruct;     
  s : string;
  wnd: HWND;
begin
  wnd:=FindWindow(nil, 'Form1');
  s:='Дорогое окно, шлю тебе эту строку с наилучшими пожеланиями';
  cd.dwData:=107114;
  cd.cbData:=Length(s);
  cd.lpData:=PChar(s);
  SendMessage(wnd,WM_COPYDATA, 0 ,dword(@cd));
end;


Если длина строки не превышает 255 символов, то можно воспользоваться твоим изначальным вариантом, переправив структуру TMsgType:
Код

type    
  MsgType = packed record    
    s:ShortString;    
    i:integer;    
  end;    
  PMsgType = ^MsgType;
А если длина превышает 255 символов и не содержит нулевых символов, и не охото возиться с выделением-освобождением памяти, то можно сделать структуру такую:
Код

type    
  MsgType = packed record    
    s:array[0..1023] of char; // или какой-нужно-длины
    i:integer;    
  end;    
  PMsgType = ^MsgType;



--------------------
С уважением, г-н Посол.
PM   Вверх
Red Wind
Дата 6.11.2005, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 280
Регистрация: 25.6.2004
Где: Минск

Репутация: нет
Всего: 2



Всем спасибо! Но первые два варианта не работают smile . А третий уже не проверял - решил задачу другим способом.
PM MAIL ICQ   Вверх
casinosoftguru
Дата 13.5.2009, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 138
Регистрация: 22.12.2008

Репутация: нет
Всего: нет



Господа! Все отлично работает в XP но не работает под Vista! Есть идеи ?
PM MAIL   Вверх
CodeMonkey
Дата 13.5.2009, 16:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1839
Регистрация: 24.6.2008
Где: Россия, Тверь

Репутация: 16
Всего: 89



Ошибка в 13-й строке.


--------------------
Опытный программист на C++ легко решает любые не существующие в Паскале проблемы.
PM MAIL WWW ICQ Skype GTalk Jabber   Вверх
Демо
Дата 13.5.2009, 20:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1278
Регистрация: 3.11.2005

Репутация: 6
Всего: 50



Цитата(casinosoftguru @  13.5.2009,  14:35 Найти цитируемый пост)
Господа! Все отлично работает в XP но не работает под Vista! Есть идеи ? 

Версия Delphi?


--------------------
    
PM MAIL ICQ Skype   Вверх
Keeper89
Дата 13.5.2009, 21:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2580
Регистрация: 26.2.2009

Репутация: 14
Всего: 58



Цитата(casinosoftguru @  13.5.2009,  14:35 Найти цитируемый пост)
Господа! Все отлично работает в XP но не работает под Vista! Есть идеи ? 

Если работаете в D2009, объявите s вместо string как AnsiString.

Это сообщение отредактировал(а) Keeper89 - 13.5.2009, 21:07


--------------------
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: WinAPI и системное программирование"
Snowybartram
MetalFanbems
PoseidonRrader
Riply

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • 99% ответов по WinAPI можно найти в MSDN Library, оставшиеся 1% здесь

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, bartram, MetalFan, bems, Poseidon, Rrader, Riply.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: WinAPI и системное программирование | Следующая тема »


 




[ Время генерации скрипта: 0.0572 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.