![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Обработка сообщения на закрытие приложение [D6, WinXP]
leonidus © (2010-01-13 01:06:00)Нужно реализовать корректную работу мой программы в случае если при ее запуске обнаружена ранее запущенная копия. В этом случае ранее запущенной копии нужно отправить сообщение на закрытие, а копия запущенная позже должна продолжать работать. Реализую поиск копии через атом, в который вместе с сигнатурой добавляю хендл запущенного приложения. Вторая копия находит сигнатуру, вычленяет хендл и отправляет сообщение 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 она почему-то обработать не может. Я что не правильно его принимаю?
Pashka.cool (2010-05-11 11:18:00) [1]Вот как я решал именно эту же проблему:
В главном модуле своего приложения с заголовком "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;
leonidus (2010-01-13 13:18:00) [2]Разобрался, большое спасибо!
Сергей М. (2010-01-13 11:55:00) [3]
> Чтоже указывать в виде хендла приложения, чтобы можно было
> через PostMessage отправить собственное сообщение?
Ну ты же сам сказал
> application.Handle то что нужно, ведь я могу по этому хендлу
> отправить
Application.Handle - это хэндл главного окна VCL-приложения.
Оно невидимо, потому что его ширина и высота равны 0.
Вариант (2010-01-13 11:53:00) [4]
> leonidus (13.01.10 11:42) [6]
В твоем варианте речь не о приложении, а об окне.
У тебя обработчик в твоем примере принадлежит классу TForm1, значит нужен WND окна, которое является экземпляром класса TForm1.
А зачем посылать сообщение? И еще - а почему закрываем первую программу и оставляем работать вторую копию? (Я наоборот обычно делаю - проверяю, если прога уже запущена, то завершаю работу новой копии программы.)
leonidus (2010-01-13 11:42:00) [5]Ок, пусть будет MMF, но всеравно нужно разобраться с хендлом. Чтоже указывать в виде хендла приложения, чтобы можно было через PostMessage отправить собственное сообщение?
Вариант (2010-01-13 11:32:00) [6]
> leonidus (13.01.10 11:04) [4]
> Другое дело, что обработчик то никак не может получить управление,
> вот и вопрос, почему?
Form1.Handle <> Application.Handle
И согласен с [2] - атомы не лучший вариант.
leonidus (2010-01-13 11:04:00) [7]Вот так ищу атом:
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);. Другое дело, что обработчик то никак не может получить управление, вот и вопрос, почему?
Leonid Troyanovsky (2010-01-13 09:02:00) [8]
> leonidus (13.01.10 01:06)
> с сигнатурой добавляю хендл запущенного приложения. Вторая
..
> не может. Я что не правильно его принимаю?
Если добавляется Application.Handle, то неправильно.
--
Regards, LVT.
Leonid Troyanovsky (2010-01-13 08:47:00) [9]
> leonidus (13.01.10 01:06)
> работать. Реализую поиск копии через атом
Плохая идея. Если процесс будет терминирован,
то атом будет жить вплоть до логофа.
Лучше взять memory mapped file.
--
Regards, LVT.
Игорь Шевченко (2010-01-13 03:14:00) [10]
> а вот сообщение wm_close_program она почему-то обработать
> не может.
А если вставить после GlobalDeleteAtom(...)
слово Close ?