2014年5月28日水曜日

C# Enumwindow

やりたいこと
c#でwin32apiのEnumwindowを呼び出して、ウィンドウの一覧を作成する。
こういうものを作りたい。

参考にしたサイト
(1)C# で ウィンドウを列挙する方法1
http://code.msdn.microsoft.com/windowsdesktop/Enumerate-top-level-9aa9d7c1
(2)C# で ウィンドウを列挙する方法2
http://dobon.net/vb/dotnet/process/enumwindows.html
(3)LPARAMで情報やり取りする方法
http://stackoverflow.com/questions/8949652/do-windows-api-enumwindows-and-enumchildwindows-functions-behave-differently-in

どうやるの?
(1) 参考にしたサイト(1)のサイトからサンプルコードをダウンロードして、コピペする。
(2) Win32を別のclassにした。 (必須ではないです。)
※適宜protected -> publicに置き換え
(3) IntPtr lParam を Arraylist に置き換え。
というような感じでできた。
このような感じになる。
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;

namespace AutoTest2
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            ArrayList alist = new ArrayList();

            Win32.EnumWindows(new Win32.EnumWindowsProc(Win32.EnumTheWindows), ref alist);

           foreach (string str in alist)
           {
               label1.Text += str + Environment.NewLine;
           }
        }
    }

    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);
        public static bool EnumTheWindows(IntPtr hWnd, ref ArrayList alist)
        {
            int size = GetWindowTextLength(hWnd);
            if (size++ > 0 && IsWindowVisible(hWnd))
            {
                StringBuilder sb = new StringBuilder(size);
                GetWindowText(hWnd, sb, size);
                alist.Add(sb.ToString());
            }
            return true;
        }
    }

}



苦労した点
Win32APIで取得ウィンドウの一覧をForm側に戻す方法がよくわからず、苦戦した。
マーシャリング / アンマネージとかがよく分かってないためと思ってます。


注意事項
ひとまず、動作してますが、マーシャリングをよくわかっていいので、本当にこれでよいのか不安です。
0 件のコメント:
コメントを投稿