现需要捕获天翼通无线上网客户端
通过System.Diagnostics.Process.Start()启动并取得窗体句柄
但是不知道如何去模仿鼠标点击里面的自动连接按钮注:FindWindowEx无效,找不到自动连接按钮的句柄。SPY++分析亦找不到对应的BUTTON
请各位给点意见,有源码更好,谢谢。
通过System.Diagnostics.Process.Start()启动并取得窗体句柄
但是不知道如何去模仿鼠标点击里面的自动连接按钮注:FindWindowEx无效,找不到自动连接按钮的句柄。SPY++分析亦找不到对应的BUTTON
请各位给点意见,有源码更好,谢谢。
private static extern IntPtr FindWindow( string lpClassName, string lpWindowName );
[DllImport ( "user32.dll", EntryPoint = "FindWindowEx", SetLastError = true )]
private static extern IntPtr FindWindowEx( IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow );
[DllImport ( "user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto )]
private static extern int SendMessage( IntPtr hwnd, uint wMsg, int wParam, int lParam );
[DllImport ( "user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true )]
private static extern void SetForegroundWindow( IntPtr hwnd )
const uint BM_CLICK = 0xF5;
IntPtr hwndC= FindWindow ( null, "" );
if ( hwndC!= IntPtr.Zero )
{
IntPtr hwnd = FindWindowEx ( hwndC, 0, null, "1" );
SetForegroundWindow ( hwndC );
SendMessage (hwnd , BM_CLICK, 0, 0 );
}
2楼的方法我试过,就是FindWindowEx根本早不到对应的BUTTON,用SPY++也找不到
int x=25,y=193;//btn坐标
int xy = (y << 16) + x;
MyApi.SendMessage(ip, MOUSEEVENTF_LEFTDOWN, 0, xy);
MyApi.SendMessage(ip, MOUSEEVENTF_LEFTUP, 0, xy);
谢谢你的回复。不过,SENDMESSAGE无效啊
用SPY++的日志消息监视你点击按钮时出现了哪些消息,最后直接模拟消息
那么就是那个按钮。不是一个控件,
需要用别的方法了。比如钩子。
public class WinAPI
{
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[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 SetActiveWindow(IntPtr hWnd);
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
}
///调用
假定被启动的窗体(窗体text内容):flash
窗体按纽(按纽text内容):begin
首先启动那个窗体程序,然后执行下面程序:
const int WM_CLICK = 0x00F5;
IntPtr window;
while (true) //循环抓取,抓到为止
{
window = WinAPI.FindWindow(null, "flash");
if (window.ToInt32() != 0)
{
break;
}
}
WinAPI.SetActiveWindow(window); //激活抓到的窗体
WinAPI.SetForegroundWindow(window); //设置该窗体为顶层窗体
//抓按纽,并发送点击命令
IntPtr EdithWnd = new IntPtr(0);
EdithWnd = WinAPI.FindWindowEx(window, EdithWnd, "Button", "begin");
if (!EdithWnd.Equals(IntPtr.Zero))
{
WinAPI.SendMessage(EdithWnd, WM_CLICK, (IntPtr)0, "0");
}
这里按纽text内容"begin",如果第一个字母b下有下滑线,你可以写成"&begin"。
窗体句柄可以找到,但找不到按钮句柄FindWindowEx无效。
/*
某些控件是直接绘制出来的,不是一个单独控件
找不到句柄的话,说明这个控件根本就没有句柄
这里你可以找到按钮所在位置
然后去发送WM_LBUTTONDOWN WM_LBUTTONUP(即使你的目标程序不在最顶端也可以发送有效的)
*/
PostMessage(hwnd,WM_LBUTTONDOWN,MK_LBUTTON,MAKELPARAM(x,y));
PostMessage(hwnd,WM_LBUTTONUP,0,MAKELPARAM(x,y)));
public static extern IntPtr CreateToolhelp32Snapshot(uint flags, uint processid);
[DllImport("KERNEL32.DLL ")]
public static extern int CloseHandle(IntPtr handle);
[DllImport("KERNEL32.DLL ")]
public static extern int Process32First(IntPtr handle, ref ProcessEntry32 pe);
[DllImport("KERNEL32.DLL ")]
public static extern int Process32Next(IntPtr handle, ref ProcessEntry32 pe);
[DllImport("KERNEL32.DLL ")]
public static extern IntPtr OpenProcess(uint dwDesiredAccess, bool bInheritHandle, uint dwProcessId);
[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.dll", EntryPoint = "FindWindowEx", SetLastError = true)]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, uint hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll", EntryPoint = "SendMessage", SetLastError = true, CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hwnd, uint wMsg, int wParam, int lParam);
[DllImport("user32.dll", EntryPoint = "SetForegroundWindow", SetLastError = true)]
private static extern void SetForegroundWindow(IntPtr hwnd); public delegate bool CallBack(IntPtr hwnd, int lParam);
[DllImport("user32.dll")]
public static extern int EnumChildWindows(IntPtr hWndParent, CallBack lpfn, int lParam); [DllImport("user32.dll", EntryPoint = "GetWindowText")]
public static extern int GetWindowText(IntPtr hwnd,StringBuilder lpString,int cch);
[DllImport("user32.dll ", EntryPoint = "GetDlgItem")]
public static extern IntPtr GetDlgItem(IntPtr hParent, int nIDParentItem);
[DllImport("user32.dll")]
public static extern uint GetWindowThreadProcessId(IntPtr hWnd,out uint dwProcessId);
[DllImport("kernel32.dll")]
public static extern IntPtr VirtualAllocEx(IntPtr hProcess, IntPtr lpAddress,uint dwSize, uint flAllocationType, uint flProtect); [DllImport("kernel32.dll")]
public static extern bool VirtualFreeEx(IntPtr hProcess, IntPtr lpAddress,uint dwSize, uint dwFreeType); [DllImport("kernel32.dll")]
public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress,IntPtr lpBuffer, int nSize, ref uint vNumberOfBytesRead);
以上API全部试过,均无效果
http://msdn.microsoft.com/zh-cn/library/aa686045.aspx
System.Diagnostics.Process wc = System.Diagnostics.Process.Start(@"D:\Chinatelecom C+W\C+WClient.exe");
System.Threading.Thread.Sleep(5000);
IntPtr hwndCalc = wc.MainWindowHandle; // 等同于FindWindow窗体句柄已经活得,无奈里面的BUTTON句柄无法获取
SPY++也找不到相关按钮
如果用模仿鼠标点击的话,位置必须得固定。(多系统多显示器下很难控制这点)所以此举不可取
不好意思,文章只是介绍 P/Invoke 编程,系统API调用。
你找到form的坐标 然后 加上你的按钮的相对位置就是它的坐标了