Windows95的程序一般都可以重复执行,例如你按下WIN+E组合键即启动资源管理器,如果再按WIN+E组合键又会出现一个资源管理器,这两个程序互不干扰。有时候你可以需要制作这样一个程序:当该程序已经执行时,若用户企图再次执行该程序则只会激活那个已执行的程序,而不是又出现一个副本。
完成这个目的的核心就是要在程序启动时查找该程序是否已经运行,我曾试过很多种方法,包括向“全局元素表”(Global ATOM Table)写特定字符串等等,但最简单的方法还是下面这个:
procedure TForm1.FormCreate(Sender: TObject);
var
ZAppName : array[0..127] of Char;
Hold : String;
Found : HWND;
begin
Hold := Application.Title; 查找窗体的方法
Application.Title :='OnlyOne'+IntToStr(HInstance);暂时修改窗口标题
StrPCopy(ZAppName,Hold); 原窗口标题
Found := FindWindow(nil,ZAppName); 查找窗口
Application.Title := Hold; 恢复窗口标题
if Found <> 0 then 若找到则激活已运行的程序并结束自身
begin
ShowWindow(Found,SW_RESTORE);
Application.Terminate;
end;
end;
Function CheckReEnter:Boolean ;//避免重复启动
var
hMap : THandle;
temp:string;
begin
Result := False;
temp:= ExtractFileName(Application.ExeName);
hMap := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,2,PChar(ExtractFileName(Application.ExeName)));
if ((hMap <> 0) and (GetLastError() = ERROR_ALREADY_EXISTS)) then
begin
CloseHandle(hMap);
hMap := 0;
Result := True;
end;
end;
简单点的:
const classname='Tmainform'; {声明为主窗体的类名}
var handle:integer;
begin
handle:=findwindow(classname,nil);{查找是否有此类的窗体}
if handle<>0 then {不为0则程序已运行}
begin
messagebox(0,'系统已经在运行中!','提示',0);{提示程序已运行}
halt; {退出程序}
防止程序重复运行
将下面的代码放到工程文件中
uses windows;
...
var MutexHandle:Thandle;
begin
Mutexhandle:=windows.CreateMutex(nil,true,'能代表程序特点的字符串');
if Mutexhandle<>0 then
begin
if getlasterror=windows.ERROR_ALREADY_EXISTS then
begin
closehandle(Mutexhandle);
halt;
end;
end;