前言:

一個視窗(Window Form、瀏覽器、資料夾視窗),的內容那麼多,

要如何抓取一個視窗下的所有文字呢?(請參考 AutoIt3 的 AutoIt Window Info 的功能,更強大)

 

觀念:

1.一個視窗可以當作一個控件,而控件的Text就是這控件的文字,

 (ex. 一個視窗當成控件,此視窗的Text的文字,就是Title的文字)

 (ex. 一個確定的按鈕,此按鈕的Text的文字,就是"確定")

2.視窗下的內容,可以看成視窗下的所有控件的Text

 

實作:

要如何抓取一個視窗下的所有文字呢?

1.抓取視窗最上層的Handle (Parent Handle)

 (此篇重點不在這,怎麼實作請參考下方連結)

2.接下來要得到此 Parent Handle 下的所有子控件 (Child Handle)

 a.加入Dll參考

  DllImport 需 using System.Runtime.InteropServices;

  IntPtr 型態則需 using System;


[DllImport("user32.dll")]
        public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam);


// 取得控件的文字(Text)
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        internal static extern int GetWindowText(IntPtr hWnd, [Out, MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpString, int nMaxCount);

        //抓取TextBox的內文會用到
        [DllImport("User32.dll")]
        static extern int SendMessage(IntPtr hWnd, int Msg, int wParam, StringBuilder lParam);


 

 b.需要定義以上API函數的回調函數(CallBack Function)代理:


  // 回調函數代理  
        public delegate bool CallBack(int hwnd, int lParam);


 

 c.主要實作內容的函數


// 抓取到每一個子控件後要做的事
        public static bool ChildWindowProcess(int hwnd, int lParam)
        {   
            StringBuilder title = new StringBuilder(1024);


            int len;
            len = GetWindowText(new IntPtr(hwnd), title, title.Capacity);

            if (len > 0)
            {
                keyWord += title.ToString()+ "\r\n";
            }
            else // 可能為TextBox,注意,TextBox用以上方法抓取不到,所以改為以下方法
            { 
                
int WM_GETTEXT = 0x000D;
             int num = SendMessage(new IntPtr(hwnd), WM_GETTEXT, title.Capacity, title);
                if(title.Length > 0)
                    keyWord += title.ToString()+ "\r\n";
            }

            return true;
        }


 

 d.將主要實作內容函數加入CallBack Function


 public static CallBack callBackEnumChildWindows = new CallBack(ChildWindowProcess);


 

 e.然後在你的主程式碼中,想要的地方加入


string keyWord = "";
EnumChildWindows(hParentWindow, callBackEnumChildWindows, 0);


 

 f.然後 keyWord 是這個視窗下的所有文字了

 

解說:

EnumChildWindows(),會根據傳入的 Parent Handle 找到以下的所有Child Handle,

而每一個 Child Handle 都會呼叫CallBack Function 去處理他。

 

而 CallBack Function 的實作,就是先步驟 2b,

然後做一個 Function ,內容為取得每一個Child Handle 後要做的事,步驟 2c,

然後拿去註冊成 CallBack Function 步驟 2d。

 

當你的程式碼跑到 EnumChildWindows(hParentWindow, callBackEnumChildWindows, 0); 時

它就會找到 hParentWindow 下的所有 Child Handle ,

Child Handle 都會傳進你所註冊的 callBackEnumChildWindows 跑程式碼。

 

參考: 

1.MSDN Window Functions http://msdn.microsoft.com/en-us/library/ff468919(v=VS.85).aspx

2.取得 Parent Handle http://jimmy1p4204.pixnet.net/blog/post/13459931

3.C#中捕捉对话框的文本内容 EnumChildWindows http://www.chenjiliang.com/Article/View.aspx?ArticleID=2117

後記:

1.抓取到Child Handle,除了Text,或許還能抓到其他資訊。

2.目前會有抓取不到網址列的問題,資料夾的網址列或者是瀏覽器的網址列都是。

 (原因為 TextBox 沒有 hWnd 處理,所以抓取不到,必須改用SendMessage(,WM_Gettext,,)方法,已改寫於2c中)

 

關鍵字:

打關鍵字是希望有相同問題的人,能藉由關鍵字搜尋到這篇。

抓取視窗下的內容 抓取視窗下的資訊 抓取視窗下的所有文字 抓取視窗下的控件 Window Handle Control 

arrow
arrow
    全站熱搜

    GiMi 發表在 痞客邦 留言(0) 人氣()