Модуль для быстрого поиска значения по массиву числовых идентификаторов. Колво идентификаторов передается в конструктор.
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кб)
Как определить работает ли уже данное приложение или это первая его копия?
Для Delphi 1. Каждый экземпляр программы имеет ссылку на свою предыдущую копию - hPrevInst: hWnd. Ее можно проверить перед созданием приложения и при необходимости отреагировать соответствующим образом. Если запущена только одна копия, то эта ссылка равна нулю. Пример:
procedure TForm1.FormCreate(Sender: TObject); begin {Проверяем есть ли указатель на предыдущую копию приложения} IF hPrevInst <> 0 THENBEGIN {Если есть, то выдаем сообщение и выходим} 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 DOBEGIN IF (Wnd <> Application.Handle) AND (GetWindow(Wnd, gw_Owner) = 0) THENBEGIN 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.
Если программа уже запущена, управление будет передано существующей копии.
Диалоговое окошко входа в домен!
Уважаемые мастера, просьба помочь! Я сталкнулся с такой проблемой: мне надо с помошью Делфей получить Имя пользователя, ...
Ограничение количества одновременно запущенных экземпляров приложения
Обсуждение данной темы ведется, начиная с появления первых 32-х разрядных версий Windows. Казалось бы, проблема давно уже должна быть окончательно решена, но количество вопросов в конференциях и форумах не уменьшается, хотя из книги в книгу, из FAQ'а в FAQ кочуют одни и те же варианты решения. Но не все так очевидно и просто...
Технологии передачи данных. 7-е изд.
В книге рассматриваются современные технологии передачи данных и перспективы их развития. Освещаются основные аспекты передачи информации, от структуры сетей до безопасности их использования. Представлены технологии, позволяющие существенно улучшить качество работы отдельных пользователей, а также корпораций и государственных учреждений. Издание содержит подробные сведения, необходимые для понимания функционирования различных систем передачи данных — от кабельных сетей до беспроводных спутниковых систем. Книга предназначена как профессионалам в области систем коммуникации, так и студентам технических специальностей.
Автор: Хелд Г.
Хокку дня
летом на реке - рядом мост, но мой конь переходит вброд
Афоризмы
Вежливость - благожелательность в мелочах...
Фраза дня
Привлекательные женщины отвлекают.
Дурацкие законы (информация предоставлена сайтом kurilka.com)
В Нью Джерзи (США) водителям нельзя самим заправлять машину. На всех заправках этим должен заниматься обслуживающий персонал.
В Арканзасе (США) считается преступлением неправильно произнести название этого штата.
И на закуску коротенький анекдот
Найден щенок бультерьера. Большая просьба к хозяевам: ЗАБЕРИТЕ ПОСКОРЕЕ ЭТУ СВОЛОЧЬ!