Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

Мастера DELPHI. Новости мира компонент, FAQ, статьи...


Информационный Канал Subscribe.Ru

Ежедневная рассылка сайта Мастера DELPHI

DELPHIMASTER.ru

Выпуск от 20.01.04 16:37

Вышел очередной дайджест форумов. Скачать можно здесь
Кое-что из нашей кладовки   |x|
  • TIndexedStorage - оптимизированная Polevi   (20.01.04 15:15)
    Оптимизирована ф-ия Get
    »»» Скачать: исходные тексты (1кб)
  • TIndexedStorage Polevi   (20.01.04 12:43)
    Модуль для быстрого поиска значения по массиву числовых идентификаторов.
    Колво идентификаторов передается в конструктор.

    procedure TIndexedStorage.Put(Arr:array of integer;Value:Pointer);
    -помещает указатель в хранилище по идентификаторам в массиве Arr
    function TIndexedStorage.Get(Arr:array of integer):Pointer;
    -извлекает указатель из хранилища по идентификаторам в массиве Arr
    function TIndexedStorage.GetMemory(ASize:DWORD):Pointer;
    -замена GetMem, вся память выделенная этой ф-ией будет освобождена при уничтожении хранилища.

    PS
    Размер массива Arr должен совпадать со значеним, переданным в конструктор
    »»» Скачать: исходные тексты (1кб)
Лучшее из нашего FAQ   |x|
Как определить работает ли уже данное приложение или это первая его копия?
Для Delphi 1. Каждый экземпляр программы имеет ссылку на свою предыдущую копию - hPrevInst: hWnd. Ее можно проверить перед созданием приложения и при необходимости отреагировать соответствующим образом. Если запущена только одна копия, то эта ссылка равна нулю.
Пример:


procedure TForm1.FormCreate(Sender: TObject);
begin
 {Проверяем есть ли указатель на предыдущую копию приложения}
 IF hPrevInst <> 0 THEN BEGIN
   {Если есть, то выдаем сообщение и выходим}
   MessageDlg('Программа уже запущена!', mtError, [mbOk], 0);
   Halt;
 END;
 {Иначе - ничего не делаем (не мешаем созданию формы)}
end;


P.S. Для выхода необходимо использовать Halt, а не Close, как хотелось бы, так как форма еще не создана и закрывать нечего.
Есть и другой способ - по списку загруженных приложений




procedure TForm1.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
   MessageDlg('Приложение уже загружено', mtWarning, [mbOk], 0);
   Halt;
  END;
 END;
 Wnd := GetWindow (Wnd, gw_hWndNext);
END;
End;


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

Пример:


program Project1;
uses
 Windows, // Обязательно
 Forms,
 Unit1 in 'Unit1.pas' {Form1};

{$R *.RES}
Const
MemFileSize = 1024;
MemFileName = 'one_inst_demo_memfile';
Var
MemHnd : HWND;
begin
 { Попытаемся создать файл в памяти }
 MemHnd := CreateFileMapping(HWND($FFFFFFFF),
                             nil,
                             PAGE_READWRITE,
                             0,
                             MemFileSize,
                             MemFileName);
 { Если файл не существовал запускаем приложение }
 if GetLastError<>ERROR_ALREADY_EXISTS then
 begin
  Application.Initialize;
  Application.CreateForm(TForm1, Form1);
  Application.Run;
 end;
 CloseHandle(MemHnd);
end.


Часто при работе у пользователя может быть открыто 5-20 окон и сообщение о том, что программа уже запущено приводит к тому, что он вынужден полчаса искать ранее запущенную копию. Выход из положения - найдя копию программы активировать ее, для чего в последнем примере перед HALT необходимо добавить строку :
SetForegroundWindow(Wnd);
Например так:


program Project0;
uses
 Windows,  // !!!
 Forms,
 Unit0 in 'Unit0.pas' {Form1};

var
 Handle1 : LongInt;
 Handle2 : LongInt;

{$R *.RES}

begin
 Application.Initialize;
 Handle1 := FindWindow('TForm1',nil);
 if handle1 = 0 then
   begin
     Application.CreateForm(TForm1, Form1);
     Application.Run;
   end
 else
   begin
     Handle2 := GetWindow(Handle1,GW_OWNER);
      //Чтоб заметили :)
     ShowWindow(Handle2,SW_HIDE); ShowWindow(Handle2,SW_RESTORE);
     SetForegroundWindow(Handle1); // Активизируем
   end;
end.




Комментарий от "Vladimir" (damageinc@e-mail.ru)
Лучше  всего  использовать  именованные  мутексы.  Главное,  придумать
уникальное  имя  для  этого мутекса. Вот пример вполне работоспособной
программы:

