Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как из второго экземпляра программы послать первому сообщение?... [D6, Win2k]


Dinara ©   (2002-07-31 23:29:00) 

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


nick_sniper   (2002-08-01 02:43:00) [1]

Извини за большой код, но:
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); //


DenKop   (2002-08-01 01:26:00) [2]

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


DenKop   (2002-08-01 01:24:00) [3]

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

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.


Dinara   (2002-08-01 00:25:00) [4]

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

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

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


nick_sniper   (2002-08-01 00:05:00) [5]

Можно использовать модуль 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;


VID   (2002-07-31 23:54:00) [6]

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

:)


VID   (2002-07-31 23:52:00) [7]

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

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


Странный Прохожий   (2002-07-31 23:47:00) [8]

Mutex лучше :o)


VID   (2002-07-31 23:45:00) [9]

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

Т.к. речь идёт фактически об одной и той же программе, то можно сделать так:
в папке расположения проги создать подпапку и файл:
.../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:41:00) [10]

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


Наверх

Титульная страница Поиск, карта сайта Написать письмо