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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Приём сообщения, посланного через SendMessage 
:(
    Опции темы
Micher
Дата 6.10.2008, 16:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 13.1.2006
Где: г. Ижевск

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



День добрый. У меня такая ситуация. Есть 2 приложения, написанные НЕ на делфи, но они импортируют DLL на делфи. Приложения получают данные через интернет. Первое приложение, получив определённую информацию, должна послать данные 2-му приложению(например какую-то строку). Написал в DLL такую функцию для отправки сообщения посредством SendMessage:

Код

Function SendMes(): integer; export; stdcall;
var
  pril: hWnd;
  aCopyData: TCopyDataStruct;
 begin
   with aCopyData do
    begin
     dwData := 0;
     cbData := StrLen(PChar('Ot ulibki stanet vsem svetley!')) + 1;
     lpData := PChar('Ot ulibki stanet vsem svetley!')
    end;
   pril:= FindWindow(nil, 'ЗАГОЛОВОК ПРИЛОЖЕНИЯ, К-МУ ОТСЫЛАЕСТЯ СООБЩЕНИЕ');
   if pril <> 0 then
    begin
      SendMessage(pril, WM_COPYDATA, 0, Longint(@aCopyData));
      SendMes:=1;
    end else SendMes:=0;
 end;


Теперь, не могу понять, как принять те данные(в частности строку) вторым приложением? Нужна функция, которая бы возвращала именно эти данные. Нашёл в инете примерно такой код:

Код

type
   TForm1 = class(TForm)
     private
     procedure WMCopyData(var Msg: TWMCopyData); message WM_COPYDATA;
   public
   end;
procedure TForm1.WMCopyData(var Msg: TWMCopyData);
 var
   sText: array[0..99] of Char;
 begin
   // generate text from parameter
  StrLCopy(sText, Msg.CopyDataStruct.lpData, Msg.CopyDataStruct.cbData);
   // write received text
  ShowMessage(sText);
 end;


Помогите написать функцию для DLL, в делфи очень слабо разбираюсь, к сожалению
PM MAIL   Вверх
Romikgy
Дата 7.10.2008, 13:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

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



нужно имено через сендмессаге?


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Poseidon
Дата 7.10.2008, 15:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Delphi developer
****


Профиль
Группа: Комодератор
Сообщений: 5273
Регистрация: 4.2.2005
Где: Гомель, Беларусь

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



Micher, сообщения посылаются окнам! Самой программе ничего не посылается, если у нее нет окна. Поэтому, если хочешь передавать текст от одной библиотеки другой, то сообщения использовать не получится, т.к. в библиотеках нет окон (конечно, можно запихнуть, но зачем?). Пробуй другие варианты. Мьютексы или симафоры.


--------------------
Если хочешь, что бы что-то работало - используй написанное, 
если хочешь что-то понять - пиши сам...
PM MAIL ICQ   Вверх
Rennigth
Дата 7.10.2008, 15:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Poseidon @  7.10.2008,  15:28 Найти цитируемый пост)
Самой программе ничего не посылается, если у нее нет окна.

 smile  ну эт ты зря smile По сути сообщения посылаються потоку... и послать сообщение можно и без оконному приложению через PostThreadMessage. Другой вопрос будет ли поток обрабатывать сообщение.


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Micher
Дата 7.10.2008, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 13.1.2006
Где: г. Ижевск

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



Цитата(Romikgy @ 7.10.2008,  13:37)
нужно имено через сендмессаге?

Рассмотрю другие варианты smile

Добавлено @ 17:06
Цитата(Poseidon @ 7.10.2008,  15:28)
Micher, сообщения посылаются окнам! Самой программе ничего не посылается, если у нее нет окна. Поэтому, если хочешь передавать текст от одной библиотеки другой, то сообщения использовать не получится, т.к. в библиотеках нет окон (конечно, можно запихнуть, но зачем?). Пробуй другие варианты. Мьютексы или симафоры.

Вы недопоняли. Есть 2 приложения(которые работают в отдельных окнах), оба они написаны не на делфи, но оба подключают одну и ту же DLL, написанную на делфи как раз. 1 приложение, получив данные извне, должно как то сообщить что-либо второму приложению - например, послать ту же строку, ну или набор чисел. Т.е. нужно написать в этой DLL грубо говоря 2 функции:
1) функция типа sendData() - отправить данные
2) функция типа receivedata() - получить данные

1 приложение вызывает sendData() , а второе как то должно принять, то что посылает ему первое. И обе функции будут в DLL

Это сообщение отредактировал(а) Micher - 7.10.2008, 17:09
PM MAIL   Вверх
Rennigth
Дата 7.10.2008, 17:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Micher, по сабжу. что мешает из dll узнать хендл принимающего сообщения окна, и подменить ему с помощью SetWindowLong процедуру обработки сообщений?

