c#调windows API操作键鼠

  前两天去面试一公司,流程的最后面我主管让我上机,原题说是自动打开浏览器去点某个页面,我说可以打开浏览器进程去xxxx...,然而他的本意并非如此。后来我总算听懂了,大意是做一个类似于“按键精灵”的功能,题目则改为移动鼠标去双击点开某个qq好友进入聊天对话框,允许上网查资料。

  好在我查到了这篇https://www.2cto.com/kf/201410/343342.html

  关键代码均来自源于此,稍微改了一下。

 

//1、windowsApi.cs

 1 using System;
 2 using System.Runtime.InteropServices;
 3 
 4 namespace demo
 5 {
 6     //结构体布局 本机位置
 7     [StructLayout(LayoutKind.Sequential)]
 8     public struct NativeRECT
 9     {
10         public int left;
11         public int top;
12         public int right;
13         public int bottom;
14     }
15 
16     //将枚举作为位域处理
17     [Flags]
18     public enum MouseEventFlag : uint //设置鼠标动作的键值
19     {
20         Move = 0x0001,               //发生移动
21         LeftDown = 0x0002,           //鼠标按下左键
22         LeftUp = 0x0004,             //鼠标松开左键
23         RightDown = 0x0008,          //鼠标按下右键
24         RightUp = 0x0010,            //鼠标松开右键
25         MiddleDown = 0x0020,         //鼠标按下中键
26         MiddleUp = 0x0040,           //鼠标松开中键
27         XDown = 0x0080,
28         XUp = 0x0100,
29         Wheel = 0x0800,              //鼠标轮被移动
30         VirtualDesk = 0x4000,        //虚拟桌面
31         Absolute = 0x8000
32     }
33     class WindowsAPI
34     {
35         //设置鼠标位置
36         [DllImport("user32.dll")]
37         public static extern bool SetCursorPos(int X, int Y);
38 
39         //设置鼠标按键和动作
40         [DllImport("user32.dll")]
41         public static extern void mouse_event(MouseEventFlag flags, int dx, int dy,
42             uint data, UIntPtr extraInfo); //UIntPtr指针多句柄类型
43 
44         [DllImport("user32.dll")]
45         public static extern IntPtr FindWindow(string strClass, string strWindow);
46 
47         //该函数获取一个窗口句柄,该窗口雷鸣和窗口名与给定字符串匹配 hwnParent=Null从桌面窗口查找
48         [DllImport("user32.dll")]
49         public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
50             string strClass, string strWindow);
51 
52         [DllImport("user32.dll")]
53         public static extern bool GetWindowRect(HandleRef hwnd, out NativeRECT rect);
54     }
55 }
View Code

 //2、业务逻辑

 1 using System;
 2 using System.Runtime.InteropServices;
 3 using System.Windows.Forms;
 4 
 5 namespace demo
 6 {
 7     public partial class Form1 : Form
 8     {
 9         public Form1()
10         {
11             InitializeComponent();
12         }
13 
14         private void button1_Click(object sender, EventArgs e)
15         {
16             NativeRECT rect;
17             //获取主窗体句柄
18             IntPtr ptrDeskTopbar = WindowsAPI.FindWindow("Shell_TrayWnd", null);
19             if (ptrDeskTopbar == IntPtr.Zero)
20             {
21                 MessageBox.Show("No windows found!");
22                 return;
23             }
24 
25             //获取子窗体
26             IntPtr childPtr = WindowsAPI.FindWindowEx(ptrDeskTopbar, IntPtr.Zero, "TrayNotifyWnd", null);
27             if (childPtr == IntPtr.Zero)
28             {
29                 MessageBox.Show("No child windows found!");
30                 return;
31             }
32 
33             IntPtr ccPtr = WindowsAPI.FindWindowEx(childPtr, IntPtr.Zero, "SysPager", null);
34             if (ccPtr == IntPtr.Zero)
35             {
36                 MessageBox.Show("No childschild windows found!");
37                 return;
38             }
39 
40             //获取窗体大小
41             WindowsAPI.GetWindowRect(new HandleRef(this, ccPtr), out rect);
42             int X = rect.left+14;
43             int Y =rect.top+15 ;
44 
45             WindowsAPI.SetCursorPos(X, Y);
46             run_doubleClick();
47 
48             //获取qq页面的主页面句柄
49             IntPtr qqPtr = WindowsAPI.FindWindow("TXGuiFoundation", "QQ");
50             if (qqPtr == IntPtr.Zero)
51             {
52                 MessageBox.Show("No qq windows found!");
53                 return;
54             }
55             //获取窗体大小
56             WindowsAPI.GetWindowRect(new HandleRef(this, qqPtr), out rect);
57             X = rect.left + 67;
58             Y = rect.top + 278;
59 
60             WindowsAPI.SetCursorPos(X, Y);
61             run_Click();
62 
63             X = rect.left + 96;
64             Y = rect.top + 317;
65 
66             WindowsAPI.SetCursorPos(X, Y);
67             run_doubleClick();
68         }
69 
70 
71         /// <summary>
72         ///  模拟单击
73         /// </summary>
74         void run_Click()
75         {
76             WindowsAPI.mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
77             WindowsAPI.mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
78         }
79 
80         /// <summary>
81         /// 模拟双击
82         /// </summary>
83         void run_doubleClick()
84         {
85             WindowsAPI.mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
86             WindowsAPI.mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
87             WindowsAPI.mouse_event(MouseEventFlag.LeftDown, 0, 0, 0, UIntPtr.Zero);
88             WindowsAPI.mouse_event(MouseEventFlag.LeftUp, 0, 0, 0, UIntPtr.Zero);
89         }
90     }
91 }
View Code

 

关键的API解释:

public static extern IntPtr FindWindow(string strClass, string strWindow);

public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,string strClass, string strWindow);

FindWindow:根据窗体的类名和标题来获取窗体的句柄;

FindWindowEx:根据主窗口(可为空,为空时默认主窗口为桌面)句柄 和子窗口句柄(可为空),及类名和标题名(可为null)获取子窗口句柄。

其中类名和标题名可通过按键精灵来抓取,如下图:

posted on 2018-03-24 19:54  吃肉不吃菜  阅读(479)  评论(0编辑  收藏  举报

导航