Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Вторая копия приложения в CodeGear


Автор: Urvin 30.1.2008, 17:12
Мне необходимо сделать защиту от запуска второй копии приложения.
При попытке запуска появляется ранее запущенная копия.
Всегда пользовался и был рад следующему коду:
Код

procedure TfrmMain.FormCreate(Sender: TObject);
var 
  Wnd: hWnd;
  buff : ARRAY[0.. 127] OF Char;
begin
  Wnd := GetWindow(Handle, gw_HWndFirst);
  WHILE Wnd <> 0 DO
  begin
    IF (Wnd <> Application.Handle) AND (GetWindow(Wnd, gw_Owner) = 0) THEN
      begin GetWindowText (Wnd, buff, sizeof (buff ));
        IF StrPas (buff) = Application.Title THEN
          begin
           SetForegroundWindow(wnd);
           ShowWindow(wnd,SW_SHOWNORMAL);
           Halt;
          end;
      end;
    Wnd := GetWindow (Wnd, gw_hWndNext);
  end;
end;


Но с удивлением обнаружил, что в CodeGear данная конструкция не работает.
Не ругется, руками не машет, но позволяет запустить несколько копий приложения.

Я в панике. подскажите, что сделать?

Автор: Snowy 30.1.2008, 17:28
Потому что в 2007 изменена концепция главного окна.
Теперь оным является не Application, а главная форма.
Вот её хэндл и ищи.

Автор: Alexeis 30.1.2008, 17:31
Urvin, потому что в 2007 версии отделили окно приложения, от окна главной формы, теперь это разные окна. 
GetWindow(Handle, gw_HWndFirst); - теперь неверно, можно попробовать GetWindow(Application.Handle, gw_HWndFirst);

Добавлено через 42 секунды
упс. опередил smile 

Автор: Urvin 30.1.2008, 17:36
простите, но... можно как для дебилов?  smile 

Автор: Rohoss 30.1.2008, 19:21
Цитата(Snowy @  30.1.2008,  17:28 Найти цитируемый пост)
Потому что в 2007 изменена концепция главного окна.

В 2006 тоже?

Автор: Esperito 30.1.2008, 19:25
Рекомендую мьютекс.

Автор: Urvin 30.1.2008, 21:15
Самый рабочий код с мьютексами, как ни странно, оказался наименее замороченным.
Действительно, вторая копия приложения не стартует.

Код

program Project1;

uses
  Forms,
  Windows, // не забудьте эту строчку
  Unit1 in 'Unit1.pas' {Form1};

  {$R *.RES}

var
  HM: THandle;
function Check: boolean;
begin
  HM := OpenMutex(MUTEX_ALL_ACCESS, false, 'MyOwnMutex');
  Result := (HM <> 0);
  if HM = 0 then
    HM := CreateMutex(nil, false, 'MyOwnMutex');
end;

begin
  if Check then
    Exit;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.



Как можно изменить данный код, чтобы на экран показывалась предыдущая работающая копия программы? smile

Автор: VICTAR 30.1.2008, 22:57
Найти нужное окно FindWindow и поместить его на передний план SetForegroundWindow

Добавлено через 5 минут и 5 секунд
Впрочем, в твоем первом посте все есть

Автор: Urvin 1.2.2008, 20:26
я все же не справляюсь  smile 

Автор: Qu1nt 2.2.2008, 13:10
Код

program Project1;

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

{$R *.res}

function Check: Boolean;
var
  HM : THandle;
begin
  HM := OpenMutex(MUTEX_ALL_ACCESS, False, 'MyOwnMutex');
  Result := (HM <> 0);
  if HM = 0 then
    HM := CreateMutex(nil, False, 'MyOwnMutex');
end;

procedure Active;
var
  Wnd  : hWnd;
  Buff : array[0..127] of Char;
begin
  Wnd := GetWindow(Application.Handle, gw_HWndFirst);
  while Wnd <> 0 do
  begin
    if (Wnd <> Application.Handle) and (GetWindow(Wnd, gw_Owner) = 0) then
    begin
      GetWindowText(Wnd, Buff, SizeOf(Buff));
      if StrPas(Buff) = Application.Title then
      begin
        SetForegroundWindow(Wnd);
        ShowWindow(Wnd, SW_SHOWNORMAL);
        Halt;
      end;
    end;
    Wnd := GetWindow(Wnd, gw_hWndNext);
  end;
end;

begin
  if Check then
    Active;
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
end.

Ы?

Автор: Urvin 2.2.2008, 13:31
Qu1nt,  твой пример не показывает форму в том случае, если она была свернута.





только что справился по иной технологии, взятой на
http://www.delphikingdom.com/asp/viewitem.asp?catalogid=904

Сильно урезал-доподрезал и вот что получил:
http://urvin.ifolder.ru/5196756
Нашел ошибочку ;) исправляем на
Код

procedure TForm1.WMCommandArrived(var Message: TMessage);
begin
  Application.Restore;
  SetForeGroundWindow(Application.Handle);
  ShowWindow(Form1.Handle, SW_SHOW);
end;


 smile 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)