如何用Vb.net查找到另外一个应用程序中的文本框控件,并实现赋值
我希望用自己写的应用程序,实现对另外一个应用程序的登陆框中的用户名和密码自动赋值,考虑如下实现,
1.在自己的应用程序中(A)启动另外一个应用程序(B)
2.模拟B的菜单点击弹出登陆窗口
3.往B的登陆界面中的两个文本框赋值,然后模拟点击窗口上的确定按钮.
程序(A)代码如下
Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Integer) As Integer
Private Const WM_COMMAND As Integer = &H111
Private Const BM_CLICK = &HF5
Private Const WM_SETTEXT = &HC
Dim g3eHWnd As Integer = 0
Dim newProcess As Process = New Process()
newProcess.StartInfo.FileName = "c:\B.exe"
newProcess.Start()
newProcess.WaitForInputIdle()
'newPrecoess.WaitForExit(2000)
g3eHWnd = newProcess.MainWindowHandle '得到B的主窗口界面句柄
SendMessage(g3eHWnd, WM_COMMAND, 40117, 0&) '模拟B菜单操作,然后会弹出登陆窗口
'下面就不会写了
'我理解是这么来实现
'得到B的登陆窗口的句柄,然后递归查找上面的控件,得到需要的文本框的句柄,然后仍然用
'SendMessage 赋值 ,我不知道怎样才能得到刚弹出登陆窗口的句柄,并在上面找到我需要的文本框,
'用spy++ 看了登陆窗口,无法得到文本框ID,也无法从caption等来区分。
'查过一些例子,一定要用到EnumChildWindows么,我看不太懂,希望贴出代码来!
再有个问题就是,如果我在newProcess.WaitForInputIdle() 后,如果马上执行newProcess.MainWindowHandle
得不到数值,好像是程序的主窗口界面还没有加载完成,所以我又执行了'newPrecoess.WaitForExit(2000) 来等待两秒钟,
这个办法我知道不好,但是为什么阿?还有别的办法么,本来想用循环来求newProcess.MainWindowHandle 是否等于0来判断,
也不行,newProcess.MainWindowHandle 在代码里只能执行一次,如果第一次求得是0,以后永远都是0,为什么呢?如果解决呢
--------------------编程问答-------------------- 不会,帮你顶 --------------------编程问答-------------------- 通过主窗口的句柄循环得到里面的控件然后发消息
SendMessage(hwnd,WM_SETTEXT,"改变文本") --------------------编程问答-------------------- 你可以看看这篇文章,也许有帮助
http://www.4oa.com/Article/html/6/34/493/2005/17922.html --------------------编程问答-------------------- 刚才发的文章不对,这次对了,
你看看这篇
http://www.chenjiliang.com/Article/View.aspx?ArticleID=2117&TypeID=84
--------------------编程问答-------------------- 是的,我也知道可能需要用EnumChildWindows,不过不会写。还有就是如果找到,怎么才能判别每个文本框是我需要的? --------------------编程问答-------------------- 帮顶 ~ --------------------编程问答-------------------- 有没有人知道啊? --------------------编程问答-------------------- //遍历进程
Process[] foundProcess = Process.GetProcessesByName(listBox1.SelectedItem.ToString());
foreach (Process p in foundProcess)
{
Win32.EnumChildWindows(p.MainWindowHandle.ToInt32(), Win32.childWindowProcess, 255);
}
//Win32中的函数
[DllImport("user32.dll")]
public static extern bool IsWindowVisible(int hwnd);
[DllImport("user32.dll")]
public static extern int GetWindowText(int hwnd,
StringBuilder buf, int nMaxCount);
[DllImport("user32.dll")]
public static extern int GetClassName(int hwnd,
[MarshalAs(UnmanagedType.LPStr)] StringBuilder buf,
int nMaxCount);
[DllImport("user32.dll")]
public static extern int GetWindowRect(int hwnd, ref RECT rc);
[DllImport("user32.dll")]
// 注意,运行时知道如何列集一个矩形
public static extern int GetWindowRect(int hwnd, ref Rectangle rc);
[DllImport("User32.Dll")]
public static extern void SetWindowText(int h, String s);
[DllImport("user32.dll")]
public static extern int EnumChildWindows(int hWndParent, EnumChildWndProc lpfn, int lParam);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
[DllImport("user32.dll")]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam,
int lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr SendMessage(IntPtr hWnd, int msg, int
wParam,ref SYSTEMTIME lParam);
/// <summary>
/// 回调函数代理
/// </summary>
public delegate bool EnumChildWndProc(int hwnd, int lParam);
/// <summary>
/// 子窗口回调函数代理
/// </summary>
public static EnumChildWndProc childWindowProcess = new EnumChildWndProc(ChildWindowProcess);
/// <summary>
/// 子窗口回调处理函数
/// </summary>
/// <param name="hwnd"></param>
/// <param name="lParam"></param>
/// <returns></returns>
public static bool ChildWindowProcess(int hwnd, int lParam)
{
StringBuilder s = new StringBuilder(256);
Win32API.Win32.GetWindowText(hwnd, s, s.Capacity);
StringBuilder bb = new StringBuilder(255);
Win32.GetClassName(hwnd, bb, 255);
//StringBuilder dd = new StringBuilder(255);
//Win32.GetClassInfo(hwnd, dd, 255);
//为可输入控件赋值
const int WM_SETTEXT = 0x000C;
//SendMessage((IntPtr)hwnd, WM_SETTEXT, (IntPtr)0, "123");
//模拟单击
const int WM_CLICK = 0x00F5;
//SendMessage((IntPtr)hwnd, WM_CLICK, (IntPtr)0, "0");
//为下拉控件赋值
const int WM_CLICK2 = 0x014D;
//SendMessage((IntPtr)hwnd, WM_CLICK2, (IntPtr)0, "123");
//向下拉控件添加值
const int WM_CLICK3 = 0x0180;
//SendMessage((IntPtr)hwnd, WM_CLICK3, (IntPtr)0, "123");
//展开日期下拉
const int wm_syskeydown = 0x0104, vk_down = 0x28;
//SendMessage((IntPtr)hwnd, wm_syskeydown, vk_down, 0);
return true;
} --------------------编程问答-------------------- --------------------编程问答-------------------- 如果你要发送的是.net的可能不可以。没试过。 --------------------编程问答-------------------- 用这样的代码就可以找到你要的控件,然后用sendmessage模拟按键好了
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function FindWindowEx Lib "user32" Alias "FindWindowExA" (ByVal hWnd1 As Long, ByVal hWnd2 As Long, ByVal lpsz1 As String, ByVal lpsz2 As String) As Long
'以下是查找窗口 WindowsForms10.BUTTON.app.0.bf7d44 的代码:
Private Function MyFindWindow() As Long
'父窗口类名数组
Dim A_szClassName(2) As String
A_szClassName(0) = "WindowsForms10.Window.8.app.0.bf7d44"
A_szClassName(1) = "WindowsForms10.BUTTON.app.0.bf7d44"
'父窗口标题数组
Dim A_szWinName(2) As String
A_szWinName(0) = "HIR品質実績一覧"
A_szWinName(1) = "倉入日基準 Excel出力"
'首先求得顶级父窗口
Dim hLastWin As Long
hLastWin = FindWindow(A_szClassName(0), A_szWinName(0))
'逐次用FindWindowEx函数求出各级子窗口
For i = 1 To 1
hLastWin = FindWindowEx(hLastWin, 0,A_szClassName(i), A_szWinName(i))
Next i
MyFindWindow = hLastWin
End Function
'举例: Dim hLastWin as Long
' hLastWin = MyFindWindow()
--------------------编程问答-------------------- 建议你用spy --------------------编程问答-------------------- 试试用Process类 --------------------编程问答-------------------- 用
machong8183
的方法写下去,看还会遇到什么样的问题
补充:.NET技术 , VB.NET