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