![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как активировать уже запущенную копию приложения? [D6, WinXP]
novice__man © (2005-01-22 19:45:00)В общем дело обстоит так:
Мне нужно, что бы было невозможно запустить вторую копию приложения, что в принципе сделано. Вот только хотелось бы что бы при этом событии уже запущенная копия приложения дала о себе знать (либо помигала кнопкой в панеле задачь, либо вышла на передний план), в общем пользователь увидел, что приложение уже работает и вот оно!
Eraser (2005-01-28 15:24:00) [21]novice__man
Установи пакет компонентов JVCL, там есть компонент который отлично справляется с твоей задачей. Проверено.
alpet (2005-01-27 17:43:00) [22]>Просто SetForegroundWindow не сработает, если вызывать из неактивного экземпляра.
Надо перед этим вызвать AttachThreadInput, тогда обязательно сработает.
GrayFace (2005-01-27 17:36:00) [23]novice__man (27.01.05 16:17) [12]
Понял, исправлюсь, в этот момент нет еще главной формы приложения.
Я, кажется, тоже понял. Этот код - в OnCreate, а в другом месте ты делаешь MainForm.Close? Или это в .dpr до Application.CreateForm-ов?
novice__man (2005-01-27 16:17:00) [24]GrayFace © (27.01.05 16:11) [11]
Application.ShowMainForm := False;
????
Понял, исправлюсь, в этот момент нет еще главной формы приложения.
Еще надо создавать, например, атом, чтобы узнать, запущено ли приложение.
Атом создан раньше, это только индикация об уже запущенном приложении.
GrayFace (2005-01-27 16:11:00) [25]novice__man (26.01.05 17:41) [10]
Еще надо создавать, например, атом, чтобы узнать, запущено ли приложение.
novice__man (26.01.05 17:41) [10]
Application.ShowMainForm := False;
????
novice__man (2005-01-26 17:41:00) [26]
var
PrevCopy: DWORD;
begin
Application.ShowMainForm := False;
PrevCopy := BSM_APPLICATIONS;
BroadCastSystemMessage(BSF_IGNORECURRENTTASK or SF_POSTMESSAGE, @PrevCopy, MessageID, 0, 0);
end;
А так можно?
Gero (2005-01-26 17:27:00) [27]
> Только ненадо пожалуста ерунды с окнами, всеравно работать
> небудет!
> repeat
> AppWnd := FindWindowEx(0, AppWnd, 'TApplication',
> PChar(UnicName));
> until AppWnd <> Application.Handle;
> if AppWnd <> 0 then
> begin
> if IsIconic(AppWnd) then
> ShowWindow(AppWnd, SW_Restore)
> else
> SetForegroundWindow(AppWnd);
> end;
А что это за ерунда с окнами?
GrayFace (2005-01-26 17:26:00) [28]GrayFace © (26.01.05 17:25) [7]
Хотя, там, похоже есть один глюк.
Нет. Это я проглючил.
GrayFace (2005-01-26 17:25:00) [29]Помигать кнопкой в панеле задачь- FlashWindow.
Можно просто использовать TELInstanceChecker из Extension Lib. Хотя, там, похоже есть один глюк.
Erik1 © (24.01.05 11:39) [5]
Только ненадо пожалуста ерунды с окнами, всеравно работать небудет!
Будет, только криво.
Erik1 © (24.01.05 11:39) [5]
GetMem(ObjName, Length(UnicName) + 1);
try
StrCopy(ObjName, UnicName);
Handle := CreateMutex(nil, true, ObjName);
finally
FreeMem(ObjName);
end;
А не лучше лиvar s:string; s:=UnicName;? (как я понял из кода, CreateMutex требует не Readonly строку) На всякий случай можноSetString(s, UnicName, length(UnicName));
Erik1 © (24.01.05 11:39) [5]
AppWnd := 0;
repeat
AppWnd := FindWindowEx(0, AppWnd, 'TApplication', PChar(UnicName));
until AppWnd <> Application.Handle;
Как я понимаю, Application.Title должен быть равен UnicName? Тогда все это теряет смысл.
Eraser © (24.01.05 12:33) [6]
Просто SetForegroundWindow не сработает, если вызывать из неактивного экземпляра.
Eraser (2005-01-24 12:33:00) [30]Настаиваю на своём мнении, что нужно передовать своё (пользовательское) сообщение.
Что вы например будете делать, если новую копию приложения запустят с параметром, в котором указывается, например, имя файла, который нужно открыть. Можно конечно на это наплевать, но все серьёзные программы открывают файл (см. MSWord, Delphi). Для этого посылается сообщение главному экземпляру приложения с этим параметром.
Надеюсь не сильно путанное объяснение ;-)
Erik1 (2005-01-24 11:39:00) [31]Только ненадо пожалуста ерунды с окнами, всеравно работать небудет!
var
ObjName: PChar;
Handle: THandle;
AppWnd: HWnd;
IsTerm: boolean;
const
UnicName = 'Starvara';
Duplicate = 'duplicate';
begin
DateSeparator := '.';
IsTerm := IsTerminal;
if not FindCmdLineSwitch(Duplicate, ['-', '/'], true) and not IsTerm then
begin
GetMem(ObjName, Length(UnicName) + 1);
try
StrCopy(ObjName, UnicName);
Handle := CreateMutex(nil, true, ObjName);
finally
FreeMem(ObjName);
end;
if ((Handle <> 0) and (getLastError() = ERROR_ALREADY_EXISTS)) then
begin
AppWnd := 0;
repeat
AppWnd := FindWindowEx(0, AppWnd, 'TApplication', PChar(UnicName));
until AppWnd <> Application.Handle;
if AppWnd <> 0 then
begin
if IsIconic(AppWnd) then
ShowWindow(AppWnd, SW_Restore)
else
SetForegroundWindow(AppWnd);
end;
Halt;
end;
end; {isTerm}
Просто Джо (2005-01-23 03:17:00) [32]
SetForegroundWindow(H);?
Leonid Troyanovsky (2005-01-23 02:54:00) [33]
> vertal © (23.01.05 02:28) [2]
> Если в вашем приложении все время существует какое-то окно,
> то можно по SetForegroundWindow(FindWindow(YourWndClass,
> YourWndName))
Это надо делать не c самим окном, а с окном приложения,
т.е. wnd := HWND(GetWindowLong(wnd, GWL_HWNDPARENT)).
Ну, а окно главной формы всегда существует.
Если, конечно, приложение не бесформенное ;)
--
Regards, LVT.
vertal (2005-01-23 02:28:00) [34]Если в вашем приложении все время существует какое-то окно, то можно по SetForegroundWindow(FindWindow(YourWndClass, YourWndName))
Eraser (2005-01-22 20:18:00) [35]Один из способов. Отсылка сообщения уже запущеному приложению, которое оповещает о запуске его второй копии.