1.概要
運用上、常にアクティブ状態である必要があるアプリケーションウィンドウがあります。
これが何かしらの原因で、フォーカスが失われアクティブ状態から抜けてしまうことがあります。
例えば、エラーポップアップなどがこれにあたるのではないでしょうか?
今回はこの問題を解決してみたいと思います。
2.アクティブなウィンドウ名を取得する
まずは現在アクティブな状態のウィンドウ名を取得します。
ここで重要なのはアプリケーション名ではなくウィンドウ名になります。
例えば【Chrome】で【YAHOO】のページを開いているウィンドウがアクティブな場合は
【Yahoo! JAPAN - Google Chrome】
となります。
ではどのようにして取得するのかというと
【GetForegroundWindow】でアクティブ状態のウィンドウハンドルを取得し
それをもとに【GetWindowText】でウィンドウのタイトルを取得します。
3.外部アプリをアクティブにする
方法ですが実行されているすべてのプロセスを取得し
その中から指定の文字列(アクティブにしたいウィンドウ名)を探し
一致するものがあったら
【SetForegroundWindow】にウィンドウハンドルを渡し
アクティブ状態にします。
4.スクリプト
【Form】に【Label】と【Button】を貼り付けています。
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace moveFront { public partial class Form1 : Form { [DllImport("USER32.DLL")] private static extern IntPtr GetForegroundWindow(); [DllImport("USER32.DLL",CharSet = CharSet.Auto)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder text, int length); [DllImport("USER32.DLL")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool SetForegroundWindow(IntPtr hWnd); public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { string activeAppName; StringBuilder sb = new StringBuilder(256); IntPtr hWnd = GetForegroundWindow(); // hWndはMainWindowが存在する(0ではない) if (!IntPtr.Zero.Equals(hWnd)) { int ret = GetWindowText(hWnd, sb, 256); string windowName = "メモ帳"; if (sb.ToString(0, ret) != windowName) { activeAppName = sb.ToString(0, ret); foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses()) { if (0 <= p.MainWindowTitle.IndexOf(windowName)) { SetForegroundWindow(p.MainWindowHandle); label1.Text = activeAppName + "から" + windowName + "をアクティブにしました。"; return; } } label1.Text = windowName + "は存在しません。"; } else { label1.Text = windowName + "はアクティブ状態です。"; } } } } }
5.結果
今回は【メモ帳】をターゲットにしました。
結果は下図のとおりです。
Form上にあるボタンをクリックしてから処理が走るので
【Form1からメモ帳をアクティブにしました】
となってしまいますが、やりたいことは実現出来ました。
また、
【メモ帳】が起動していない時:【メモ帳は存在しません。】
【メモ帳】がアクティブ状態 :【メモ帳はアクティブ状態です。】
となります。