Недавно добавленные исходники

•  DeLiKaTeS Tetris (Тетрис)  4 069

•  TDictionary Custom Sort  6 169

•  Fast Watermark Sources  5 964

•  3D Designer  8 847

•  Sik Screen Capture  6 308

•  Patch Maker  6 719

•  Айболит (remote control)  6 713

•  ListBox Drag & Drop  5 571

•  Доска для игры Реверси  95 909

•  Графические эффекты  6 934

•  Рисование по маске  6 179

•  Перетаскивание изображений  5 099

•  Canvas Drawing  5 470

•  Рисование Луны  5 181

•  Поворот изображения  4 722

•  Рисование стержней  3 336

•  Paint on Shape  2 575

•  Генератор кроссвордов  3 474

•  Головоломка Paletto  2 773

•  Теорема Монжа об окружностях  3 575

•  Пазл Numbrix  2 344

•  Заборы и коммивояжеры  3 028

•  Игра HIP  1 984

•  Игра Go (Го)  1 906

•  Симулятор лифта  2 259

•  Программа укладки плитки  1 970

•  Генератор лабиринта  2 423

•  Проверка числового ввода  2 100

•  HEX View  2 429

•  Физический маятник  2 058

 
скрыть

  Форум  

Delphi FAQ - Часто задаваемые вопросы

| Базы данных | Графика и Игры | Интернет и Сети | Компоненты и Классы | Мультимедиа |
| ОС и Железо | Программа и Интерфейс | Рабочий стол | Синтаксис | Технологии | Файловая система |



Delphi Sources

Как не допустить запуск второй копии программы 12



Автор: Тихонов Михаил

Он основан на объекте ядра FileMapping. Такой способ уже был приведен ранее, но в отличие от приведенного, в нем использован оригинальный метод получения дескриптора первого запущенного приложения. Хэндл дескриптора первого запу- щенного приложения (Application.Handle) как раз и сохраняется в области дан- ных объекта FileMapping. Используется только одна функция FirstHinstanceRunning. Она имеет один параметр RunMode, Значения которого должны быть определены следующим образом:

  • если RunMode = 0 то недопущение повторного запуска того-же самого EXE файла с учетом пути
  • если RunMode = 1 то недопущение повторного запуска того-же самого EXE файла без учета пути
  • иначе повторный запуск разрешен

Ниже приводится текст функции:

unit FirstHinstanceRunning;

interface

uses
  Windows,
  Forms,
  StrUtils,
  SysUtils;

function FirstHinstanceRunning(RunMode: Integer = 0): boolean;

implementation

function FirstHinstanceRunning(RunMode: Integer = 0): boolean;
const
  MemFileSize = 127;

var
  MemHnd: HWND;
  MemFileName: string;
  lpBaseAddress: ^HWND;
  FirstAppHandle: HWND;

begin
  Result := False;
  MemFileName := Application.ExeName;
  case RunMode of
    0:
      MemFileName := AnsiReplaceText(MemFileName, '\', '/');
    1:
      MemFileName := ExtractFileName(MemFileName);
  else
    Exit;
  end;
  //если FileMapping есть - то происходит OpenFileMapping
  MemHnd := CreateFileMapping(HWND($FFFFFFFF), nil,
    PAGE_READWRITE, 0, MemFileSize, PChar(MemFileName));
  if GetLastError <> ERROR_ALREADY_EXISTS then
  begin
    if MemHnd <> 0 then
    begin
      lpBaseAddress := MapViewOfFile(MemHnd, FILE_MAP_WRITE, 0, 0, 0);
      if lpBaseAddress <> nil then
        lpBaseAddress^ := Application.Handle;
    end;
  end
  else
  begin
    //    MemFileHnd := OpenFileMapping(FILE_MAP_READ, False, PChar(MemFileName));
    Result := True;
    if MemHnd <> 0 then
    begin
      lpBaseAddress := MapViewOfFile(MemHnd, FILE_MAP_READ, 0, 0, 0);
      if lpBaseAddress <> nil then
      begin
        FirstAppHandle := lpBaseAddress^;
        ShowWindow(FirstAppHandle, SW_restore);
        SetForegroundWindow(FirstAppHandle);
      end;
    end;
  end;
  if lpBaseAddress <> nil then
    UnMapViewOfFile(lpBaseAddress);
end;

В тексте проекта * .dpr вызов функции выглядит приблизительно следующим образом

program OneHinstance;

uses
  Forms,
  Unit1 in 'Unit1.pas' {Form1},
  FirstHinstanceRunning in '..\..\FirstHinstanceRunning.pas';

{$R *.res}

begin
  Application.Initialize;

  if FirstHinstanceRunning(0) then
    Exit;

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

  //  CloseHandle(MemHnd);      //надо ли ???
end.

Обращаю Ваше внимание на то, что функция CloseHandle() не используется. В качестве обоснования этого привожу две выдержки из литературы:

А вдруг Вы забыли вызвать CloseHandle - будет ли утечка памяти? И да, и нет. Утечка ресурсов (тех же объектов ядра) вполне вероятна, пока процесс еще исполняется. Однако по завершении процесса операционная система гарантированно освобождает все ресурсы, принадлежавшие этому процессу, и в случае объектов ядра действует так: в момент завершения процесса просматривает его таблицу описателей и закрывает любые открытые описатели.

Ядру известно, сколько процессов использует конкретный объект ядра, поскольку в каждом объекте есть счетчик числа его пользователей. Этот счетчик - один из элементов данных, общих для всех типов объектов ядра. В момепт создания объекта счетчику присваивается 1. Когда к существующему объекту ядра обращается другой процесс, счетчик увеличивается на 1. А когда какой-то процесс завершается, счетчики всех используемых им объектов ядра автоматически уменьшаются на 1. Как только счетчик какого-либо объекта обнуляется, ядро уничтожает этот объект.








Copyright © 2004-2025 "Delphi Sources" by BrokenByte Software. Delphi World FAQ

Группа ВКонтакте