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

Вниз

Повторный запуск программы   Найти похожие ветки 

 
Mishenka   (2006-11-28 11:20) [0]

Есть программа, которая висит в трее. Как сделать, чтоб при попытке её повторного запуска, она не запускалась второй раз, а просто всплывало её главное окно?


 
alex810 ©   (2006-11-28 11:53) [1]

Не знаю может подойдет. Могу еще накидать.


var
 MutexHandle: THandle;
var
 UniqueKey: string;

function IsNextInstance: BOOLEAN;
begin

 Result := FALSE;

 MutexHandle := 0;
 MutexHandle := CREATEMUTEX(nil, TRUE, UniqueKey);
 if MutexHandle <> 0 then
 begin
   if GetLastError = ERROR_ALREADY_EXISTS then
   begin
     Result := TRUE;
     CLOSEHANDLE(MutexHandle);
     MutexHandle := 0;
   end;
 end;
end;

begin

 CmdShow := SW_HIDE;
 MessageId := RegisterWindowMessage(zAppName);
 Application.Initialize;
 if IsNextInstance then
   PostMessage(HWND_BROADCAST, MessageId, 0, 0)
 else
 begin
   Application.ShowMainForm := FALSE;
   Application.CreateForm(TMainForm, MainForm);
   MainForm.StartTimer.Enabled := TRUE;
   Application.Run;
 end;
 if MutexHandle <> 0 then
   CLOSEHANDLE(MutexHandle);
end.



В MainForm  необходимо вставить обработчик внутреннего сообщения


procedure TMainForm.OnAppMessage(var M: TMSG; var Ret: BOOLEAN);
begin
 if M.Message = MessageId then
 begin
   Ret := TRUE;
   // Поместить окно наверх !!!!!!!!
 end;
end;

initialization
 ShowWindow(Application.Handle, SW_Hide);
end.





 
Сергей М. ©   (2006-11-28 11:58) [2]


> Как сделать, чтоб при попытке её повторного запуска, она
> не запускалась второй раз


Никак.


 
ЮЮ ©   (2006-11-28 11:59) [3]

a UniqueKey не мешало бы чего-нибудь действительно уникальное присвоить :)


 
Elen ©   (2006-11-28 12:00) [4]


>
>  [2] Сергей М. ©   (28.11.06 11:58)
>
> > Как сделать, чтоб при попытке её повторного запуска, она
>
> > не запускалась второй раз
>
>
> Никак.

Почему никак?


 
alex810 ©   (2006-11-28 12:01) [5]

Еще на запрет повторного запуска

program SlideShow;
Forms, Windows,
slide in "slide.pas1 {Forml};
80 Глава 4
I$R *.resl
var pbuff:array[O..127] of char; {буфер для текста)
var dWin: HWnd; {дескриптор!
var st:string; (вспомогательная строка)
begin
Application.Initialize;
Application.Title := "SlideShow1;
dWin:= GetWindow(Application.Handle, GW_HWNDFIRST);
while dWin <> 0 do
begin
if (dWin <> Application.Handle) and
{собственное окно игнорируем)
(GetWindow(dWin, GW_OWNER) = 0) and
{дочерние окна игнорируем)
(GetWindowText(dWin, pbuff, sizeof(pbuff)) <> 0)
{без названия игнорируем)
then
begin
GetWindowText(dWin, pbuff, sizeof(pbuff));
(получаем текст названия приложения)
st:-string(pbuff); {переводим его в строку)
if st="SlideShow1 then
begin
st:=""flBoe пернатых в одной клетке не живут." @А.Лебедь";
Application.MessageBox(Pchar(st),"",MB_OK);
(выводим предупреждение)
exit; {прерываем программу)
end;
end;
dWin:= GetWindow(dWin, GW_HWNDNEXT);
{ищем следующее приложение из списка)
end;
Application.CreateForm(TForml, Forml);
Application.Run;
end.



 
ЮЮ ©   (2006-11-28 12:02) [6]

Она же всё равно запустится. Только снимется сама же :)


 
Сергей М. ©   (2006-11-28 12:06) [7]


> Elen ©   (28.11.06 12:00) [4]


Потому что эта фича в лок.политиках безопасности не реализована. За очевидной ненадобностью.


 
Elen ©   (2006-11-28 12:08) [8]


> Mishenka

Порули вот такое :
program Project1;

uses
 Forms,
 windows,
 Unit1 in "Unit1.pas" {Form1};

var hMappedFile: THandle;

{$R *.res}

