Текущий архив: 2005.10.23;
Скачать: CL | DM;
ВнизПередача данных из одного приложения в другое Найти похожие ветки
← →
Pasha L (2005-08-05 19:22) [0]Вопрос: можно ли из одного приложения в другое передать данные не создавая для этого временного файла? (D6 WinXP)
← →
Ega23 © (2005-08-05 19:55) [1]Удалено модератором
← →
Alexander Panov © (2005-08-05 20:03) [2]В зависимости от типа данных есть и разные методы передачи.
Какого типа данные интересуют?
← →
Андрей Молчанов (2005-08-05 20:07) [3]http://subsimple.com/delphi.asp, InterAppComm
← →
Eraser © (2005-08-05 21:51) [4]Pasha L (05.08.05 19:22)
Советую покопать в сторону MailSlots.
← →
3DxFantastika © (2005-08-05 22:15) [5]Сокеты .. лучшее и универсальное решение!
← →
y-soft © (2005-08-05 22:26) [6]Способов много
← →
Pasha L (2005-08-06 01:42) [7]Я хочу передать несколько строк из одного приложения в другое. Я мог бы из одного приложения вывести эти строки в файл, а из другого - прочитать файл. А потом файл удалить. Но уверен, что есть более рациональный способ.
//Андрей Молчанов (05.08.05 20:07) [3]
Хотелось бы выполнить задачу стандартными "инструментами"
//y-soft © (05.08.05 22:26) [6]
Расскажите о каком-нибудь поподробнее.
← →
Джо © (2005-08-06 02:38) [8]В случае нескольких строк, по-моему, нет нужды городить огород. Воспользуйся посылкой сообщения WM_COPYDATA.
Примерчик.
В первом приложении делаешь такую оболочку для посылки:
procedure SendString (AHandle: THandle; const AString: string);
var
Data: COPYDATASTRUCT;
begin
Data.dwData := 0;
Data.cbData := Length(AString);
Data.lpData := PChar(AString);
SendMessage(AHandle,WM_COPYDATA,0,Integer(@Data))
end;
Посылаешь строку вот так
SendString (H,"Hello!");
где H - хэндл нужного окна во втором приложении. Например, получаешь его при помощи FindWindow.
---
Во втором приложении в нужной форме объявляешь метод, получающий управление при приходе сообщения WM_COPYDATA:
TForm1 = class(TForm)
private
procedure WmCopyData (var Message: TMessage); message WM_COPYDATA;
...
implementation
...
procedure TForm1.WmCopyData(var Message: TMessage);
begin
ShowMessage (DecodeData(Message));
Message.Result := 1
end;
И пишешь функцию-оболочку для выдирания текста:
function DecodeData (Msg: TMessage): string;
var
Data: COPYDATASTRUCT;
begin
Data := PCopyDataStruct (Msg.LParam)^;
Result := PChar(Data.lpData);
SetLength(Result,Data.cbData);
end;
Здесь есть несколько нюансов, о которых ты можешь прочесть в MSDN или Справке из Platform SDK по сообщению WM_COPYDATA. Один из них в том, что первая программа не получит управления до тех пор, пока вторая не обработает сообщение, так как используется SendMessage, а не PostMessage. В общем, читай, разбирайся...
← →
y-soft © (2005-08-06 09:15) [9]>Pasha L (06.08.05 01:42) [7]
Расскажите о каком-нибудь поподробнее
В принципе, наверное, проще всего сделать, как в [8]. Тонкости неплохо описаны у Рихтера. Только здесь есть один не совсем приятный нюанс - приложение должно знать хендл окна получателя. Да и синхронный характер SendMessage не всегда удобен
Так же довольно несложно использовать MailSlots или Pipes, немного сложнее - сокеты...
Можно использовать и упомянутый Вами способ с использованием промежуточного файла, но в его качестве лучше использовать объект FileMapping и, возможно, позаботится о синхронизации...
В общем-то никто не запрещает использовать и технологию COM, но в реализации это будет значительно сложнее, особенно, если свяжетесь с маршалингом. Да и скорость будет не слишком высокой...
Ну и напоследок можно упомянуть о такой экзотике, как DDE...
Примеров не привожу из-за объемности материала, но их множество в MSDN...
← →
palva © (2005-08-06 22:57) [10]Можно так: Обе программы по функции RegisterWindowMessage получают идентификатор сообщения. Система гарантирует, что этот идентификатор будет уникальным (не будет мешать другим программам) и будет одним и тем же, если программы при обращении к функции зададут один и тот же строковый параметр. А потом одна программа посылает широковещательное PostMessage (с первым параметром HWND_BROADCAST) а вторая выбирает его из своей очереди по GetMessage/PeekMessage. Насколько я понимаю, вторая программа должна иметь главное окно.
← →
Leonid Troyanovsky © (2005-08-06 23:11) [11]
> Джо © (06.08.05 02:38) [8]
> function DecodeData (Msg: TMessage): string;
> var
> Data: COPYDATASTRUCT;
> begin
> Data := PCopyDataStruct (Msg.LParam)^;
> Result := PChar(Data.lpData);
> SetLength(Result,Data.cbData);
IMHO, Data must be PCOPYDATASTRUCT, а установление SetLength
после присвоения особого смысла не имеет, т.к., если
там уже есть #0, он все и ограничит.
--
Regards, LVT.
← →
GuAV © (2005-08-06 23:32) [12]
> IMHO, Data must be PCOPYDATASTRUCT
Там и так указатель на COPYDATASTRUCT.
>а установление SetLength
>после присвоения особого смысла не имеет, т.к., если
> там уже есть #0, он все и ограничит.
Эт правда, тем более, что исходя изData.cbData := Length(AString);
там этого #0 нету, поэтому возможно AV.
Прaвильно - черезSetString
.
← →
Маг Похмеляйнен (2005-08-07 00:11) [13]Надёжней через именованный file mapping object.
← →
GuAV © (2005-08-07 00:49) [14]Маг Похмеляйнен (07.08.05 0:11) [13]
Чем это надёжнее WM_COPYDATA ?
← →
Leonid Troyanovsky © (2005-08-07 09:54) [15]
> GuAV © (06.08.05 23:32) [12]
> > IMHO, Data must be PCOPYDATASTRUCT
> Там и так указатель на COPYDATASTRUCT.
Где там?
--
Regards, LVT.
← →
Leonid Troyanovsky © (2005-08-07 10:14) [16]
> Маг Похмеляйнен (07.08.05 00:11) [13]
> Надёжней через именованный file mapping object.
WM_COPYDATA передается через MMF (неименованный), создаваемый системой.
Дополнительный бонус - синхронизация с принимающим потоком.
--
Regards, LVT.
← →
Маг Похмеляйнен (2005-08-07 10:58) [17]О, это общеизвестно.
Однако:
1) Нужно знать хэндл окна, которому посылаем данные. Неудобно. Некрасиво.
2) Данные структурированные, большого объёма. Каждый раз придётся паковать их в буферок, отдавать системе (PostMessage(WM_COPYDATA...)), система делает мап,.... ДОлго.
3) На вкус и цвет... :o)
← →
Leonid Troyanovsky © (2005-08-07 11:00) [18]
> Маг Похмеляйнен (07.08.05 10:58) [17]
> придётся паковать их в буферок, отдавать системе (PostMessage(WM_COPYDATA...)),
Только не Post.
--
Regards, LVT.
← →
Маг Похмеляйнен (2005-08-07 11:17) [19]Да, действительно, через PostMessage это сделать заморочно.
Вот ещё один недостаток WM_COPYDATA.
:o)
← →
y-soft © (2005-08-07 11:50) [20]>palva © (06.08.05 22:57) [10]
С передачей строк при таком способе возникнут заморочки. Это же не WM_COPYDATA
Придется использовать что-то типа FileMapping, а тогда можно обойтись вообще без посылки сообщений, а использовать события Windows для уведомления (или вообще таймер) + мьютекс для синхронизации (при односторонней связи необязателен), тогда и наличие окна необязательно...
P.S. IMHO по простоте реализации и универсальности очень удобны каналы (Pipes) - не надо думать о синхронизации и сразу можно установить режим чтения/записи сообщений...
← →
забыл (2005-08-07 18:13) [21]сокеты не дело - ибо файрик ругнется (даже не смотря на 127.0.0.1, ибо порт открыли, данные передаются) - юзверя спугнете...
майлслоты мне показались не сильно приятными =)
пайпы - отличное решение, как и WM_COPYDATA. сам использую последнее чаще всего.
DDE - вполне разумно
← →
Alexander Panov © (2005-08-07 18:17) [22]Маг Похмеляйнен (07.08.05 11:17) [19]
Вот ещё один недостаток WM_COPYDATA.
Можно привести первый недостаток?
← →
Alexander Panov © (2005-08-07 18:23) [23]см. высказывания.
Маг Похмеляйнен (07.08.05 0:11) [13]
Надёжней через именованный file mapping object.
Leonid Troyanovsky © (07.08.05 10:14) [16]
WM_COPYDATA передается через MMF (неименованный), создаваемый системой.
Дополнительный бонус - синхронизация с принимающим потоком.
Маг Похмеляйнен (07.08.05 10:58) [17]
О, это общеизвестно.
Однако:
1) Нужно знать хэндл окна, которому посылаем данные. Неудобно. Некрасиво.
2) Данные структурированные, большого объёма. Каждый раз придётся паковать их в буферок, отдавать системе (PostMessage(WM_COPYDATA...)), система делает мап,.... ДОлго.
3) На вкус и цвет... :o)
1 решается простым Broadcast-сообщением.
2 а для именованный file mapping object это не нужно, как я понимаю?
3. Только не надо подменять объективные характеристики своими пристрастиями.
← →
3DxFantastika © (2005-08-07 18:28) [24]забыл (07.08.05 18:13) [21]
> сокеты не дело - ибо файрик ругнется
это так, но сокеты идеальны если в будующем планируется выполнение программ на разных компьютерах - проблемы уже не будет, сокеты универсальны и позволяют передавать данные в любую точку Интернета (TCP протокол)
← →
Alexander Panov © (2005-08-07 18:31) [25]3DxFantastika © (07.08.05 18:28) [24]
Один из недостатков сокетов - скорость, которая несравнима по сравнению с остальными методами.
Кроме того, на компьютере может не быть вообще установленных стеков протоколов, потому метод не может быть гарантированно применимым.
← →
y-soft © (2005-08-07 18:52) [26]>Alexander Panov © (07.08.05 18:31) [25]
Один из недостатков сокетов - скорость, которая несравнима по сравнению с остальными методами
При реализации Named Pipe"ов Windows для связи обычно использует как раз сокеты, и только если они недоступны, использует другие способы :)
← →
Pasha L © (2005-08-16 18:04) [27]Джо © (06.08.05 02:38) [8]
Воспользовался вашим способом, только вот одно не понял. Процедура wmcopydata для того чтобы "вывести наружу" полученное послание, так вроде. А что надо указывать при вызывании этой процедуры на месте аргементаvar Message: TMessage
? Буду очень признателен, если объясните.
← →
Игорь Шевченко © (2005-08-16 18:40) [28]y-soft © (07.08.05 18:52) [26]
> При реализации Named Pipe"ов Windows для связи обычно использует
> как раз сокеты
При реализации Named Pipes Windows использует объекты File, как ни странно, и сетевой редиректор, если Pipe проложен между разными компьютерами. А какой транспортный протокол будет работать - это уже несущественно :)
← →
Slym © (2005-08-17 05:08) [29]IPC в демосах - очень популярно расписано
← →
alpet © (2005-08-17 09:12) [30]Resume:
Если производительность не важна - WM_COPYDATA (как наиболее простое), если важна - FileMapping (одну секцию можно использовать многократно, а при небольшом размере данные возможно не будут покидать кэш L1).
← →
Pasha L © (2005-08-17 12:18) [31]Спасибо, но свободно я говорю только по-русски :-)
← →
alpet © (2005-08-17 12:49) [32]Pasha L © (17.08.05 12:18) [31]
Это намек, на то что все английские термины нужно перевести, и снабдить описанием? Увольте сэр, это форум программистов, а не первоклассников. Проекции файлов, и сообщения достаточно простые по себе, но если уж хочется на родном языке почитать, рекомендую найти книгу "Windows для профессионалов" Дж. Рихтера, в ней все прекрасно расписано.
← →
Игорь Шевченко © (2005-08-17 14:42) [33]Pasha L © (17.08.05 12:18) [31]
> Спасибо, но свободно я говорю только по-русски :-)
Это ведь вряд ли проблемы отвечающих ?
← →
Pasha L © (2005-08-17 16:46) [34]Ясно короче что ничего не ясно
← →
alpet © (2005-08-17 17:01) [35]Pasha L © (17.08.05 16:46) [34]
Ну как не ясно. Для того чтобы понимать и читать на русском языке надо выучить его сначала (несколько классов начальной школы). То же самое и с программированием, дабы понимать теминологию и предлагаемые решения, нужно освоить азы. Чтобы стать Windows программистом, по форумам вопросы отнюдь недостаточно задавать, надо еще и книги по теме читать. Одну книгу я уже тебе указал, если не хочешь купить бумажную, наверняка в сети где-нибудь выложена.
← →
Lin7 © (2005-08-17 17:28) [36]
> наверняка в сети где-нибудь выложена
Например здесь: http://alexsoft.home.nov.ru/download/prog/
> Pasha L ©
Почитай, очень полезно - ответишь сам на свой вопрос, причём несколькими способами.
← →
SpyBoy © (2005-08-21 21:43) [37]На http://sources.ru/delphi/sendkeys.zip лежит компонент, описание такое:
Посылаем нажатия клавиш другому приложению.
Автор: Gert v.d. Venis
Скачайте компонент Sendkeys
Описание:
Данный компонент получает хэндл(handle) любого запущенного окна и даёт возможность отправить по указанному хэндлу любые комбинации нажатия клавиш.
Совместимость: Все версии Delphi
Собственно сам исходничек:
После того, как проинсталируете этот компонент, создайте новое приложение и поместите на форму кнопку и сам компонент SendKeys. Добавьте следующий код в обработчик события OnClick кнопки:
procedure TForm1.Button1Click(Sender: TObject);
begin
// Запускаем Notepad, и ему мы будем посылать нажатия клавиш
WinExec("NotePad.exe", SW_SHOW);
// В параметре процедуры GetWindowHandle помещаем
// текст заголовка окна Notepad"а.
SendKeys1.GetWindowHandle("Untitled - Notepad");
// Если хэндл окна получен успешно, то отправляем ему текст
if SendKeys1.WindowHandle <> 0 then
SendKeys1.SendKeys("This is a test");
// Так же можно отправить код любой кнопки типа
// RETURN, используя следующий код:
// SendKeys1.SendKeys(Chr(13));
end;
---------------------------------
Неправда ли весело :)
← →
Defunct © (2005-08-22 03:43) [38]SpyBoy © (21.08.05 21:43) [37]
дурь какая-то.
если в компоненте есть процедура с названием ничинающимся со слова GET, то место такого "компонента" на помойке.
← →
Defunct © (2005-08-22 03:51) [39]Pasha L © (16.08.05 18:04) [27]
Процедура wmcopydata для того чтобы "вывести наружу" полученное послание, так вроде.
да, но это Джо непраильно ее назвал. Она должна называться например "ObrabotchikWmCopyData" или "WMCopyDataHandler".
WM_COPYDATA это не процедура. это сообщение Windows.
> А что надо указывать при вызывании этой процедуры на месте аргемента var Message: TMessage?
ее не нужно вызывать, она будет сама вызываться, когда окну придет вышеуказанное сообщение.
ps: сорри если повторил чей-то ответ.
← →
Джо © (2005-08-22 04:00) [40]
> [39] Defunct © (22.08.05 03:51)
> да, но это Джо непраильно ее назвал. Она должна называться
> например "ObrabotchikWmCopyData" или "WMCopyDataHandler".
Всего лишь стараюсь придерживаться стандарта Борланд.
Ср.:
TCustomForm = class(TScrollingWinControl)
private
...
procedure WMPaint(var Message: TWMPaint); message WM_PAINT;
procedure WMEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ERASEBKGND;
procedure WMIconEraseBkgnd(var Message: TWMEraseBkgnd); message WM_ICONERASEBKGND;
procedure WMQueryDragIcon(var Message: TWMQueryDragIcon); message WM_QUERYDRAGICON;
...
Страницы: 1 2 вся ветка
Текущий архив: 2005.10.23;
Скачать: CL | DM;
Память: 0.56 MB
Время: 0.055 c