前言:
一個視窗(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
留言列表