begin
 Application.Initialize;
 if OpenFileMapping(FILE_MAP_ALL_ACCESS,true,"SharedBlock")=0
 then begin
  hMappedFile:=CreateFileMapping ($FFFFFFFF, nil, PAGE_READWRITE,
0, 255, "SharedBlock");
  Application.CreateForm(TForm1, Form1);
 Application.Run;
 end else Application.MessageBox("sdfdf","adasd");
end.


Для разгону мысли ;) А в проекте можеш писать че угодно. Здесь вместо МессагеБокса можеш активить нужную форму, например хендель которой запихнеш в этот МапФайл


 
Elen ©   (2006-11-28 12:13) [9]


> Потому что эта фича в лок.политиках безопасности не реализована.
> За очевидной ненадобностью.

Причем здесь локальная политика? Автор спрашивает как написать такое. Не нужно автора вводить в заблуждение.!


 
Сергей М. ©   (2006-11-28 12:22) [10]


> Причем здесь локальная политика?



> Автор спрашивает как написать такое


"Такое" = "она не запускалась второй раз ..".

Где и как твоем коде (или в коде alex810) это достигается ?
Да нигде и никак).. Сколько раз юзер жмакнет на иконке, столько процессов и будет стартовано) ... см. [6] и не вводи автора в заблуждение)


 
Elen ©   (2006-11-28 12:27) [11]


> Где и как твоем коде (или в коде alex810) это достигается
> ?
> Да нигде и никак).. Сколько раз юзер жмакнет на иконке,
> столько процессов и будет стартовано) ... см. [6] и не вводи
> автора в заблуждение)

Это пустые придирки. Потом программа сама закроется. тем более что это один из возможных путей.
Автору нужно помогать советами а не смаковать его вопрос бессмысленно его критикуя


 
Сергей М. ©   (2006-11-28 12:35) [12]


> Потом программа сама закроется


Вот на этом и следовало в первую очередь заострить внимание автора.


> это один из возможных путей


Возможных путей для достижения чего ? "Незапуска" второго экз-ра ?) Или условного завершения уже стартовавшего второго экз-ра ?)


 
Elen ©   (2006-11-28 12:43) [13]


> Возможных путей для достижения чего ? "Незапуска" второго
> экз-ра ?) Или условного завершения уже стартовавшего второго
> экз-ра ?)

Какая разница. Автору нужно чтобы второй запушенный экземпляр передал управление первому, закрывшись. Поскольку автор задал вопрос в "начинающих" то и следовательно про запуск процессов он не знает много. К чему буквоедство в его вопросе? Если что он потом переспросит, а-то сразу - "никак", это ж нечестно.


 
Сергей М. ©   (2006-11-28 12:48) [14]


> это ж нечестно


У нас с тобой разное понимание "честности" по этому поводу)
Засим позволь считать дальнейшую дискуссию на эту тему лишенной смысла.


 
Anatoly Podgoretsky ©   (2006-11-28 14:48) [15]

> alex810  (28.11.2006 12:01:05)  [5]

Приведеный код не рабочий, по определению.


 
Array ©   (2006-11-28 14:57) [16]


> Mishenka   (28.11.06 11:20) 

проверять не запущена ли програма, если да то мереть
http://narod.yandex.ru/cgi-bin/yandsearch?user=delphiworld&text=%E7%E0%EF%F3%F1%EA+%EF%F0%EE%E3%F0%E0%EC%EC+%EA%EE%EF%E8%FF&where=2


 
Mishenka   (2006-11-29 16:05) [17]


> Array ©   (28.11.06 14:57) [16]
> проверять не запущена ли програма, если да то мереть

В принципе удалось заставить мереть вторую копию программы, но никак не разберусь, как заставить в этот момент всплыть из трея окно первой копии программы???


 
Array ©   (2006-11-29 16:09) [18]


> Mishenka   (29.11.06 16:05) [17]


мереть - в смысле умереть, очепятка знаете ли

на мютексе?
ну так кто мешает читать мютекс в первой копии програмы по тому же принцыпу
У Вас ведь один фаг =>  запущена одна копия програмы
второй флаг зделайте => была проведена попытка запуска второй копии проги... или же втора должна посылать в первую сообщение какое нить


 
Chuk &amp; Gek ©   (2006-11-29 21:44) [19]

program Project1;

uses
 Forms,Windows,
 Unit1 in "Unit1.pas" {Form1};

{$R *.RES}

var
hwin:HWND;

begin
hwin:=FindWindow("TForm1","Form1");
if hwin<>0 then
 begin
  SetForegroundWindow(hwin);
  Application.Terminate;
 end;

 Application.Initialize;
 Application.CreateForm(TForm1, Form1);
 Application.Run;