program My1;
uses
 Forms, Windows, Dialogs, SysUtils,

var
g_hAppMutex: THandle;
Wnd : hWnd;
buff: array [0..127] of Char;
s:string;
i:integer;

function OneInstance: boolean;

begin
g_hAppMutex:=CreateMutex(nil,false,PChar('AnUniqueString'+IntToStr(GetDesktopWindow)));
Result:=(WaitForSingleObject(g_hAppMutex,0)<>WAIT_TIMEOUT);
end;

begin
 Application.Initialize;
 Application.Title := 'SmartDecoder';
 Application.HelpFile := 'Decoder.hlp';
 //создаём инстанс, если его ещё нету на текущем рабочем столе
 g_hAppMutex:=0;
 if OneInstance then
    begin
     Application.CreateForm(TMainFrm, MainFrm);
     Application.Run;
    end;
 if LongBool(g_hAppMutex) then //если уже есть
    begin
     ReleaseMutex(g_hAppMutex);
     CloseHandle(g_hAppMutex);
     if  ParamStr(1)=''  then  ShowMessage('Программа уже запущена на
     этом  рабочем столе. Нажмите кнопку "OK" для передачи управления
     уже запущенной копии программы.');
     Wnd:=GetWindow(GetTopWindow(0),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 Copy(StrPas(buff),1,12)='SmartDecoder' then
              if Wnd=GetWindowLong(Wnd,GWL_USERDATA) then
                 begin
                  ShowWindow(Wnd,SW_ShowNormal);
                  SetForegroundWindow(Wnd);
                  i:=1;
                  while ParamStr(i)<>'' do
                   begin
                    s:=ParamStr(i);
                    PostMessage(Wnd,WM_OPEN_FILE,GlobalAddAtom(PChar(s)),0);
                    inc(i);
                   end;
                  Application.Terminate;
                  Exit;
                 end;
          end;
       Wnd:=GetWindow(Wnd,gw_hWndNext);
      end;
    end;
end.

Если  программа  уже  запущена, управление будет передано существующей
копии.

»»» Прислать свои комментарии

Обсуждается в конференциях   |x|
У нас большой выбор статей   |x|
Ограничение количества одновременно запущенных экземпляров приложения
Обсуждение данной темы ведется, начиная с появления первых 32-х разрядных версий Windows. Казалось бы, проблема давно уже должна быть окончательно решена, но количество вопросов в конференциях и форумах не уменьшается, хотя из книги в книгу, из FAQ'а в FAQ кочуют одни и те же варианты решения. Но не все так очевидно и просто...
Новинки книжного рынка   |x|
Технологии передачи данных. 7-е изд.
В книге рассматриваются современные технологии передачи данных и перспективы их развития. Освещаются основные аспекты передачи информации, от структуры сетей до безопасности их использования. Представлены технологии, позволяющие существенно улучшить качество работы отдельных пользователей, а также корпораций и государственных учреждений. Издание содержит подробные сведения, необходимые для понимания функционирования различных систем передачи данных — от кабельных сетей до беспроводных спутниковых систем. Книга предназначена как профессионалам в области систем коммуникации, так и студентам технических специальностей.
Автор: Хелд Г.
Другие сайты о DELPHI   |x|
Компьютерная литература о Delphi
Обзор компьютерной литературы и цен на нее в крупнейших интернет магазинах Рунета.

» Оценка сайта: 3
Опрос населения :)
Образование программиста?
»»» Высшее
»»» Незаконченное высшее
»»» Среднее специальное
»»» Среднее
Для души

Хокку дня
летом на реке -
рядом мост, но мой конь
переходит вброд

Афоризмы
Вежливость - благожелательность в мелочах...

Фраза дня
Привлекательные женщины отвлекают.

Дурацкие законы (информация предоставлена сайтом kurilka.com)
В Нью Джерзи (США) водителям нельзя самим заправлять машину. На всех заправках этим должен заниматься обслуживающий персонал.
В Арканзасе (США) считается преступлением неправильно произнести название этого штата.

И на закуску коротенький анекдот
Найден щенок бультерьера. Большая просьба к хозяевам: ЗАБЕРИТЕ ПОСКОРЕЕ ЭТУ СВОЛОЧЬ!

Фотоприколы.
Начните день с хорошего настроения!
http://www.delphimaster.ru/cgi-bin/prikol.pl?id=37423


На этом позвольте откланяться и пожелать вам удачного дня.
Искренне ваш, Алексей (merlin@delphimaster.ru)

Добро пожаловать на сайт -= Мастера DELPHI =- 


http://subscribe.ru/
E-mail: ask@subscribe.ru
Отписаться
Убрать рекламу

В избранное