想必有很多人在項目開發中可能遇見需要做模擬鼠標點擊的小功能,很多人會在
百度過后采用mouse_event這個函數,不過我并不想討論如何去使用mouse_event
函數怎么去使用,因為那沒有多大意義。
- static void mouse_event(int dwFlags, int dx, int dy, int cButtons, int dwExtraInfo)
- {
- int x = dx, y = dy;
- edit_position(dwFlags, dx, dy, ref x, ref y);
- IntPtr hWndFromPoint = WindowFromPoint(x, y);
- screen_to_client(hWndFromPoint, ref x, ref y);
- send_message(hWndFromPoint, dwFlags, cButtons, x, y);
- }
上述代碼你發現了什么?如果你發現說明你知道了本文到底在寫什么東東 說不定你
會有一些興趣看下去,不過想到我如今混那么凄慘 在工地上做干活 不過也還好。
鼠標點擊目標時會向鼠標所點擊目標窗口投遞消息,根據鼠標的按鍵、狀態不同會
投遞不同的消息,一個完整的“鼠標左鍵單擊”事件過程為“WM_LBUTTONDOWN +
WM_LBUTTONUP”即鼠標“先左鍵按下 + 后左鍵抬起”,由于mouse_event可以模擬
鼠標點擊過程而不是直接性一次完整的鼠標單擊過程,所以同樣存在“按下、抬起”
- mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP | MOUSEEVENTF_MOVE, -450, 0, 1, 0);
mouse_event在沒有提供MOUSEEVENTF_MOVE量時光標不會移動到相對位置,
“光標相對位置=光標現行位置+新光標位置”如果提供量“MOUSEEVENTF_ABSOLUTE”
絕對位置,則會以“新光標位置”為準而不會添加“光標現行位置”
- static void edit_position(int dwFlags, int dx, int dy, ref int x, ref int y)
- {
- Point pos = MousePosition;
- x = x + pos.X;
- y = y + pos.Y;
- if ((dwFlags | MOUSEEVENTF_ABSOLUTE) == dwFlags)
- SetCursorPos(dx, dy);
- if ((dwFlags | MOUSEEVENTF_MOVE) == dwFlags)
- SetCursorPos(x, y);
- }
edit_position函數主要用于對MOUSEEVENTF_MOVE于MOUSEEVENTF_ABSOLUTE
相對/絕對光標位置修改的一個支持
- static void send_message(IntPtr hWnd, int dwFlags, int cButtons, int x, int y)
- {
- if ((dwFlags | MOUSEEVENTF_LEFTDOWN) == dwFlags)
- SendMessage(hWnd, WM_LBUTTONDOWN, cButtons, MakeDWord(x, y));
- if ((dwFlags | MOUSEEVENTF_LEFTUP) == dwFlags)
- SendMessage(hWnd, WM_LBUTTONUP, cButtons, MakeDWord(x, y));
- if ((dwFlags | MOUSEEVENTF_RIGHTDOWN) == dwFlags)
- SendMessage(hWnd, WM_RBUTTONDOWN, cButtons, MakeDWord(x, y));
- if ((dwFlags | MOUSEEVENTF_RIGHTUP) == dwFlags)
- SendMessage(hWnd, WM_RBUTTONUP, cButtons, MakeDWord(x, y));
- if ((dwFlags | MOUSEEVENTF_MIDDLEDOWN) == dwFlags)
- SendMessage(hWnd, WM_MBUTTONDOWN, cButtons, MakeDWord(x, y));
- if ((dwFlags | MOUSEEVENTF_MIDDLEUP) == dwFlags)
- SendMessage(hWnd, WM_MBUTTONUP, cButtons, MakeDWord(x, y));
- }
send_message函數主要用于模擬鼠標點擊的過程,上面我提到“先左鍵按下 + 后左鍵抬起”
在上面的代碼中你會看的清楚的不得了,如果相反你可以去嘗試一番會有什么后果 與其說
不如你們自己做更要來的快些。
- static int MakeDWord(int low, int high)
- {
- return low + (high * Abs(~ushort.MaxValue));
- }
-
- static int Abs(int value)
- {
- return ((value >> 31) ^ value) - (value >> 31);
- }
MakeDWord / 合并整數,函數主要是把兩個short合并為一個int,分為low、high兩部分
- static bool screen_to_client(IntPtr hwnd, ref int x, ref int y)
- {
- bool bRetVal = false;
- Point lPPTPos = new Point(x, y);
- if ((bRetVal = ScreenToClient(hwnd, ref lpptPos)))
- {
- x = lpptPos.X;
- y = lpptPos.Y;
- }
- return bRetVal;
- }
screen_to_client函數故名思意,它主要用于把屏幕上的坐標轉換到窗口客戶上對應坐標
- public const int WM_LBUTTONDOWN = 513;
- public const int WM_LBUTTONUP = 514;
- public const int WM_RBUTTONDOWN = 516;
- public const int WM_RBUTTONUP = 517;
- public const int WM_MBUTTONDOWN = 519;
- public const int WM_MBUTTONUP = 520;
-
- public const int MOUSEEVENTF_MOVE = 0x0001;
- public const int MOUSEEVENTF_LEFTDOWN = 0x0002;
- public const int MOUSEEVENTF_LEFTUP = 0x0004;
- public const int MOUSEEVENTF_RIGHTDOWN = 0x0008;
- public const int MOUSEEVENTF_RIGHTUP = 0x0010;
- public const int MOUSEEVENTF_MIDDLEDOWN = 0x0020;
- public const int MOUSEEVENTF_MIDDLEUP = 0x0040;
- public const int MOUSEEVENTF_ABSOLUTE = 0x8000;
- [DllImport("user32.dll", SetLastError = true)]
- public static extern int SendMessage(IntPtr hWnd, int uMsg, int wParam, int lParam);
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern IntPtr WindowFromPoint(int xPoint, int yPoint);
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern int SetCursorPos(int x, int y);
-
- [DllImport("user32.dll", SetLastError = true)]
- public static extern bool ScreenToClient(IntPtr hWnd, ref Point lppt);
-
鼠標右鍵單擊(靜默):
- mouse_event(MOUSEEVENTF_RIGHTDOWN | MOUSEEVENTF_RIGHTUP, 0, 0, 1, 0);
鼠標左鍵雙擊(靜默):
- mouse_event(MOUSEEVENTF_LEFTDOWN | MOUSEEVENTF_LEFTUP, 0, 0, 2, 0);
鼠標移動(相對位置):
- mouse_event(MOUSEEVENTF_MOVE, 100, 50, 0, 0);
鼠標移動(絕對位置):
- mouse_event(MOUSEEVENTF_ABSOLUTE, 100, 50, 0, 0);
好了就這么多吧,現在渾身頭暈腦漲的 話說多了反倒不好 自己從代碼中領悟才是真