Как определить работает ли уже данное приложение или это первая его копия?
Для 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, &n!
bsp; 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.R!
un; 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); &!
nbsp; inc(i); end; Application.Terminate; Exit; end; end; Wnd:=GetWindow(Wnd,gw_hWndNext); end; end; end.
Если программа уже запущена, управление будет передано существующей копии.
опять про раскраску Grid 'oв
Проблема в том что пока не попадались пустые поля все было ровно, А теперь Выдает "Invalid variant type conversion" при ...
Delphi 5 для профессионалов
Эта книга поможет вам овладеть программированием в Delphi, включая язык Object Pascal, компоненты Delphi (как работу с существующими компонентами, так и разработку ваших собственных), поддержку баз данных и приложений клиент/сервер, базовые элементы программирования в среде Windows и разработку COM-приложений, а также Web-программирование. Для чтения этой книги нет необходимости в глубоких знаниях какой-либо из этих тем, но что вам действительно понадобится — это основы программирования на Паскале.
Автор: М. Кэнту
Дорогие друзья! Мы рады представить вам новый совместный проект сайтов www.rsdn.ru, delphi.mastak.ru и www.optim.ru - профессиональный журнал для программистов RSDN Magazine.
Несомненно, ваше мнение о необходимости такого журнала, содержании рубрик и темах отдельных статей поможет сделать журнал более полезным и интересным. Высказать свое мнение, проголосовать или же подписаться вы можете на сайте. Без вашего участия, нам будет трудно сделать правильный журнал!
На сайте выложен анонс пилотного выпуска журнала, вступительное слово от редакции.
Для души
Хокку дня
Гляжу - опавший лист Опять взлетел на ветку: То бабочка была.
Афоризмы
Разбойники требуют кошелек или жизнь, женщины и то, и другие.... (прислал Блок )
Фраза дня
Уронив свое достоинство, сделайте вид, что оно не ваше.
Дурацкие законы (информация предоставлена сайтом kurilka.com)
В Хартфорде в Коннектикуте (США) запрещено переходить дорогу на руках.
В Бальтиморе (США) запрещается швырять копны сена со второго этажа.
И на закуску коротенький анекдот
- Открываю утром холодильник, а там - ничего... Ну, погоди, коварный живой йогурт!