查找另一个程序,并将其显示在最前端

来源:互联网 发布:万象网管数据库密码 编辑:程序博客网 时间:2024/05/01 02:46

      之前在做一个程序只能开一次,再次打开就会提示此软件已运行。但是我发现会再次点这个程序是因为它是处于最小化,或者干脆就是处于托盘状态,才会去再次点。但是点击后知道那个程序已在运行,但是还得再找到那个程序。我就想可不可以提示运行之后就把那个程序显示出来!不过在之中间我还是发现了两个问题。

      1、如果此软件没做什么事还好,用正常的FindWindow(nil,'此软件的项目标题') 就可以找到。但是如果这个软件本身就已有在接收消息,且时刻在处于系统消息,那就会出现找不到该软件的句柄;或是找到了消息也发过去了,但是该软件却没收到。我就对FindWindow这个函数进行研究了下,发现参数改变下准确率就升高了好多。我是用FindWindow('TMainForm',nil)有该软件主窗体的类进行查找,成功率就高好多,或者可以把两者结合起来TFormtdmain('TMainForm','此软件的项目标题')。我目前的成功率是100%但是没在高强度情况下进行查找,不敢说完全100%能成功。

      2、第二个问题是找到该软件了,消息也收到了,怎么让该软件从最小化或是托盘中显示出来,且显示在最前端。在网上找了说什么三种方法,且三种方法还各有缺点,还得多种结合才能去掉缺点。看的好像很复杂的样子,但是我记得我好像有做过这个类似的,找了下就找到了。只要用ShowWindow(Application.Handle,SW_SHOW);      Application.Restore;  这两句就可以很快解决了。

      希望能给读者一点帮助。

      以下是我的代码,以供参考。

 

//这是在工程文件 program ABTMonitor; 里进行判断

var
  hMutex: THandle;
  h: HWND;
  Size: Integer;
  CopyDataStruct: TCopyDataStruct;
begin
  hMutex := CreateMutex(nil, False, 'ABRMonitorSystem');
  if WaitForSingleObject(hMutex, 0) = wait_TimeOut then
  begin
    application.MessageBox('安贝通视频监控系统已经运行!','运行',MB_OK+MB_ICONINFORMATION);
     h := FindWindow('TMainForm',PChar('安贝通视频监控系统')); { 按标题查找目标窗口 }
    if h > 0 then
    begin
      Size := 7;   { 多出的两个字节用于后面的 #0 }
      CopyDataStruct.lpData := PChar('@Show' + #0); { 要发送的字符串, #0 表示 PChar 结束}
      CopyDataStruct.dwData := WM_COPYDATA;            { 指定消息类型 }
      CopyDataStruct.cbData := Size;                   { 指定要发送的数据的大小 }
      SendMessage(h, WM_COPYDATA, 0, Integer(@CopyDataStruct)); { 发送 }
    end;
    Exit;
  end;
  Application.Initialize;
  Application.Title :='安贝通视频监控系统';
  Application.CreateForm(TMainForm, MainForm);
  Application.CreateForm(TFormshowlabel, Formshowlabel);
  Application.Run;

 

//这是在主窗体unit MainFrm;里接收消息

procedure TMainForm.Mymessage1(var t: TWmCopyData);
var
  CommrevStr: string;
begin
  CommrevStr := StrPas(t.CopyDataStruct^.lpData);
  if CommrevStr='@Show' then
  begin
    ShowWindow(Application.Handle,SW_SHOW);
    Application.Restore;

    exit;
  end;

end;

 

原创粉丝点击