Вниз
Скачать: CL | DM;

Как из второго экземпляра программы послать первому сообщение?...   Найти похожие ветки 

← →
Dinara ©   (2002-07-31 23:29) [0]

... просто о том, что второй экземпляр запущен?


← →
Странный Прохожий ©   (2002-07-31 23:41) [1]

Можно создать именованый Mutex.
Второй экземпляр при запуске может проверять его наличие/отсутствие.


← →
VID ©   (2002-07-31 23:45) [2]

Примитивный вариант:

Т.к. речь идёт фактически об одной и той же программе, то можно сделать так:
в папке расположения проги создать подпапку и файл:
.../MSG/Message.TXT

Программа отслеживает изменения (запись) файлов в папке MSG
Как только поступил сигнал об изменения какого-нибудь файла в папке MSG, программа читает первые две строки файла Message.txt

А теперь реализация сабжа:
В необходимый момент вторая копия проги записывает в файл, message.txt две строки:
1 - Application.Handle
2 - Строку сообщения

Сразу же , ОБЕ проги обнаружив изменение файла, прочтут его первые две строки. Пусть S1 - первая строка, а S2 - вторая.

И сделают проверку:
IF StrTOInt(S1)<>Application.Handle then
begin
//необходимые действия, связанные с сообщением S2
end;

В результате, одна прога (копия), ничего не сделает (т.к. Application.Handle = S1), а первая - выполнит необх. действия.

Всё.


← →
Странный Прохожий ©   (2002-07-31 23:47) [3]

Mutex лучше :o)


← →
VID ©   (2002-07-31 23:52) [4]

Кстати, после прочтения файла Message.txt и выполнения указанных действия, программа, выполнившая действия, должна ОЧИСТИТЬ ФАЙЛ Message.txt, т.е. удалить обе строки.
Этим достигается большая стабильность работы программы, т.к. если содержимое файла не будут очищено, а пользователь вручную откорректирует этот файл, и отменив свои корректировки, сохранит этот файл, то одна из программ, снова выполнит действия, связанные с сообщеним второй строки.

Это конечно всё маловероятно, но возможно.


← →
VID ©   (2002-07-31 23:54) [5]

Зато "Примитивный вариант" позволяет посылать разные сообщения от одной копии другой, что расширяет сферу приминения этого метода...

:)


← →
nick_sniper ©   (2002-08-01 00:05) [6]

Можно использовать модуль VCLutils из RxLib. Там есть такие прекрасные функции, как:

function FindPrevInstance(const MainFormClass, ATitle: string): HWnd;
function ActivatePrevInstance(const MainFormClass, ATitle: string): Boolean;

И сделать что-то типа:
wnd := FindPrevInstance(...);
if wnd <> 0 then begin
PostMessage(wnd,...);
Application.Terminate; // Если нужен только один экземпляр программы
end;


← →
Dinara ©   (2002-08-01 00:25) [7]

nick_sniper, можно поподробнее - куда что пихать?

Суть в чем - запускается первая копия, работает. Потом вторую запускают с параметром. Она кое-что делает, потом обнаруживает мьютекс и завершается. И надо как-нибудь сделать так, чтобы первый экземпляр узнал о том, что второй кое-что сделал.

Какой час уже с этим мучаюсь :(((


← →
DenKop ©   (2002-08-01 01:24) [8]

Я делал это примерно так:

function VerCopyProg:Boolean;
VAR
Wnd : hWnd;
buff: ARRAY [0..127] OF Char;
begin
Result:=False;
Wnd := 1;
WHILE Wnd <> 0 DO
BEGIN
IF (Wnd <> Application.Handle) AND
(IsWindowVisible(Wnd)or False) AND
((GetWindow(Wnd, gw_Owner) = 0)or False) AND
(GetWindowText(Wnd, buff, sizeof(buff)) <> 0)
THEN
BEGIN
GetWindowText(Wnd, buff, sizeof(buff));
if StrPas(buff)="Здесь Caption гдавной формы" then
begin Result:=True;Exit;end;
END;
Wnd := GetWindow(Wnd, gw_hWndNext);
END;
end;

Если программа уже запущена функция вернёт True.


← →
DenKop ©   (2002-08-01 01:26) [9]

Упустил самое главное, в твоём случае вместо строк
begin Result:=True;Exit;end; вставляешь PostMessage(Wnd,Своё_сообщение);


← →
nick_sniper ©   (2002-08-01 02:43) [10]

Извини за большой код, но:
Unit1:

unit Unit1;

interface

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

type
TMyMainForm = class(TForm)
BitBtn1: TBitBtn;
Label1: TLabel;
Label2: TLabel;
procedure BitBtn1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
procedure DefaultHandler(var Message); override;
end;

var
MyMainForm: TMyMainForm;

var
FirstProgram : Boolean;
ActivePrograms : Integer;
WM_ProgActivate : Cardinal;
WM_ProgDeactivate : Cardinal;

procedure CheckActive;

implementation

{$R *.DFM}

procedure CheckActive;
const
MessText1 : PChar = "WM_ProgActivate";
MessText2 : PChar = "WM_ProgDeactivate";
begin
ActivePrograms := 0;
WM_ProgActivate := RegisterWindowMessage(MessText1);
WM_ProgDeactivate := RegisterWindowMessage(MessText2);
if (FindPrevInstance(TMyMainForm.ClassName,"MyMainForm") <> 0) then begin
FirstProgram := False;
SendMessage(HWND_BROADCAST,WM_ProgActivate,0,0); //



Страницы: 1 вся ветка

Скачать: CL | DM;



Память: 0.48 MB
Время: 0.014 c
3-47922
Vern
2002-07-23 09:10
2002.08.15
Проблемы с SQL


1-48129
Ильдар
2002-07-31 11:03
2002.08.15
Многострочный caption


14-48319
Alexandr
2002-07-11 12:43
2002.08.15
Блондинка за рулем


1-48176
galik
2002-08-02 15:35
2002.08.15
Express QuantumGrid?


1-48145
DeBuGeR
2002-07-31 20:05
2002.08.15
Баг в дельфи?




   Наверх