一个程序,同一时间只允许存在一个实例。当实例启动时如果检测到已经有实例存在,就退出。在退出的同时广播一个自定义的消息,通知已经存在的实例激活。
问题是,我只能从第二个实例向第一个实例传递这个自定义的消息,而无法传递其它信息。
比如,点击文件“a.txt”起动了第二个实例,如何才能使第一个实例收到“a.txt”这个信息,使其可以激活并打开“a.txt”???

解决方案 »

  1.   

    下在的代码是不是可以达到你的要求啊。把下面这一段写在dpr里面。
            Application.Initialize;
            if Findwindow(nil,'a.txt') <> 0 then
            begin
              showwindow(findwindow(nil,'a.txt'),SW_SHOW );
              application.terminate;
            end else
            begin
              Formsd:=tFormsd.Create(Application);
              Formsd.Show;
              Formsd.Update;
              Application.Title := 'a.txt';
              application.run;
            end;
      

  2.   

    什么是检测到已存在的实例?
    检测到了当然就抓到了实例的"把柄"( Handle)有了它的"把柄"当然传消息也就有了对象......, 打开a.txt嘛...你的消息里能放得了这么多东西吗?我没用过.建议: 不要用什么自定义消息. 就找到实例,然后把找到的实例放到最前面.
    然后调用找到实例的方法,打开文件. 然后, 自己退出.program Project2;uses
      Forms,
      windows,
      Unit1 in 'Unit1.pas' {Form1};{$R *.RES}var
      g_hWnd : HWND;
    begin
      g_hWnd := FindWindow('TForm1',nil);
      if g_hWnd > 0 then
      begin
        g_hWnd := GetWindow(g_hWnd, GW_OWNER);    if IsIconic(g_hWnd) then
          ShowWindow(g_hWnd, SW_RESTORE);
        SetForegroundWindow(g_hWnd);
        halt;
      end;
      Application.Initialize;
      Application.CreateForm(TForm1, Form1);
      Application.Run;end.
      

  3.   

    《Delphi深度历险》里面讲得很好!!建议看一看。
      

  4.   

    建议不要使用hydonlee(青山情)的方法!如果有多个用Delphi编写的程序在运行就会失败!
      

  5.   

    《Delphi深度历险》里面正讲到了这个问题,就是将应用程序的参数传递到前一个实例,建议看一看。
      

  6.   

    CreateMutex(nil,False,'ProjectName');
      if GetlastError = ERROR_ALREADY_EXISTS then
      begin
        Application.MessageBox('系统已经运行!','消息',MB_ICONERROR);
        Halt(0);
      end;
      

  7.   

    var ret :integer;hMutex:=CreateMutex(nil,False,'宏达第三方维护软件');
      ret:=GetLastError;
      if Ret<>ERROR_ALREADY_EXISTS then
      begin
      Application.CreateForm(TFrmMain, FrmMain);
      FrmSplash.Show;
      FrmSplash.Update;
      Application.Run;
      end
      else
       Application.MessageBox(' 软件已经启动,或者上次启动时非正常关闭,'+#13#13+'您不能再次运行本程序,或者请重新启动系统!','错误',MB_OK+MB_IconError);
       ReleaseMutex(hMutex);
      

  8.   

    高手来了 ^_^~~~~
    给你一点提示
    你可以发送 wm_copydata 消息 //一个唯一可以跨进程传递文本的windows消息
    具体的你自己找吧 哈哈
      

  9.   

    各位革命同胞们,可能我没说清楚。我所要的不是如何实现了只启动一个实例,因为已经用互斥对象实现了。
    我所要追求的是像Media Play那样,点击一个相关联的文件(比如MP3)来启动程序,如果发现之前已经启动了一个实例就退出,并在退出前把文件名传给之前启动的那个实例,使其播放之。
    有没有什么办法做到这一点??就像WINAMP之类的播放器那样.
      

  10.   

    还有,TO hydonlee(青山情):
    FindWindow方法不是太可靠,无法保证
      

  11.   

    一个简单的方法:预设两个不同的MutEx名称,一个内存映射文件名称。过程:
      1.创建MutEx1,如果不存在,转6
      2.打开并等待MutEx2的所有权,如果成功,转4
      3.睡眠100毫秒,转2
      4.打开内存映射文件,取其内容作为Window句柄
      5.向Window句柄发送命令,退出程序  6.创建并获得MutEx2的所有权,创建内存映射文件
      7.创建一个专门接受命令的Window,并为其设立消息处理系统,并将句柄放入内存映射文件
      8.其他初始化工作
      9.释放MutEx2的所有权
      

  12.   

    TO  dbExpress
    虽然被你转啊转啊头有点晕,但终于有了一点启发。
    实现的方法和你的可能不太相同,是这样的:
    虽然第二个实例启动时只能通知一个消息来激活第一个实例,但是可以将所需的的文件信息存放至某个地方,第一个实例收到通知消息后再从那里取得所需信息,进行操作,OK!
    多谢指点!老规矩,挂一夜,明天结帐。
      

  13.   

    你如果只是想传个文件给程序还是有办法啦,也不用另个找一个地方,就在你的程序的主窗体上放一个隐含的EditBox就可以了。需要传的进候,发个消息过去不就OK了。然后你再发个消息激活就是了。
      

  14.   

    TO proman() 
    不太明白你的意思啊,能否讲清楚点??