我要完成的功能是:
例如程序:a.exe
如果这个程序正在运行,那么我再次运行这个程序的时候,将会自动关闭;
并且先运行的哪个程序如果已经最小化则使其正常显示,并显示到最前面;以下使我的代码:procedure TForm1.FormCreate(Sender: TObject);
var
  errNO: Integer;
  hMutex: HWND;
begin
  //创建互斥对象
  hMutex := CreateMutex(nil, false, PChar(Application.Title));
  errNO := GetLastError;
  //判断程序是否重复运行
  if errNO = ERROR_ALREADY_EXISTS then
  begin
    hMutex := FindWindow(nil, 'zzz'); //获得程序句柄
    ShowWindow(hMutex, SW_NORMAL);    //如果最小化则正常显示
    SetForegroundWindow(hMutex);      //程序显示到最前面
    Application.Terminate;
  end;
end;procedure TForm1.FormShow(Sender: TObject);
begin
  Form1.Caption := 'zzz';
end;
问题是:
如果先运行的哪个程序已经最小化,那么当我再次打开这个程序的时候,先运行的哪个程序便会变为正常显示,但却再也无法最小化了,不知道为什么?请各位大侠指点!

解决方案 »

  1.   

    这段代码你加到工程文件里去
    不要在FormCreate里
      

  2.   

    结合你自己的代码
    大概是这个样子
    var
     hMutex:hwnd;
     ret:integer;
    begin
      Application.Initialize;  hmutex:=createMutex(nil,false,'program run once');
      ret:=getlasterror;
      if ret<>error_already_exists then
      begin
        Application.CreateForm(TForm_Main, Form_Main);
        Application.Run;
      end
      else application.messagebox('程序已经运行','提醒',MB_OK);
      releasemutex(hmutex);
    end.
      

  3.   

    我找到原因了,但不知道该如何解决!
    FindWindow(nil, 'zzz'); 我获得是form的句柄,要获得Application的句柄就可以。但是我的Application.Title是随时在变的,不知该怎么获得句柄?
    或者通过form的句柄得到Application.Title也可以!请大家帮帮忙!!谢谢!
      

  4.   

    hprevinst:=findwindow('TFrm_Operation_main',nil);
     if hprevinst=0 then
       //运行
     else
     begin
       Application.Terminate;
       Application.Run;
     end;
      

  5.   

    你看了试了我前面的回复吗
    放在dpr单元里就解决你的问题了
      

  6.   

    采用消息方式吧:
    if errNO = ERROR_ALREADY_EXISTS then
      begin
        hMutex := FindWindow(nil, 'zzz'); //获得程序句柄
        ShowWindow(hMutex, SW_NORMAL);    //如果最小化则正常显示
        SetForegroundWindow(hMutex);      //程序显示到最前面
        Application.Terminate;
      end;改为:if errNO = ERROR_ALREADY_EXISTS then
      begin
        hMutex := FindWindow(nil, 'zzz'); //获得程序句柄
        SendMessage(hMutex, WM_USER + 1000, 0, 0);    
        Application.Terminate;
      end;
    现在程序中加入消息处理过程.
    procedure HandleIconMessage(var Msg: TMessage); Message WM_USER + 1000;实现部分为:
    procedure TForm1.HandleIconMessage(var Msg: TMessage);
    begin
      Application.Restore;             //恢复窗体
      Application.BringToFront;        //窗体放到最前
    end;包你解决
      

  7.   

    或者用别的办法,内存映射文件,保存Application.Handle。程序启动时先打开,若能打开则说明已经存在,用这个Handle把它恢复就好了。不能打开就创建新程序。
      

  8.   

    各位大虾,帮帮忙吧?呵呵http://expert.csdn.net/expert/Topicview1.asp?id=1704009
      

  9.   

    [email protected]谢谢楼上的大侠们!
      

  10.   

    用FindWindow来判断程序是否在运行是不可靠的
    有这样一种情况,一个程序同时运行两个副本。同时查找窗体(都没找到),然后再同时创建窗体。然后都运行起来了。这是以前我遇到的问题。
    现在我使用另一种方法来避免重复运行。使用CreateSemaphore( )创建信号量,如果成功则是首次运行,再次运行时,创建同名的信号量会失败。这样可做到万无一失,并且实现也很简单。我对CreateSemaphore( )进行了包装,做成了一个单元。
    下载:http://www.ahjoe.net/2/PrevInst.pas
    使用示例:
      prev: TPrevInst;
    begin
      prev := TPrevInst.Create();
      if prev.FindPrev('TMyAppSema') <> 0 then
      begin
        prev.Free();
        Exit;
      end;
      Application.Initialize();
       ......
      Application.Run();
    end;
      

  11.   

    示例改一下:
      prev: TPrevInst;
    begin
      prev := TPrevInst.Create();
      if prev.FindPrev('TMyAppSema') <> 0 then
      begin
        prev.Free();
        Exit;
      end;
      Application.Initialize();
       ......
      Application.Run();
      prev.Free()
    end;
      

  12.   

    已经发送到了你的邮箱.
    注意.dpr文件中还有代码... 同时, 也在这里帖上.............//--------------------------------------------------------------------------------
    //Unit1.pas 内容
    //--------------------------------------------------------------------------------
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;//-----------------------------------------
    //常量定义
    //-----------------------------------------
    const
      Const_Params  =  'Window_Delphi_Ex';
      WM_CM_RESTORE =  WM_USER + 1000;  type
      TForm1 = class(TForm)
      private
        { Private declarations }
        procedure GetWM_CM_RESTORE(var Msg: TMessage); Message WM_CM_RESTORE;
      public
        { Public declarations }
        procedure CreateParams(var Params: TCreateParams); override;
      end;var
      Form1: TForm1;implementation{$R *.dfm}{ TForm1 }procedure TForm1.CreateParams(var Params: TCreateParams);
    begin
      inherited CreateParams(Params);
      Params.WinClassName := Const_Params;
    end;//此消息从 Project1.dpr 中发出
    procedure TForm1.GetWM_CM_RESTORE(var Msg: TMessage);
    begin
        Application.Restore;
        Application.BringToFront;
    end;end.
    //--------------------------------------------------------------------------------
    //Project1.dpr 内容
    //--------------------------------------------------------------------------------
    program Project1;uses
      Forms, Windows,
      Unit1 in 'Unit1.pas' {Form1};{$R *.res}var
      h: HWND;
    begin
      h := FindWindow(Const_Params, NIL);
      if h > 0 then
      begin
        SetForegroundWindow(h);      
        SendMessage(h, WM_CM_RESTORE, 0, 0);
        Exit;
      end;
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;
    end.
      

  13.   

    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;