求助:一个程序已经在运行了,再双击这个可执行程序,不会运行两个这样的程序,只是跳出先前程序的窗口。请问如何实现!请各位高手指教。

解决方案 »

  1.   

    简单的方法是查找到你程序窗口的句柄并判断,假如句柄不为0时表示已经打开了该窗口。
    查句柄的方法:
    wnd :THandle;
    wnd := FindWindow(类名,标题名);
    (其中类名和标题名任填一,另外那个为nil。当然你想两个都写也没关系)如果你怕的你这个标题或者类名与其他的程序有重复,那么就为你程序填加一个GUID,用其来判断
      

  2.   

    程序只运行一个实例的问题,这个方法可多了
    你可以找一本windows编程的书来看看,什么全局变量、信号量、信号灯、还有什么傻瓜的写注册表写文件等等。大概的思路是这样的,
    在你的程序初始化的时候检查你设置的[标志](比如写一个注册表的键值为1,当然在你程序正常结束的最后你一定得删除它或者改写它,然后在程序的初始化部分读它的值)如果找到了证明已经有实例在运行中,然后就做一些另外的事情(比如弹出一个对话框告诉别人程序已经在运行中了),然后调用findwindow找到那个已经运行的程序的窗口,再调用showwindow激活它(恢复到前台),最后再结束程序就ok了。如果你用delphi的话,可以随便找一个delphi tips看看,里面一般都会有的。
    如果你想知道为什么的话,可以看看《windows程序设计》或者《windows核心编程》
      

  3.   

    实例只能运行一次的代码:
    unit Unit1;interfaceuses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs, ExtCtrls, StdCtrls, CheckLst;type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
      public
        { Public declarations }
      end;var
      Form1: TForm1;
      //保存Mutex句柄
      mHandle:THandle;
      PreviousInstanceWindow:HWnd;
      Project:String;
      AppName:String;
    implementation{$R *.dfm}
    procedure TForm1.FormCreate(Sender: TObject);
    beginend;initialization
      //定义自己的项目名称,作为要创建的互斥区名,最好有自己的特点以防止重复
      Project:='RunOnlyOnce_MyProject';
      //将lpMutexAttributes设为nil,bInitialOwner设为True(即本程序拥有该互斥区)
      mHandle:=CreateMutex(nil,True,PChar(Project));
      if GetLastError=ERROR_ALREADY_EXISTS then
       //该互斥区已存在则表明已有本程序的另一个实例在运行
        begin
          ShowMessage('已经有该程序在运行');
          //保存程序标题
          AppName:=Application.Title;
          //不显示本窗口
          Application.ShowMainForm:=False;
          //改变程序标题,以使函数FindWindow找到的是前一个实例窗口
          Application.Title:='destroy me';
          //寻找前一个实例窗口句柄
          PreviousInstanceWindow:=FindWindow(nil,PChar(AppName));
          //已经找到
          if PreviousInstanceWindow<>0 then
          //如果该窗口最小化则恢复
             if IsIconic(PreviousInstanceWindow) then
               ShowWindow(PreviousInstanceWindow,SW_RESTORE)
            else
            //如果程序在后台则将其放到前台
             SetForegroundWindow(PreviousInstanceWindow);
             //中止本实例
            Application.Terminate;
          end;
        finalization
        //该互斥区对象仍存在则关闭对象
          if mHandle<>0 then
            CloseHandle(mHandle);
    end.
      

  4.   

    不用那么麻烦吧wnd :THandle;
    wnd := FindWindow(类名,标题名);
    if(找到了)
      ShowWindow(wnd,SW_SHOW);
    else 
      运行程序