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

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

Вернуться   Форум программистов > IT форум > Помощь студентам
Регистрация

Восстановить пароль

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

Ответ
 
Опции темы Поиск в этой теме
Старый 27.08.2009, 15:11   #1
Ronder
Пользователь
 
Регистрация: 14.07.2009
Сообщений: 28
По умолчанию Проблемы с SendMessage

Хочу передать текст из одной программы в другую. Получаю хэндл второй программы, передаю текст:

Код:
var
  win: Thandle;
  text: PChar;

begin
  text := 'hello!';
  win := FindWindow(nil, 'Prog2');
  SendMessage(win, MY_MESSAGE, 0, DWORD(PChar(text)) );
Вторая программа получает сообщение с помощью процедуры:
Код:
procedure MessageReceiver(var msg: TMessage); message MY_MESSAGE;

procedure TForm1.MessageReceiver(var msg: TMessage);
 var
   txt: PChar;
 begin
   txt := PChar(msg.lParam);
   msg.Result := 1;
   ShowMessage(txt);
 end;
В итоге, вторая программа получает сообщение в непонятно виде. Что я делаю неправильно?
Ronder вне форума Ответить с цитированием
Старый 27.08.2009, 16:27   #2
JTG
я получил эту роль
Старожил
 
Аватар для JTG
 
Регистрация: 25.05.2007
Сообщений: 3,694
По умолчанию

Код:
var
  win: Thandle;
  txt: PChar;
begin
  txt := PChar(string('hello!'));
  win := FindWindow(nil, 'Form1');
  SendMessage(win, WM_USER+х, 0, dword(txt));
Код:
procedure MessageReceiver(var msg: TMessage); message WM_USER+x;

procedure TForm1.MessageReceiver(var msg: TMessage);
var
   txt: PChar;
begin
   //привет, переполнение буффера :)
   txt := pchar(ptr(msg.lParam));
   ShowMessage(StrPas(txt));
end;
По-хорошему надо явно выделить память через GlobalAlloc и проверять чего и сколько пришло в MessageReceiver
пыщь

Последний раз редактировалось JTG; 27.08.2009 в 16:41.
JTG вне форума Ответить с цитированием
Старый 27.08.2009, 18:04   #3
Ronder
Пользователь
 
Регистрация: 14.07.2009
Сообщений: 28
По умолчанию

Вот что пришло в Form1, вместо 'hello!':

Ronder вне форума Ответить с цитированием
Старый 27.08.2009, 18:57   #4
0nni
Форумчанин
 
Аватар для 0nni
 
Регистрация: 24.07.2008
Сообщений: 279
По умолчанию

Такое лучше делать через WM_COPYDATA
Сказал и загрустил от бесспорности своей правоты.
0nni вне форума Ответить с цитированием
Старый 27.08.2009, 21:12   #5
AndreyMust19
Пользователь
 
Регистрация: 01.03.2009
Сообщений: 31
По умолчанию

JTG
Цитата:
//привет, переполнение буффера
Какое переполнение буфера? Здесь буфера никакого нет! То что ты показал в примере - работает правильно. Дело в другом.

Программы выполняются в разных адресных пространствах. Если вы передаете другой программе указатель на строку из другой программы, то в ней этой строки не будет. Строка, к-ю вы хотите передать - существует только в АП первого процесса. В АП второго процесса по тому же адресу ее нет.

Передавать надо так (один вариант из 3-х):
1) Передавать через lParam и wParam сами символы строки по 8 штук (четыре символа на один параметр).
2) Пусть 2-ой процесс выделит в АП блок памяти и передаст первому процессу его адресу. Тот запишет нужные данные в этот блок.
3) А вообще обмен данными между процессами реализуется с помощью разделяемой памяти (Shared Memory). Чтобы оба процесса не читали и не писали в нее данные одновременно, используйте синхронизацию с помощью событий, сообщений или семафоров (один процесс ждет, когда другой разрешить писать / читать).

Последний раз редактировалось AndreyMust19; 27.08.2009 в 21:17.
AndreyMust19 вне форума Ответить с цитированием
Старый 27.08.2009, 21:40   #6
0nni
Форумчанин
 
Аватар для 0nni
 
Регистрация: 24.07.2008
Сообщений: 279
По умолчанию

Код:
procedure TcdServerForm.Button1Click(Sender: TObject);
var
  pStr : PChar;
  len : Integer;
  ClientWnd : HWND;
  CopyDataStr : TCopyDataStruct;
begin
  len := Length(Edit1.Text);
  pStr := PChar(Edit1.Text);



  ClientWnd := FindWindow('TcdClientForm', nil);
  CopyDataStr.dwData := 0;//размер данных для 64-x
  CopyDataStr.cbData := (len + 1) {* 2 }; //Размер для 32-x. Двойка для юникода
  CopyDataStr.lpData := pStr;//Указатель на данные
  SendMessage(ClientWnd, WM_COPYDATA, Handle, Integer(@CopyDataStr));
end;

Код:
type
  TcdClientForm = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure wmcopydata(var msg : TWMCopyData); message WM_COPYDATA;
  end;

...

procedure TcdClientForm.wmcopydata(var msg: TWMCopyData);
var
  pstr : PChar;
begin

  pstr := pChar(msg.CopyDataStruct.lpData);
  Caption := pstr;
end;
Сказал и загрустил от бесспорности своей правоты.
0nni вне форума Ответить с цитированием
Старый 27.08.2009, 22:06   #7
Ronder
Пользователь
 
Регистрация: 14.07.2009
Сообщений: 28
По умолчанию

Всем спасибо за помощь!
Ronder вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Параметры SendMessage Jenya Win Api 4 11.12.2010 19:15
Как подружить SendMessage и TIdHTTP zcoder Работа с сетью в Delphi 1 13.04.2009 06:01
Не работает SendMessage MaTBeu Win Api 6 01.10.2008 19:00
Как принять сообщение (SendMessage) Crazyman Win Api 4 20.02.2008 04:42