![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Есть две программы, надо из одной в другую передать строку?
dracula © (2006-04-17 13:10:00)Допустим есть программа при запуске которой она определяет запущена её копия или нет, и если запущена то она должна передать содержимое командной строки первой копии. В первый раз столкнулся с такой проблемой, и незнаю в какую сторону копать? Плз. подскажите знающие люди. Заранее спасибо.
Dracula (2006-04-17 13:55:00) [1]Дмитрий Л. спасибо, твой код как раз то что надо, уже всё работает огромное СПАСИБО!
Дмитрий Л. (2006-04-17 13:45:00) [2]В [1], конечно, представлен не единственно возможный метод. Но в случае с Wm_CopyData основная проблема в том, не как передать данные, а кому. В данном случае сложно обойтись без именованных каналов, MMF или LPC, т.к. FindWindow не гарантирует верный результат, а EnumWindows+GetWindowThreadProcessId - не самое красивое решение, ибо цикл.
Dracula (2006-04-17 13:27:00) [3]Спасибо, сейчас буду пробовать...
Сергей М. (2006-04-17 13:27:00) [4]
> в какую сторону копать?
Если взаимодействующие программы используют GUI, то можно копнуть в сторону сообщений WM_COPYDATA.
В противном случае как альтернатива [1] - см. NamedPipes.
Dmitrij_K (2006-04-17 13:25:00) [5]WM_COPYDATA
TUser (2006-04-17 13:24:00) [6]Посмотри в сторону Wm_CopyData
Дмитрий Л. (2006-04-17 13:18:00) [7]дарю:
program Project1;
uses
windows,
SysUtils,
Forms,
Unit1 in 'Unit1.pas' {Form1};
{$R *.res}
var
InstExists: Boolean;
begin
NewInstMessageValue:=RegisterWindowMessage(Pchar(UniqueName+'msg'));
if NewInstMessageValue=0 then
RaiseLastOSError;
hSection:=CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE, 0, DATA_SIZE, Pchar(UniqueName+'map'));
if hSection=0 then
RaiseLastOSError();
InstExists:=GetLastError=ERROR_ALREADY_EXISTS;
try
lpCustomData:=MapViewOfFile(hSection, FILE_MAP_ALL_ACCESS, 0, 0, DATA_SIZE);
if lpCustomData=nil then
RaiseLastOSError;
if InstExists then
begin
if (ParamCount>0) and (Length(ParamStr(1))>0) then
CopyMemory(@(lpCustomData^.Buffer), @Paramstr(1)[1], Length(Paramstr(1)));
SendMessage(lpCustomData^.ClientHandle, NewInstMessageValue, GetCurrentProcessId, GetCurrentThreadId);
end
else
begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
ZeroMemory(lpCustomData, DATA_SIZE);
lpCustomData.ClientHandle:= Form1.Handle;
Application.Run;
end;
finally
if lpCustomData<>nil then
UnmapViewOfFile(lpCustomData);
CloseHandle(hSection);
end;
end.
////////////////////////////////////
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs;
type
TForm1 = class(TForm)
protected
procedure WndProc(var Message: TMessage); override;
private
{ Private declarations }
public
{ Public declarations }
end;
const
DATA_SIZE = 1024;
type
TCustomData = packed record
ClientHandle: THandle;
Buffer: array [0..DATA_SIZE-SizeOf(THandle)-1] of char;
end;
PCustomData = ^TCustomData;
const
UniqueName = 'AppNotificationNameSpace';
var
Form1: TForm1;
hSection: DWORD;
NewInstMessageValue: DWORD;
lpCustomData: PCustomData;
implementation
{$R *.dfm}
{ TForm1 }
procedure TForm1.WndProc(var Message: TMessage);
begin
inherited;
if Message.Msg=NewInstMessageValue then
begin
ShowMessage(Format('New instance running: PID: %d, TID: %d, Param: %s',
[Message.WParam, Message.LParam, Pchar(@(lpCustomData.Buffer))]));
ZeroMemory(@(lpCustomData^.Buffer), SizeOf(lpCustomData^.Buffer));
end;
end;
end.