2011年7月7日木曜日

指定したウインドウを最前面にもってくる

VBAから指定したアプリが起動してない場合は起動し、既に起動済みの場合は、最前面に持ってくる
という処理が必要になったので、Delphiで作成してみた。

以下、指定したアプリを前面に持ってくるサンプル。

  1. procedure TForm1.Button1Click(Sender: TObject);  
  2. unit Unit1;  
  3.   
  4. interface  
  5.   
  6. uses  
  7.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  8.   Dialogs, StdCtrls, ExtCtrls;  
  9.   
  10. type  
  11.   TForm1 = class(TForm)  
  12.     LabeledEdit1: TLabeledEdit;  
  13.     Button1: TButton;  
  14.     procedure Button1Click(Sender: TObject);  
  15.   private  
  16.     { Private 宣言 }  
  17.   public  
  18.     { Public 宣言 }  
  19.   end;  
  20.   
  21. var  
  22.   Form1: TForm1;  
  23.   
  24. implementation  
  25. Uses JclSysInfo;  
  26.   
  27. {$R *.dfm}  
  28. function AllowSetForegroundWindow(dwProcessID: Cardinal): BOOL; stdcall; external 'user32.DLL';  
  29.   
  30.   
  31. procedure TForm1.Button1Click(Sender: TObject);  
  32. var  
  33.   ProcessList : TStringList;  
  34.   i : Integer;  
  35.   Pid : Cardinal;  
  36.   Wnd: THandle;  
  37. begin  
  38.   
  39.   ProcessList := TStringList.Create;  
  40.   try  
  41.     //起動するアプリは、自前のものではないので  
  42.     //プロセスがいるかどうかは、プロセスのリストを総当りで  
  43.     //確認  
  44.     JclsysInfo.RunningProcessesList(ProcessList,true);  
  45.     i := -1;  
  46.     ProcessList.Find(LabeledEdit1.Text,i);  
  47.     if i >= 0 then  
  48.     begin  
  49.       Pid := GetPidFromProcessName(ProcessList.Strings[i]);  
  50.       Wnd :=GetMainAppWndFromPid(Pid);  
  51.       //いつぞやのバージョンのwindowsから前面に出す許可を  
  52.       //しておくことが必要  
  53.       AllowSetForegroundWindow(Pid);  
  54.       //最小化されているのでアイコンからもとのサイズに  
  55.       //戻す  
  56.       if IsIconic(Wnd) then  
  57.       begin  
  58.         OpenIcon(Wnd);  
  59.       end  
  60.       else  
  61.       begin  
  62.         //指定したウインドウを前面に  
  63.         SetForegroundWindow(wnd);  
  64.         //場合によっては、AttachThreadInputで  
  65.         //前面に出したいウインドのスレッドにあタッチが必要  
  66.       end;  
  67.     end;  
  68.   
  69.   finally  
  70.    ProcessList.Free;  
  71.   end;  
  72. end;  
  73.   
  74. end.  

プロセスリストを表示する(その2)

Project jediのJclのJclSysInfoユニットにある。RunningProcessesList関数を使用すると
プロセスリストが簡単にとれます。

以下、サンプル

  1. procedure TForm1.Button1Click(Sender: TObject);  
  2. unit Unit1;  
  3.   
  4. interface  
  5.   
  6. uses  
  7.   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,  
  8.   Dialogs, StdCtrls, ExtCtrls;  
  9.   
  10. type  
  11.   TForm1 = class(TForm)  
  12.     LabeledEdit1: TLabeledEdit;  
  13.     Button1: TButton;  
  14.     ListBox1: TListBox;  
  15.     procedure FormCreate(Sender: TObject);  
  16.   private  
  17.     { Private 宣言 }  
  18.   public  
  19.     { Public 宣言 }  
  20.   end;  
  21.   
  22. var  
  23.   Form1: TForm1;  
  24.   
  25. implementation  
  26. Uses JclSysInfo;  
  27.   
  28. {$R *.dfm}  
  29.   
  30. procedure TForm1.FormCreate(Sender: TObject);  
  31. var  
  32.  ProcessList : TStringList;  
  33.   i : Integer;  
  34.   Pid : Cardinal;  
  35.   
  36. begin  
  37.  ListBox1.Clear;  
  38.   ProcessList := TStringList.Create;  
  39.   try  
  40.   JclsysInfo.RunningProcessesList(ProcessList,true);  
  41.     for i := 0 to ProcessList.Count-1 do  
  42.     begin  
  43.       Pid := GetPidFromProcessName(ProcessList.Strings[i]);  
  44.       ListBox1.Items.Add('(' + IntToStr(Pid) + ')' + ProcessList.Strings[i]);  
  45.     end;  
  46.   
  47.   finally  
  48.    ProcessList.Free;  
  49.   end;  
  50.   
  51. end;  

RunningProcessesListは、引数で指定したTStringsを継承した型インスタンスに
プロセスのリストを返してくれます。

このJclSysInfoユニット、ざっと見た感じで、便利そうなものが一杯あった。
サンプルプログラムを元にもうチョットみてみよう。