- 引入需要的接口
/// <summary>
/// 查找窗口
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="title">窗口标题</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr FindWindow(IntPtr hwnd, string title);
/// <summary>
/// 移动窗口
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="x">起始位置X</param>
/// <param name="y">起始位置Y</param>
/// <param name="nWidth">窗口宽度</param>
/// <param name="nHeight">窗口高度</param>
/// <param name="rePaint">是否重绘</param>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern void MoveWindow(IntPtr hwnd, int x, int y, int nWidth, int nHeight, bool rePaint);
/// <summary>
/// 获取窗口矩形
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="rect"></param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool GetWindowRect(IntPtr hwnd, out Rectangle rect);
/// <summary>
/// 向窗口发送信息
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="msg">信息</param>
/// <param name="wParam">高字节</param>
/// <param name="lParam">低字节</param>
/// <returns></returns>
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int PostMessage(IntPtr hwnd, int msg, uint wParam, uint lParam);
public const int WM_CLOSE = 0x10; //关闭命令
public const int WM_KEYDOWN = 0x0100;//按下键
public const int WM_KEYUP = 0x0101;//按键起来
public const int VK_RETURN = 0x0D;//回车键
public const int WM_SETTEXT = 0x000C;//发送消息
public const int WM_INITDIALOG = 0x0110;//初始化
public const int WM_LBUTTONDOWN = 0x0201;//按下鼠标左键
public const int WM_LBUTTONUP = 0x0202;//释放鼠标左键
public const int WM_LBUTTONDBLCLK = 0x203; //双击鼠标左键
public const int WM_RBUTTONDOWN = 0x204;//按下鼠标右键
public const int WM_RBUTTONUP = 0x205;//释放鼠标右键
public const int WM_RBUTTONDBLCLK = 0x206;//双击鼠标右键
public static bool IsWorking = false;
/// <summary>
/// 对话框标题
/// </summary>
public static string[] titles = new string[4] { "Error", "提示", "错误", "警告" };
[DllImport("User32.dll", EntryPoint = "FindWindow")]
private static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "FindWindowEx")]
private static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
private static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
- 封装的常用方法
/// <summary>
/// 查找和移动窗口
/// </summary>
/// <param name="title">窗口标题</param>
/// <param name="x">起始位置X</param>
/// <param name="y">起始位置Y</param>
public static void FindAndMoveWindow(string title, int x, int y)
{
Thread t = new Thread(() =>
{
IntPtr msgBox = IntPtr.Zero;
while ((msgBox = FindWindow(IntPtr.Zero, title)) == IntPtr.Zero) ;
Rectangle r = new Rectangle();
GetWindowRect(msgBox, out r);
MoveWindow(msgBox, x, y, r.Width - r.X, r.Height - r.Y, true);
});
t.Start();
}
/// <summary>
/// 查找和关闭窗口
/// </summary>
/// <param name="title">标题</param>
public static void FindAndKillWindow(string title)
{
IntPtr ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
int ret = PostMessage(ptr, WM_CLOSE, 0, 0);
Thread.Sleep(1000);
ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
PostMessage(ptr, WM_KEYDOWN, VK_RETURN, 0);
PostMessage(ptr, WM_KEYUP, VK_RETURN, 0);
}
}
}
/// <summary>
/// 查找和关闭窗口
/// </summary>
public static void FindAndKillWindow()
{
Thread t = new Thread(() =>
{
while (IsWorking)
{
//按标题查找
foreach (string title in titles)
{
FindAndKillWindow(title);
}
Thread.Sleep(3000);
}
});
t.Start();
}
/// <summary>
/// 查找窗口
/// </summary>
/// <param name="title">窗口标题</param>
/// <returns>True表示找到窗口,false则未找到</returns>
public static IntPtr? FindWindows(string title)
{
IntPtr ptr = FindWindow(IntPtr.Zero, title);
if (ptr != IntPtr.Zero)
{
return ptr;
}
return null;
}
public static bool FindWindows()
{
Thread t = new Thread(() =>
{
while (IsWorking)
{
//按标题查找
foreach (string title in titles)
{
FindWindows(title);
}
Thread.Sleep(3000);
}
});
t.Start();
return false;
}
- 根据窗口的关系获取控件
可以通过spy++获取控件的类型名称
var ptr=FindWindows("打开");
//IntPtr hwnd = FindWindow("#32770 (对话框)", "MainWindow"); //FindWindow只查找顶层窗口
//IntPtr htextbox = FindWindowEx(ptr.Value, IntPtr.Zero, "wxWindowClassNR", null);//(当前为第一层)IntPtr.Zero则表示获得第一个子窗口。第三个参数表示你需要找的子窗口的类型,第四个参数一般为null。
//IntPtr htextbox2 = FindWindowEx(hwnd, IntPtr.Zero, "wxWindowClassNR", null);//(当前为第一层)IntPtr.Zero则表示获得第一个子窗口。第三个参数表示你需要找的子窗口的类型,第四个参数一般为null。
//IntPtr htextbox2 = FindWindowEx(hwnd, htextbox, "EDIT", null);//填上次获得的句柄,可以得到下一个的句柄。
//SendMessage(ptr.Value, WM_SETTEXT, IntPtr.Zero, "123232");//发送消息
IntPtr htextbox2 = FindWindowEx(ptr.Value, IntPtr.Zero, "ComboBoxEx32", null);//填上次获得的句柄,可以得到下一个的句柄。
IntPtr htextbox22 = FindWindowEx(htextbox2, IntPtr.Zero, "ComboBox", null);//填上次获得的句柄,可以得到下一个的句柄。
IntPtr edit = FindWindowEx(htextbox22, IntPtr.Zero, "Edit", null);//填上次获得的句柄,可以得到下一个的句柄。
//SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "D:\\work\\code");//发送消息
//SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "C:\\Users\\xx\\Desktop\\t\\WeChat_20241109200005.mp4");//发送消息
SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "C:\\Users\\xx\\Desktop\\t\\test.mp4");//发送消息
IntPtr openBtn = FindWindowEx(ptr.Value, IntPtr.Zero, "Button", null);//填上次获得的句柄,可以得到下一个的句柄。
//SendMessage(openBtn, WM_KEYDOWN, IntPtr.Zero, "D:\\work\\code");//发送消息
SendMessage(openBtn, WM_LBUTTONDOWN, IntPtr.Zero, null);//鼠标按下按钮
SendMessage(openBtn, WM_LBUTTONUP, IntPtr.Zero, null);//释放鼠标
[参考]
c#获取句柄,并对第三方软件的输入框和按钮进行控制