![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как активировать уже запущенную копию приложения? [D6, WinXP]
novice__man © (2005-01-22 19:45:00)В общем дело обстоит так:
Мне нужно, что бы было невозможно запустить вторую копию приложения, что в принципе сделано. Вот только хотелось бы что бы при этом событии уже запущенная копия приложения дала о себе знать (либо помигала кнопкой в панеле задачь, либо вышла на передний план), в общем пользователь увидел, что приложение уже работает и вот оно!
Владислав (2005-02-01 19:06:00) [1]Забыл...
Две глобальные переменные:
G_LPFirstCopyInfo: PFirstCopyInfo = nil;
G_ActivateAnotherCopyMsg: Cardinal = 0;
Владислав (2005-02-01 19:03:00) [2]Вот еще вариант.
PFirstCopyInfo = ^TFirstCopyInfo;
TFirstCopyInfo = record
Window: HWND
end;
//*****************
const
G_FirstCopyMapSize = SizeOf(TFirstCopyInfo);
var
G_HFirstCopyMap: Cardinal = 0;
function AnotherCopyExists: Boolean;
begin
G_HFirstCopyMap :=
CreateFileMapping(INVALID_HANDLE_VALUE, nil, PAGE_READWRITE or SEC_COMMIT,
0, G_FirstCopyMapSize, G_SFirstCopyMapName);
Result := GetLastError = ERROR_ALREADY_EXISTS;
if G_HFirstCopyMap = 0 then
Exit;
G_LPFirstCopyInfo :=
MapViewOfFile(G_HFirstCopyMap, FILE_MAP_WRITE, 0, 0, G_FirstCopyMapSize);
G_ActivateAnotherCopyMsg := RegisterWindowMessage(G_ActivateAnotherCopyMsgName)
end;
procedure CloseFirstCopyInfo;
begin
if G_LPFirstCopyInfo <> nil then
begin
UnmapViewOfFile(G_LPFirstCopyInfo);
G_LPFirstCopyInfo := nil
end;
if G_HFirstCopyMap <> 0 then
begin
CloseHandle(G_HFirstCopyMap);
G_HFirstCopyMap := 0
end
end;
begin
if AnotherCopyExists then
begin
if G_LPFirstCopyInfo <> nil then
begin
with G_LPFirstCopyInfo^ do
if (Window <> 0) and (G_ActivateAnotherCopyMsg <> 0) then
PostMessage(Window, G_ActivateAnotherCopyMsg, 0, 0)
end;
CloseFirstCopyInfo;
Exit
end;
Application.Initialize;
Application.ShowMainForm := False;
Application.CreateForm(TdmMain, dmMain);
Application.CreateForm(TfrmMain, frmMain);
Application.Run;
CloseFirstCopyInfo
end.
GrayFace (2005-02-01 17:21:00) [3]Но ведь имя приложения - штука не очень уникальная. А зачем Mutex, если все-равно окна ищутся?
Erik1 (2005-02-01 12:22:00) [4]Вобщето я использовал мьютекс для определения запущена прошрамма или нет, а далее едет работа с окнами потому, что точно известно о старете другой копии. Поэтому работа с окнами на данном этапе совершенно безопасна. А то что UnicName = названию окна, так это мне удобнее, поскольку объект Applecation еще не нинициализирован.
remb (2005-01-31 21:22:00) [5]http://i-s-v.org.ua/
программа QLoader 1.4
GrayFace (2005-01-31 19:58:00) [6]Георгий Бедный (30.01.05 17:34) [29]
Можно использовать TELInstanceChecker из Extension Lib. Он с исходниками - можно и посмотреть, как это там делается.
Георгий Бедный (2005-01-30 17:34:00) [7]Круто. Только непонятки со списком файлов (как, например, в Винампе).
novice_man (2005-01-30 05:51:00) [8]GrayFace © (30.01.05 05:21) [27]
В принципе Вы правы и HALT здесь особой роли не играет.
GrayFace (2005-01-30 05:21:00) [9]Георгий Бедный (29.01.05 13:17) [26]
Ну, это даже я знаю! :) Halt - это значит не запускать приложение. :lol:
Нет. Halt - это значит завершить приложение. А зачем завершать приложение, если на следующей строчке, скорее всего, стоит "end." и оно все-равно завершится?
Георгий Бедный (2005-01-29 13:17:00) [10]Ну, это даже я знаю! :) Halt - это значит не запускать приложение. :lol:
Дайте мне, плиз, пример отправки-приёма сообщения предыдущей копии программы (например, когда я через системное меню винды открываю этой прогой сразу несколько файлов, она должна составить себе лист из них, т. е. все по сути командлайны стекаются в виде отфутболенных сообщений самой первой копии приложения, и она их группирует в список)!
GrayFace (2005-01-29 04:35:00) [11]alpet (27.01.05 17:43) [14], vertal © (28.01.05 22:46) [23]
Сэнкс.
novice_man © (28.01.05 16:03) [18]
if CheckPrevCopy then
Application.Initialize;
Application.Title := 'my_project';
Application.CreateForm(TForm, Form1);
Application.Run;
end else Halt;
А зачем Halt?
Johnmen (2005-01-29 03:49:00) [12]>novice_man ©
Примерно так:
const
StartEvent: string= 'MySuperPuperProgramm';
procedure ActivateOldInstance;
var
FoundWindow, FoundPopup : THandle;
begin;
try;
FoundWindow:=FindWindow(nil,PChar(AppTitle));
if FoundWindow<>0 then begin;
FoundPopup:=GetLastActivePopup(FoundWindow);
if IsIconic(FoundWindow) then ShowWindow(FoundWindow,SW_RESTORE);
BringWindowToTop(FoundWindow);
SetForegroundWindow(FoundWindow);
if FoundPopup<>0 then begin;
if IsIconic(FoundPopup) then ShowWindow(FoundPopup,SW_RESTORE);
BringWindowToTop(FoundPopup);
SetForegroundWindow(FoundPopup);
end;
end;
except end;
end;
begin;
SetLastError(0);
CreateEvent(nil,true,true,PChar(StartEvent));
if GetLastError<>0 then ActivateOldInstance
else begin;
....
vertal (2005-01-28 22:46:00) [13]> GrayFace © (27.01.05 16:11) [11]
> Еще надо создавать, например, атом, чтобы узнать, запущено ли
приложение.
Я бы так делать не стал, так как при нештатном завершении приложения этот атом не уничтожается системой и соотв. при сбое юзер больше не сможет запустить ваше приложение в текущем сеансе работы с Win, если оно будет проверять существование своей предыдущей копии по наличию атома. А мьютекс удаляется автоматически.
novice_man (2005-01-28 19:06:00) [14]Eraser © (28.01.05 16:45) [20]
Модет тут то и пригодится отсылка сообщения предидущей копии программы?
Георгий Бедный (2005-01-28 18:58:00) [15]А как заставить прогу прочитать командную строку (ParamStr) другой копии приложения??
Eraser (2005-01-28 16:45:00) [16]novice_man ©
Безусловно, сделать код который определяет вторую копию и делает её активной не сложно. Проблемы возникнут при передачи параметров запуска второй копии.
novice_man (2005-01-28 16:06:00) [17]Eraser © (28.01.05 15:24) [15]
novice__man
Установи пакет компонентов JVCL, там есть компонент который отлично справляется с твоей задачей. Проверено.
Спасибо за предложение. Но у меня все работает, спасибо интернету :), бездна информации.
А насчет дополнительных компонентов, то мне не очень нравится их использовать в своих проектах, но как справочная информация и пример реализации (если конечно они с исходниками) они мне подходят.
GrayFace © (27.01.05 17:36) [13]
Я вызываю функцию проверки в модуле project.dpr
if CheckPrevCopy then
Application.Initialize;
Application.Title := 'my_project';
Application.CreateForm(TForm, Form1);
Application.Run;
end else Halt;
может сдесь и не все правильно, но пока я только до этого дошел, может со временем все прийдется пересмотреть.
novice_man (2005-01-28 16:03:00) [18]Eraser © (28.01.05 15:24) [15]
novice__man
Установи пакет компонентов JVCL, там есть компонент который отлично справляется с твоей задачей. Проверено.
Спасибо за предложение. Но у меня все работает, спасибо интернету :), бездна информации.
А насчет дополнительных компонентов, то мне не очень нравится их использовать в своих проектах, но как справочная информация и пример реализации (если конечно они с исходниками) они мне подходят.
GrayFace © (27.01.05 17:36) [13]
Я вызываю функцию проверки в модуле project.dpr
if CheckPrevCopy then
Application.Initialize;
Application.Title := 'my_project';
Application.CreateForm(TForm, Form1);
Application.Run;
end else Halt;
может сдесь и не все правильно, но пока я только до этого дошел, может со временем все прийдется пересмотреть.
Eraser (2005-01-28 15:39:00) [19]novice__man
Установи пакет компонентов JVCL, там есть компонент который отлично справляется с твоей задачей. Проверено.
Eraser (2005-01-28 15:39:00) [20]novice__man
Установи пакет компонентов JVCL, там есть компонент который отлично справляется с твоей задачей. Проверено.