Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.09.10;
Скачать: CL | DM;

Вниз

Обработка сообщения на закрытие приложение   Найти похожие ветки 

 
leonidus   (2010-01-13 01:06) [0]

Нужно реализовать корректную работу мой программы в случае если при ее запуске обнаружена ранее запущенная копия. В этом случае ранее запущенной копии нужно отправить сообщение на закрытие, а копия запущенная позже должна продолжать работать. Реализую поиск копии через атом, в который вместе с сигнатурой добавляю хендл запущенного приложения. Вторая копия находит сигнатуру, вычленяет хендл и отправляет сообщение wm_close_program, которое программа должна получить и закрыться осободив некие ресурсы.

Делаю так:

const
wm_close_program=wm_User+500;

type
 TForm1 = class(TForm)
 ...
 ...
 private
   { Private declarations }
 procedure WM_Close_Program_MSG(Var M : TMessage); message wm_Close_Program;
 public
   { Public declarations }
 end;

....
....

procedure TForm1.WM_Close_Program_MSG(Var M : TMessage);
begin
GlobalDeleteAtom(m.WParam);
application.Terminate;
end;

Суть проблемы в том, что если по хендлу, который я беру из атом отправить WM_CLOSE, то программа прекрасно закрывается, а вот сообщение wm_close_program она почему-то обработать не может. Я что не правильно его принимаю?


 
Игорь Шевченко ©   (2010-01-13 03:14) [1]


> а вот сообщение wm_close_program она почему-то обработать
> не может.


А если вставить после GlobalDeleteAtom(...)
слово Close ?


 
Leonid Troyanovsky ©   (2010-01-13 08:47) [2]


> leonidus   (13.01.10 01:06)  

> работать. Реализую поиск копии через атом

Плохая идея. Если процесс будет терминирован,
то атом будет жить  вплоть до логофа.

Лучше взять memory mapped file.

--
Regards, LVT.


 
Leonid Troyanovsky ©   (2010-01-13 09:02) [3]


> leonidus   (13.01.10 01:06)  

> с сигнатурой добавляю хендл запущенного приложения. Вторая
..
> не может. Я что не правильно его принимаю?

Если добавляется Application.Handle, то неправильно.

--
Regards, LVT.


 
leonidus   (2010-01-13 11:04) [4]

Вот так ищу атом:

var
P: PChar;
i,j: Word;
handle:integer;
begin
 GetMem(p, 256);
 for i := 0 to $FFFF do
 begin
   GlobalGetAtomName(i, p, 255);
   if StrPos(p, PChar("MyProgram_")) <> nil then
     begin
     handle:=strtoint(
     copy(p,ansipos("MyProgram_",p)+10,length(p))
     );
     PostMessage(handle, wm_Close_Program, i, 0);
     end;
 end;
 FreeMem(p);

Вот так записываю атом:
atom:="MyProgram_"+inttostr(application.Handle);
GlobalAddAtom(pchar(atom));

application.Handle то что нужно, ведь я могу по этому хендлу отправить wm_Close и программа закроется. на счет того, то атом в это случае будет жить вечно, с чего бы это? я отправляю сообщение PostMessage(handle, wm_Close_Program, i, 0); сожержащие номер найденного атома, а обработчик удалит его: GlobalDeleteAtom(m.WParam);. Другое дело, что обработчик то никак не может получить управление, вот и вопрос, почему?


 
Вариант   (2010-01-13 11:32) [5]


> leonidus   (13.01.10 11:04) [4]


> Другое дело, что обработчик то никак не может получить управление,
>  вот и вопрос, почему?

Form1.Handle <> Application.Handle

И согласен с [2] - атомы не лучший вариант.


 
leonidus   (2010-01-13 11:42) [6]

Ок, пусть будет MMF, но всеравно нужно разобраться с хендлом. Чтоже указывать в виде хендла приложения, чтобы можно было через PostMessage отправить собственное сообщение?


 
Вариант   (2010-01-13 11:53) [7]


> leonidus   (13.01.10 11:42) [6]

В твоем варианте речь не о приложении, а об окне.
У тебя обработчик в твоем примере принадлежит классу TForm1, значит нужен WND окна, которое является экземпляром класса TForm1.

А зачем посылать сообщение? И еще - а почему закрываем первую программу и оставляем работать вторую копию? (Я наоборот обычно делаю - проверяю, если прога уже запущена, то завершаю работу новой копии программы.)


 
Сергей М. ©   (2010-01-13 11:55) [8]


> Чтоже указывать в виде хендла приложения, чтобы можно было
> через PostMessage отправить собственное сообщение?


Ну ты же сам сказал


> application.Handle то что нужно, ведь я могу по этому хендлу
> отправить


Application.Handle - это хэндл главного окна VCL-приложения.
Оно невидимо, потому что его ширина и высота равны 0.


 
leonidus   (2010-01-13 13:18) [9]

Разобрался, большое спасибо!


 
Pashka.cool   (2010-05-11 11:18) [10]

Вот как я решал именно эту же проблему:
В главном модуле своего приложения с заголовком "program" перед строкой Application.Initialization вставляю следующий код:
var
 tmpStrList: TStringList;
 i: Integer;
 tmpAppName: String;
 flFound: Boolean;
begin
 tmpStrList := TStringList.Create;
 try
   FillApplicationsList(tmpStrList);
   tmpAppName := ExtractFileName(Application.ExeName);
   for i := 0 to tmpStrList.Count - 1 do
   begin
     if AnsiUpperCase(tmpStrList[i]) = AnsiUpperCase(tmpAppName) then
     begin
       MessageDlg("Ця програма вже працює!", mtWarning, [mbOk], 0);
       Exit; // выход происходит до инициализации приложения
    end;  
 finally
   tmpStrList.Free;
 end;
 Application.Initialize;
 Application.CreateForm(TfrmTenderMain, frmTenderMain);
 Application.Run;
end;



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

Текущий архив: 2015.09.10;
Скачать: CL | DM;

Наверх




Память: 0.5 MB
Время: 0.053 c
15-1413997019
Jeer
2014-10-22 20:56
2015.09.10
А мне, что-то вспомнилось..


4-1271754311
QAZ
2010-04-20 13:05
2015.09.10
FindFirstFileW и FindNextFileW


15-1411754239
aka
2014-09-26 21:57
2015.09.10
посоветуйте offline словарь на Андройд


2-1394781921
Alex_C
2014-03-14 11:25
2015.09.10
Своя отрисовка TMemo


3-1304514851
Leon-Z
2011-05-04 17:14
2015.09.10
DBLookupListBox &amp; DBLookupComboBox.