やりたいこと
AutoIt的なものを自前でやってみたいなぁの2回目となります今回は、WinActive()を作ってみようかと思います
AutoItのWinActiveってどんな関数?
HANDLE WinExists ( "title" // チェックする title/hWnd/class [, "text"] // オプションの引数 ウィンドウのどっかにあるテキストと比較するみたい。 )引数(title)と合致するウィンドウが存在して、かつ、activeかどうかを教えてくれる関数です。
比較する対象は、ウィンドウタイトル / クラス名 / ウィンドウハンドルです。
詳細はこちら、
http://www.autoitscript.com/autoit3/docs/functions/WinActive.htm
戻り値は成功すると、ウィンドウハンドルが返り、失敗すると0が返る。
自前のWinActiveは?
自前の関数では、WinExistと同じように少し簡単にして次のようにします。(1) オプションの引数は、ひとまずよくわからないので、除外して考えます。
(2) hWndでのチェックは、難しそうなのでやめておこうかと思います。
(3) 文字列は、大文字/小文字は考慮せずに、含まれているかどうかで判断する。
(4) 戻り値はboolとする。
bool WinActive( "title" // チェックする title/class )
こんな風にしました。
UIはこんな感じです。ウィドウがアクティブかどうかの確認は、Win32Apiの、GetForegroundWindow()を使用しました。
ソースコードは、こちらになります。
ソース
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; //add using System.Runtime.InteropServices; using System.Collections; using System.Text.RegularExpressions; namespace AutoTest2 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void btnWinExist_Click(object sender, EventArgs e) { bool bExists = WinExists( tBWinExistTitle.Text ); if (bExists) { // あった。 tBWinExistRet.Text = "Exist"; } else { // なかった。 tBWinExistRet.Text = "Not Exist"; } } private void btnWinActive_Click(object sender, EventArgs e) { bool bRet = WinActive(tbWinActiveTitle.Text); if (bRet) { // Active tBWinActiveRet.Text = "Active"; } else { // Not tBWinActiveRet.Text = "Not"; } } //-------------------- // WindowのActiveかどうかの確認 細かくいうと、存在する かつ アクティブ //-------------------- private bool WinActive(string title) { bool bret = false; bool bExist = WinExists(title); if (bExist) { // active な windowの情報を取得 IntPtr hWnd = Win32.GetForegroundWindow(); int size = Win32.GetWindowTextLength(hWnd); if (size++ > 0 && Win32.IsWindowVisible(hWnd)) { // ウィンドウタイトル StringBuilder sbTitle = new StringBuilder(size); Win32.GetWindowText(hWnd, sbTitle, size); // class name StringBuilder className = new StringBuilder(256); Win32.GetClassName(hWnd, className, className.Capacity); if (((sbTitle.ToString().IndexOf(title, StringComparison.OrdinalIgnoreCase)) >= 0) || ((className.ToString().IndexOf(title, StringComparison.OrdinalIgnoreCase)) >= 0)) { bret = true; } } } return bret; } //-------------------- // Windowの存在確認 //-------------------- private bool WinExists(string title) { bool bret = false; if (!title.Equals(string.Empty)) // 入力されなかったらやめる。 { // 存在するウィンドウのタイトルとクラス名の一覧を取得 ArrayList alist = new ArrayList(); Win32.EnumWindows(new Win32.EnumWindowsProc(Win32.EnumTheWindows), ref alist); // マッチするかチェック。 foreach (WndInfo winf in alist) { // titleとマッチするか? if (winf.title.IndexOf(title, StringComparison.OrdinalIgnoreCase) >= 0) { bret = true; break; } // クラス名とマッチするか? if (winf.className.IndexOf(title, StringComparison.OrdinalIgnoreCase) >= 0) { bret = true; break; } } } return bret; } } //-------------------- // win32 api //-------------------- public class Win32 { // for Enumwindow public delegate bool EnumWindowsProc(IntPtr hWnd, ref ArrayList data); [DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount); [DllImport("user32.dll", CharSet = CharSet.Unicode)] public static extern int GetWindowTextLength(IntPtr hWnd); [DllImport("user32.dll")] public static extern bool EnumWindows(EnumWindowsProc enumProc, ref ArrayList data); [DllImport("user32.dll")] public static extern bool IsWindowVisible(IntPtr hWnd); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); // for getforegroundwnd [DllImport("user32.dll")] public static extern IntPtr GetForegroundWindow(); public static bool EnumTheWindows(IntPtr hWnd, ref ArrayList alist) { int size = GetWindowTextLength(hWnd); if (size++ > 0 && IsWindowVisible(hWnd)) { // ウィンドウタイトル StringBuilder sbTitle = new StringBuilder(size); GetWindowText(hWnd, sbTitle, size); // class name StringBuilder className = new StringBuilder(256); GetClassName(hWnd, className, className.Capacity); alist.Add(new WndInfo(sbTitle.ToString(), className.ToString())); } return true; } } //-------------------- // window の情報 を保持する 構造体 //-------------------- public struct WndInfo { public string title; public string className; public WndInfo(string Title, string ClassName) { title = Title; className = ClassName; } } }
0 件のコメント:
コメントを投稿