var
  I: Integer;
  hMutex: Hwnd;
begin
  hMutex:=CreateMutex(nil,false,'Program Run Once Test');
  I := GetLastError;
  if I = ERROR_ALREADY_EXISTS then
  begin
    ReleaseMutex(i);
    halt;
  else
  begin
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.Run;
  end;  
end.

解决方案 »

  1.   

    {CreateMutex函数用来创建一个已命名或是未命名的互斥体。CreateMutex的函数原型为:HANDLE CreateMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes,    // address of security attributes
    BOOL bInitialOwner,            // flag for initial ownership
    LPCTSTR lpName                  // address of mutex-object name
    );参数说明:lpMutexAttributes    此参数指向一个SECURITY_ATTRIBUTES结构,此结构指定该互斥体的安全
                属性,如果该参数为NULL(即为空),则以缺省的安全描述符来创建互斥
                体,并且该函数返回的句柄不能被继承。
                (此参数好象不好理解,不过在此处你只需将其设为NULL就行了!)bInitialOwner         指定互斥体对象的初始拥有者。在此处设为False。lpName              此参数指定互斥体的名字。参数类型是以NULL结尾的字符串。返回值:如果函数成功则返回互斥体的句柄,如果指定的互斥体名已经存在,则GetLastError函数返回
    ERROR_ALREADY_EXISTS}
    ...
      Application.Initialize;
      Application.Title := '小小音乐家';
      hMutex:=CreateMutex(nil,False,'aaaaaa');
      Ret:=GetLastError;
      if hasrealplayer=1 then begin
        if Ret<>ERROR_ALREADY_EXISTS then begin
          Application.CreateForm(Tmainform, mainform);
          Application.CreateForm(Timageform, imageform);
          Application.Run;
        end
        else
          ReleaseMutex(hMutex)
        end
    ...
      

  2.   

    这是我看见的一篇文章的一部分,希望对你有帮助。如何判断一个程序是否已在运行?  在某些时候我们通常需要自己编制的程序只可以有一份拷贝在运行,如何作到这一点呢?通常我们可以用GetWi ndowsWord获得窗口句柄,再用GetClassName获得并比较ClassName来达到目的。  ...  Result:=true;  if GetWindowWord(Wnd, Gww_HINSTANCE)  =hPrevInst then  begin  GetClassName(Wnd,ClassName,30);  if StrIComp(ClassName,'TApplication')=0 then  begin  TargetWindow^:=Wnd;  Result:=false;  end;  end;  ...  后来我曾在网上看过一段关于此方面的说明,它介绍了另一种方法,是通过在内存中建立旗语标志实现此功能的,试了一下效果很好,具体的过程见下面的程序与注释:  unit prevcode;  interface  uses  Windows, Messages, SysUtils, Classes, Graphics, Con trols, Forms, Dialogs;  type  TForml=class(TForm)  procedure FormCreate(Sender:TObject);  private  {Private declarations}  public  {Public declarations}  end;  function DoIExist(WndTitle:String):Boolean;  var  Form1:TForm1;  implementation  {$R*.DFM  function DoIExist(WndTitle:String):Boolean;  var  hSem:THandle;  hWndMe,hWnPrev:HWnd;  semNm,wTtl:Array[0..256]of Char;  beigin  Result:=False;  StrPCopy(semNm,'SermaphoreName');  StrPCopy(wTtl,WndTitle);  hSem:=CreateSemaphore(nil,0,1,semNm);//如果第一次运行则建立一个标志  //检查这个标志是否存在  if(hSem<>0)AND(GetLastError()=ERROR_ALREADY_EXISTS) )then  begin  CloseHandle(hSem);  hWndMe:=FindWindow(nil,wTtl);//获得当前运行的窗口句柄,改变标题SetW indowText(hWndMe,'zzzzzzz');//这样才可以寻找其他instance//寻找这个视窗的instance,然后将它置于Z-order顶层hWndMe:=FindWindow(nil,wTtl);  if(hWndMe<>0)then  begin  if IsIconic(hWndMe) then ShowWindow(hWndMe, SW_SHOW NORMAL)  else  SetForegroundWindow(hWndMe);  end;  Result:=True;  end;  end;  procedure TForm.FormCreate(Sender:TObject);  begin  if DOIExist(Self.Caption)then  Halt;  end;  end. 
      

  3.   

    在主窗体定义常量
    const
      CM_Restore = WM_User + $1000;
      AppName = 'Appname';  //自己定义的名,注意要跟工程文件里的名字相同,切记切记
    以下两个过程写在主窗体
    procedure TMain_Form.CreateParams(var Params: TCreateParams);
    begin
    inherited CreateParams(Params);Params.WinClassName:=AppName;end;procedure TMain_Form.RestoreRequest(var msg: TMessage);
    begin
    if isIconic(Application.Handle)=True then
      Application.Restore
    else
      Application.BringToFront;  
    end;在工程文件中按照下面作
    const
      CM_RESTORE = WM_USER + $1000; {自定义的“恢复”消息}
      APPNAME = 'Appname';  //自己的程序名,自己定义即可
    var
      RvHandle : hWnd;
    {$R *.RES}
    begin
    RvHandle := FindWindow(APPNAME, NIL);
    if RvHandle > 0 then
    begin
      PostMessage(RvHandle, CM_RESTORE, 0, 0);
      Exit;
    end;
      Application.Initialize;
      Application.Title := '';
      Application.CreateForm(TMain_Form, Main_Form);
      Application.Run;
    end.