Форум: "Основная";
Текущий архив: 2002.08.15;
Скачать: [xml.tar.bz2];
ВнизКак из второго экземпляра программы послать первому сообщение?... Найти похожие ветки
← →
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 вся ветка
Форум: "Основная";
Текущий архив: 2002.08.15;
Скачать: [xml.tar.bz2];
Память: 0.47 MB
Время: 0.006 c