2014年6月7日土曜日

C# で AutoIt的なもの 1 ( WinExists )

やりたいこと
AutoIt的なものを自前でやってみたいなぁとおもってます。
まずは、簡単そうなWinExsists()を作ってみようかと思います
AutoItのWinExistsってどんな関数?
引数titleとマッチする、ウィンドウがあるかどうかを教えてくれる関数です。
比較する対象は、ウィンドウタイトル / クラス名 / ウィンドウハンドルです。
詳細はこちら、
http://www.autoitscript.com/autoit3/docs/functions/WinExists.htm
bool WinExists ( 
    "title"     // チェックする title/hWnd/class 
    [, "text"]  // オプションの引数  ウィンドウのどっかにあるテキストと比較するみたい。
)
自前のWinExistsは?
自前の関数では、以下のようにしたいと思います。
(1) オプションの引数は、ひとまずよくわからないので、除外して考えます。
(2) hWndでもチェックできますが、難しそうなのでやめておこうかと思います。
(3) 文字列は、大文字/小文字は考慮せずに、含まれているかどうかで判断する。
ちょっとシンプルになってこんな感じの関数となります。
bool WinExists ( 
    "title"     // チェックする title/class 
)
こんな風にしました。
UIはこんな感じです。

このまえやったEnumwindowをちょろっと変えて、作りました。

ソース

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 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
    {
        public delegate bool EnumWindowsProc(IntPtr hWnd, ref ArrayList data);
        
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        protected static extern int GetWindowText(IntPtr hWnd, StringBuilder strText, int maxCount);
        
        [DllImport("user32.dll", CharSet = CharSet.Unicode)]
        protected static extern int GetWindowTextLength(IntPtr hWnd);
        
        [DllImport("user32.dll")]
        public static extern bool EnumWindows(EnumWindowsProc enumProc, ref ArrayList data);
        
        [DllImport("user32.dll")]
        protected static extern bool IsWindowVisible(IntPtr hWnd);

        [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        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 件のコメント:
コメントを投稿