end.


 
MetalFan ©   (2006-11-29 22:44) [20]

> [19]
бред, а если в другой, абсолютно сторонней, программе также форма назвается?
в принципе до ума доведенное [1] покатит.


 
Mishenka   (2006-11-30 14:57) [21]


> Array ©   (29.11.06 16:09) [18]
> на мютексе?
> второй флаг зделайте => была проведена попытка запуска
> второй копии проги...

Что-то я так и не разобрался как это сделать :((


 
Mishenka   (2006-12-05 11:20) [22]

Отправляю сообщение из второй копии программы в первую

if not TryCreateMutex then
begin
  PrevWin := FindWindow("TfmMain", "fmMain");
  SendMessage(PrevWin, WM_MYMESSAGE, 0, 0);
end


обрабатываю его:

type
 TfmMain = class(TForm)
  .........
 procedure WMMymessage(var Message: TMessage); message WM_MYMESSAGE;
 ..........
procedure TfmMain.WMMymessage(var Message: TMessage);
begin
  RestoreMainForm;
end;

procedure TfmMain.RestoreMainForm;
var I, J: Integer;
begin
 Application.ShowMainForm := True;
 ShowWindow(Application.Handle, SW_RESTORE);
 ShowWindow(Application.MainForm.Handle, SW_RESTORE);
 if not ShownOnce then
 begin
   for I := 0 to Application.MainForm.ComponentCount - 1 do
     if Application.MainForm.Components[I] is TWinControl then
       with Application.MainForm.Components[I] as TWinControl do
       if Visible then
       begin
         ShowWindow(Handle, SW_SHOWDEFAULT);
         for J := 0 to ComponentCount - 1 do
           if Components[J] is TWinControl then
             ShowWindow((Components[J] as TWinControl).Handle, SW_SHOWDEFAULT);
       end;
   ShownOnce := True;
 end;
end;


Окно не всплывает, при том что функция RestoreMainForm работает нормально. Непонятно почему сообщение не отсылается, и окно не всплывает.


 
Elen ©   (2006-12-05 12:09) [23]


> Непонятно почему сообщение не отсылается, и окно не всплывает.

А ты проверь что возвращает  FindWindow("TfmMain", "fmMain");. Есть подозрение что там 0


 
Mishenka   (2006-12-05 13:40) [24]


> Elen ©   (05.12.06 12:09) [23]
> А ты проверь что возвращает  FindWindow("TfmMain", "fmMain"); Есть подозрение что там 0


Действительно 0. А как тогда правильно сделать?


 
Elen ©   (2006-12-05 14:05) [25]


> Mishenka

Например вместо того чтоб в трей запуздыривать закидывай форму за пределы экрана, а потом восстанавливай позицию. Тогда FindWindow Srabotayet.


 
Mishenka   (2006-12-05 15:16) [26]

А может надо куда-нибудь засунуть SetForegroundWindow?
Только пока не пойму куда...


 
Elen ©   (2006-12-05 15:39) [27]


> А может надо куда-нибудь засунуть SetForegroundWindow?

Куда б ты не "засунуть SetForegroundWindow" если в него передается 0 то ты и на экране получиш 0


 
Mishenka   (2006-12-05 15:43) [28]


> Elen ©   (05.12.06 15:39) [27]
> Куда б ты не "засунуть SetForegroundWindow" если в него передается 0 то ты и на экране получиш 0

В общем это верно. Но может всё-таки можно как-нибудь это сделать. как например это делает TotalCommander ?


 
Elen ©   (2006-12-05 15:59) [29]


> как например это делает TotalCommander ?

А как он делает?


 
term1t ©   (2006-12-05 17:41) [30]

как это раелизовать я не знаю (because too low skill :)), но это сделать можно 100%. Например Winamp, в нем есть опция "запускать больше 1 копии", если она отключена, то сколько не клацай - толку мало. И в процессах только 1 винамп.



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

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

Наверх




Память: 0.55 MB
Время: 0.045 c
15-1164800476
Quicker
2006-11-29 14:41
2006.12.24
Синтаксис .htaccess


15-1164688328
vajo
2006-11-28 07:32
2006.12.24
Саммит НАТО в Риге


2-1165396893
Roman_ln
2006-12-06 12:21
2006.12.24
Если в делфи процедуры работающие с датой?


15-1165248006
oldman
2006-12-04 19:00
2006.12.24
Наши опять взяли Кубок Девиса...


15-1165218074
Kolan
2006-12-04 10:41
2006.12.24
Два вопроса по BDS2006