やりたいこと
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;
}
}
}