最近在群里有人說用Win32 Api不能對(duì)文本框設(shè)置內(nèi)容(是別人寫的一個(gè)程序,設(shè)置它的文本框的值).但是搞過win32的人都會(huì)說.這個(gè)應(yīng)該不難啊,大概是搞.net的人,被微軟 寵壞了.基本都不要用win32 api,這里我也不討論用這個(gè)東西好不好,反正有人有這個(gè)需求,就要去做這個(gè)東西,我就自己建了一個(gè)工程,只要得到這個(gè)窗體的句柄,然后向他發(fā)送消息就搞定了,用到FindWindow,SendMessage搞定就可以了,我們所做的最核心的內(nèi)容就是要找句柄.
要在win32 api下面使用FindWindow,SendMessage,必須這2個(gè)聲明
記得這里要加上CharSet,否則發(fā)送中文可能是亂碼,調(diào)用的時(shí)候
查找窗體的句柄,然后再在這個(gè)窗體下面查找這個(gè)文本框的句柄,窗口我們是根據(jù)窗體的標(biāo)題文本來查找,文本控件時(shí)根據(jù)控件的類型來找.
設(shè)置文本
輕松搞定了.很簡(jiǎn)單.
這個(gè)時(shí)候我想,窗體上只有一個(gè)文本框,也就是說一個(gè)Edit,查找起來是很方便,可是往往,我們?cè)趯?shí)際情況中,一個(gè)窗體上有很多文本框,我們要找到其中一個(gè)文本框設(shè)置它的值,這個(gè)時(shí)候你在用WinAPIuser32.FindWindowEx(hwndCalc, 0,"Edit",null);就做不到了.因?yàn)樗玫降?始終是最后一個(gè) 文本框的句柄,也就是說如果頁面上有
3個(gè)文本,你使用這個(gè)時(shí)候只會(huì)獲取到最后一個(gè)文本框的 句柄,如果你要設(shè)置第2個(gè)文本框你是做不到的,我們有2個(gè)辦法,一個(gè)是EnumChildWindows方法來遍歷下面的所有文本框,對(duì)這些文本框進(jìn)行賦值,第2中方法就是 根據(jù)控件ID來查找句柄,在一個(gè)程序編譯完成以后,也就是發(fā)布給客戶用的時(shí)候,窗體上的控件ID就是固定的了,不可改變,我這里說的控件ID不是指.net的立面一個(gè)TextBox控件的ID,而是在windows下面,顯現(xiàn)出來的ID,這樣我們就可以通過固定的ID來查找,注意ID是固定的,不會(huì)再改變,這樣我們就可以用GetDlgItem的方法來通過ID號(hào)來獲取句柄,這里我們先講第2中方法,第一種方法,比較復(fù)雜,而且后面我會(huì)用第一種方法來做一個(gè)非常特殊的演示,那就是如果控件ID時(shí)動(dòng)態(tài)的時(shí)候,我們也如何獲取句柄
當(dāng)然得到了句柄還有什么做不到的,對(duì)這3個(gè)文本發(fā)送消息,設(shè)置文本內(nèi)容
一切很順利,就像我們想的一樣,3個(gè)文本框的內(nèi)容都改變了,太好了,不過不要太高興了,因?yàn)槲覀冞@里的ID是固定所以都硬編碼進(jìn)去了,在一般情況下是沒有問題,因?yàn)榇蟛糠值亩际枪潭ǖ?這個(gè)時(shí)候我發(fā)現(xiàn).net的程序的控件ID時(shí)隨時(shí)改變的,而且每次運(yùn)行一次ID都不一樣,這個(gè)ID是跟著句柄改變,句柄是多少ID就是多少,老火啊.這回要根據(jù)ID來獲取句柄是獲取是行不通了,現(xiàn)在的情況是 一個(gè)頁面多個(gè)Edit類控件的ID是動(dòng)態(tài)的,程序每次運(yùn)行都不一樣,不固定.
關(guān)閉程序,再重新打開,在看下ID
那么我現(xiàn)在用第二種辦法來解決,請(qǐng)出EnumChildWindows方法,這個(gè)方法比較特殊,有個(gè)一個(gè)參數(shù)是一個(gè)回調(diào)函數(shù)
CallBack是一個(gè)委托 EnumChildWindows用來遍歷所有的子控件的句柄,有一個(gè)回調(diào)函數(shù),CallBusiness也是一個(gè)代理,是提供給客戶端調(diào)用的時(shí)候來編寫邏輯的.代碼很簡(jiǎn)單,應(yīng)該很容易理解,客戶端調(diào)用的代碼,因?yàn)槭?net開發(fā)的程序 所以 Edit的控件類型有點(diǎn)不一樣,不過沒關(guān)系,不影響我們查找
public static extern int EnumChildWindows(int hWndParent, CallBack lpfn, int lParam);
public static extern int EnumChildWindows(int hWndParent, CallBack lpfn, int lParam);
/// <summary>
/// 回調(diào)業(yè)務(wù)
/// </summary>
public delegate void CallBusiness(IntPtr hwnd);
public delegate bool CallBack(IntPtr hwnd, int lParam);
/// <summary>
/// 遍歷子窗體的父窗體句柄
/// </summary>
public static CallBack callBackEnumChildWindows = new CallBack(ChildWindowProcess);
/// <summary>
/// 委托業(yè)務(wù),需要客戶端添加
/// </summary>
public static CallBusiness CallFuntion;
/// <summary>
/// 遍歷子窗體或控件
/// </summary>
/// <param name="hWnd"></param>
/// <param name="lParam"></param>
/// <returns></returns>
public static bool EnumChildWindows(IntPtr hWnd, int lParam)
{
EnumChildWindows(hWnd.ToInt32(), callBackEnumChildWindows, 0);
return true;
}
/// <summary>
/// 獲取類名字
/// </summary>
/// <param name="hwnd">需要獲取類名的句柄</param>
/// <param name="lpClassName">類名(執(zhí)行完成以后查看)</param>
/// <param name="nMaxCount">緩沖區(qū)</param>
/// <returns></returns>
[DllImport("user32.dll", EntryPoint = "GetClassName")]
public static extern int GetClassName(
IntPtr hwnd,
StringBuilder lpClassName,
int nMaxCount
);
/// <summary>
/// 遍歷子控件
/// </summary>
/// <param name="hwnd"></param>
/// <param name="lParam"></param>
/// <returns></returns>
public static bool ChildWindowProcess(IntPtr hwnd, int lParam)
{
if (CallFuntion != null)
{
CallFuntion(hwnd);
}
return true;
}
代碼會(huì)提供下載,不明白的可以自己仔細(xì)看看.
聯(lián)系客服