п.с. завтра накидаю примерчик, сейчас нет ни возможности, ни мозгов, ни желания :(


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Micher
Дата 7.10.2008, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 13.1.2006
Где: г. Ижевск

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



Цитата(Rennigth @ 7.10.2008,  17:36)
Micher, по сабжу. что мешает из dll узнать хендл принимающего сообщения окна, и подменить ему с помощью SetWindowLong процедуру обработки сообщений?

п.с. завтра накидаю примерчик, сейчас нет ни возможности, ни мозгов, ни желания :(

Можно отсюда поподробнее? smile
PM MAIL   Вверх
Rennigth
Дата 8.10.2008, 16:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


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

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



Цитата(Micher @  7.10.2008,  19:25 Найти цитируемый пост)
Можно отсюда поподробнее?  

Можно. Завтра/После завтра. Болею...


--------------------
(* Honesta mors turpi vita potior *)
PM MAIL ICQ   Вверх
Romikgy
Дата 8.10.2008, 20:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Любитель-программер
****


Профиль
Группа: Участник Клуба
Сообщений: 7326
Регистрация: 11.5.2005
Где: Porto Franco Odes sa

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



имхо можно юзать filemapping , udp, pipe .... можно заюзать атомы ,
для твоих уелей наверное первое самое оптимальное


--------------------
Владение русской орфографией это как владение кунг-фу — истинные мастера не применяют его без надобности. 
smile

PM   Вверх
Micher
Дата 12.10.2008, 08:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 13.1.2006
Где: г. Ижевск

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



Цитата(Romikgy @ 8.10.2008,  20:50)
имхо можно юзать filemapping , udp, pipe .... можно заюзать атомы ,
для твоих уелей наверное первое самое оптимальное

Нашёл в инете пример по работе с FileMapping:
Код

unit Main;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
    StdCtrls, Buttons, ExtCtrls;

type
  TForm1 = class(TForm)
    edVariable: TEdit;
    lbEnterValues: TLabel;
    bbOK: TBitBtn;
    bbExit: TBitBtn;
    lbShowValue: TLabel;
    lbVariable: TLabel;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure bbExitClick(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure bbOKClick(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;
  //глобальные переменные
  hFileMapObj: THandle; //описатель FaleMapping
  lpBaseAddress: PChar; //"указатель" (см. выше) на начальный адрес данных
implementation

{$R *.DFM}

procedure TForm1.FormCreate(Sender: TObject);
begin
  //создадим FileMapping с именем MySharedValue
  //и передадим его хэндл в глобальную переменную hFileMapObj
  hFileMapObj := CreateFileMapping(MAXDWORD, nil, PAGE_READWRITE, 0, 4,
    'MySharedValue');
  if (hFileMapObj = 0) then
    //ошибочка вышла
    ShowMessage('Не могу создать FileMapping!')
  else
    //подключим FileMapping к адресному пространству
    //и получим начальный адрес данных
    lpBaseAddress := MapViewOfFile(hFileMapObj, FILE_MAP_WRITE, 0, 0, 0);
  if lpBaseAddress = nil then
    //ошибочка вышла
    ShowMessage('Не могу подключить FileMapping!');
end;

procedure TForm1.bbExitClick(Sender: TObject);
begin
  //закроем форму
  Close;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
  //кое-что надо сделать при закрытии формы:
  //отключим FileMapping от адресного пространства
  UnMapViewOfFile(lpBaseAddress);
  //освободим объект FileMapping
  CloseHandle(hFileMapObj);
  //теперь форму можно закрыть
  Action := caFree;
end;

procedure TForm1.bbOKClick(Sender: TObject);
begin
  //поместим в адресное пространство свои данные
  //переменная типа PChar имеет в конце завершающий #0, значит при считывании данных
  //система сама сможет определить, где находится конец нужных данных
  StrPCopy(lpBaseAddress, edVariable.Text);
end;

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  //считаем нужные данные, обратившись по начальному адресу
  //данных адресного пространства FileMapping
  lbVariable.Caption := PChar(lpBaseAddress);
end;

end.


Вопросов возникло немало: а как из другого приложения читать то, что пишет первая. Нужно ли, чтобы обе программы работали одновременно ? У меня планируется, что 2 приложения будут работать в течение долгого времени - несколько часов(в бесконечных циклах). Т.е. они оба будут работать беспрерывно. Но как всё таки читать вторым приложением то что пишет первое, не понимаю. Как получить доступ к той области, куда пишет первое.... по идентификатору какому-то(заранее оговоренному?) ? Было бы здорово получить пример  smile . Заранее спасибо за любой ответ
PM MAIL   Вверх
bems
Дата 12.10.2008, 16:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



Цитата(Micher @  12.10.2008,  08:39 Найти цитируемый пост)
по идентификатору какому-то(заранее оговоренному?) ?
да, это у тебя 'MySharedValue'

создаешь файлмаппинг с одинаковым именем в обеих программах и на практике первая программа его создаст, а вторая только откроет. MapViewOfFile в разных процессах вернет (в общем случае) разное значение, но обе области гарантировано имеют одинаковое содержимое в обоих процессах. В одном пишешь в область, начинающуюся с lpBaseAddress, в другом читаешь. Только наверное нужно еще как-то передавать сигнал о том что данные записаны и пора перечитать. Для этой цели можно использовать эвент или мютекс.


--------------------
Обижено школьников: 8
PM MAIL   Вверх
Micher
Дата 12.10.2008, 20:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 13.1.2006
Где: г. Ижевск

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



Цитата(bems @ 12.10.2008,  16:52)
Только наверное нужно еще как-то передавать сигнал о том что данные записаны и пора перечитать. Для этой цели можно использовать эвент или мютекс.

Спасибо за ответ! Сигнал подавать не придётся, так как оба приложения фактически в бесконечных циклах будут читать/писать в маппинг.
А вопрос, если первое приложение(которое создало маппинг) завершит свою работу, то маппинг будет ещё доступен второму приложению или память под маппинг очистится?
PM MAIL   Вверх
bems
Дата 13.10.2008, 15:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



Цитата(Micher @  12.10.2008,  20:24 Найти цитируемый пост)
Сигнал подавать не придётся, так как оба приложения фактически в бесконечных циклах будут читать/писать в маппинг.
тогда нужно предотвратить одновремменные запись и чтение (мютексом) а то можно прочитать что-то записаное на половину


Цитата(Micher @  12.10.2008,  20:24 Найти цитируемый пост)
если первое приложение(которое создало маппинг) завершит свою работу, то маппинг будет ещё доступен второму приложению или память под маппинг очистится? 
файлмаппинг это объект ядра, а они уничтожаются когда закрывается последний хэндл. 
Цитата(Micher @  12.10.2008,  08:39 Найти цитируемый пост)
hFileMapObj := CreateFileMapping

тут ты получаеш хэндл. Если этот код вызывается из двух процессов то имеем уже два хэндла
Цитата(Micher @  12.10.2008,  08:39 Найти цитируемый пост)
lpBaseAddress := MapViewOfFile(hFileMapObj

тут создается неявный хэндл (еще один) на тот же файлмаппинг. Неявный потому что lpBaseAddress это не хэндл, а указатель. Неявный хэндл закрывается при вызове UnmapViewOfFile. Это тоже выполняется в двух процессах, итого имеем 4 хэндла на один объект. Если ты закроешь в одном процессе все его хэндлы на объект (две штуки) или тупо крашнеш программу (при этом винда сама закроет все хэндлы принадлежащие умирающему процессу) то останется еще два хэндла на объект (принадлежащие другому процессу) и объект будет благополучно существовать, пока счётчик хэндлов не станет 0 



--------------------
Обижено школьников: 8
PM MAIL   Вверх
Micher
Дата 13.10.2008, 17:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 129
Регистрация: 13.1.2006
Где: г. Ижевск

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



Цитата(bems @ 13.10.2008,  15:39)
тогда нужно предотвратить одновремменные запись и чтение (мютексом) а то можно прочитать что-то записаное на половину

Стыдно спросить, но что есть мютекс? И как использовать его чтобы предотвратить одновременную запись и чтение?
PM MAIL   Вверх
bems
Дата 13.10.2008, 18:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

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



Цитата(Micher @  13.10.2008,  17:52 Найти цитируемый пост)
что есть мютекс? И как использовать его чтобы предотвратить одновременную запись и чтение? 
это еще один объект ядра, он служит для эксклюзивного доступа к ресурсам.
Еще до любой записи или чтения (там же где ты вызывашь CreateFileMapping) нужно сделать 
Код

hReadWriteMutex:=CreateMutex(nil,false,'UniqueMutexName');

а чтение и запись так:
Код

WaitForSingleObject(hReadWriteMutex,INFINITE);
try
//тут запись в одном процессе и чтение в другом
finally
 ReleaseMutex(hReadWriteMutex);
end;


кстати имена своих файлмаппинга и мютекса сделай какими-то сильно длинными и уникальными, чтобы случайно не пересечся с чьей-то чужой прогой


--------------------
Обижено школьников: 8
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "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.1820 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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