#副標=實用的.NET Key單幫手(1) #大標=鍵盤與滑鼠動作模擬 作者=文/李明儒 ====================================== 程式1 using System; using System.Threading; using System.Runtime.InteropServices; //PInvoke時要參照此Namespace namespace MKAssistant { public class MouseAgent { public MouseAgent() { } #region Mouse API //設定Mouse游標 API [DllImport("user32.dll")] [return:MarshalAs(UnmanagedType.Bool)] private static extern bool SetCursorPos(int X, int Y); //模擬Mouse動作的API [DllImport("user32.dll")] private static extern void mouse_event( uint dwFlags, // 識別動作種類的旗標(移動或點選) uint dx, // 水平位置或移動量 uint dy, // 垂宜位置或移動量 uint dwData, // 滾輪的移動量 IntPtr dwExtraInfo // 應用程式自訂的資訊(指標) ); // 識別動作種類的旗標值 const uint MOUSEEVENTF_ABSOLUTE = 0x8000; const uint MOUSEEVENTF_MOVE = 0x0001; const uint MOUSEEVENTF_LEFTDOWN = 0x0002; const uint MOUSEEVENTF_LEFTUP = 0x0004; const uint MOUSEEVENTF_RIGHTDOWN = 0x0008; const uint MOUSEEVENTF_RIGHTUP = 0x0010; const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020; const uint MOUSEEVENTF_MIDDLEUP = 0x0040; #endregion //指定游標位置 public static void MoveCursorTo(int x, int y) { SetCursorPos(x,y); } //指定游標位置後並等待一小段時間,讓游標所在的程式足夠做出反應 public static void MoveCursorTo(int x, int y, int delay) { MoveCursorTo(x,y); Thread.Sleep(delay); } //模疑滑鼠移動, x,y為移動量,負數表反方向 public static void MoveCursor(int x, int y) { mouse_event(MOUSEEVENTF_MOVE,(uint) x,(uint) y,0,IntPtr.Zero); } //模疑滑鼠移動並等待一小段時間, x,y為移動量,負數表反方向 public static void MoveCursor(int x, int y, int delay) { MoveCursor(x,y); Thread.Sleep(delay); } //模擬左鍵單擊 public static void LeftClick(int x, int y) { MoveCursorTo(x,y,50); mouse_event(MOUSEEVENTF_LEFTDOWN,(uint) x,(uint) y,0,IntPtr.Zero); Thread.Sleep(50); mouse_event(MOUSEEVENTF_LEFTUP,(uint) x,(uint) y,0,IntPtr.Zero); } //模擬左鍵單擊後等待一段時間 public static void LeftClick(int x, int y, int delay) { LeftClick(x,y); Thread.Sleep(delay); } //模擬右鍵單擊 public static void RightClick(int x, int y) { MoveCursorTo(x,y,50); mouse_event(MOUSEEVENTF_RIGHTDOWN,(uint) x,(uint) y,0,IntPtr.Zero); Thread.Sleep(50); mouse_event(MOUSEEVENTF_RIGHTUP,(uint) x,(uint) y,0,IntPtr.Zero); } //模擬右鍵單擊後等待一段時間 public static void RightClick(int x, int y, int delay) { RightClick(x,y); Thread.Sleep(delay); } //模擬左鍵雙擊 public static void DoubleClick(int x, int y) { MoveCursorTo(x,y,50); mouse_event(MOUSEEVENTF_LEFTDOWN,(uint) x,(uint) y,0,IntPtr.Zero); Thread.Sleep(50); mouse_event(MOUSEEVENTF_LEFTUP,(uint) x,(uint) y,0,IntPtr.Zero); Thread.Sleep(100); mouse_event(MOUSEEVENTF_LEFTDOWN,(uint) x,(uint) y,0,IntPtr.Zero); Thread.Sleep(50); mouse_event(MOUSEEVENTF_LEFTUP,(uint) x,(uint) y,0,IntPtr.Zero); } //模擬左鍵雙擊後等待一段時間 public static void DoubleClick(int x, int y, int delay) { DoubleClick(x,y); Thread.Sleep(delay); } } } ============================================= ===================================== 程式2 private void button1_Click(object sender, System.EventArgs e) { MouseAgent.MoveCursor(200,0,100); //游標向右移200點並等待100ms } private void button2_Click(object sender, System.EventArgs e) { MouseAgent.RightClick(this.Left+this.Width+10,this.Top); //在Form右方10點處點右鍵,出現桌面的內容設定選單 } ===================================== =============================== 程式3 using System; using System.Runtime.InteropServices; namespace MKAssistant { public enum VKMap { //參考 MSDN /library/ en-us/ winui/ WinUI/ WindowsUserInterface/ UserInput/ VirtualKeyCodes.asp[參1-4] 建立列舉值 VK_SHIFT = 16, VK_CONTROL = 17, VK_ALT = 18 /* 完整映對請參照MSDN文件,這裡只列出Ctrl、Alt、Shift的對應,其餘省略 */ } public class KbAgent { public KbAgent() { } #region Keyboard API const uint KEYEVENTF_KEYDOWN = 0x0; const uint KEYEVENTF_EXTENDEDKEY = 0x1; const uint KEYEVENTF_KEYUP = 0x2; // 用以模擬按鍵動作的API [DllImport("user32.dll")] static extern void keybd_event( byte bVk, //Virtual Key Code byte bScan, //Scan Code uint dwFlags, //按鍵動作旗標 IntPtr dwExtraInfo //指向額外資料結構的指標 ); #endregion // Overloading 1: 模擬按鍵動作,傳入按鍵字串的語法接近口語,例如: Shift-F、Ctrl-Y、Ctrl-Shift-A public static void PressKey(string key) { PressKey(1,key); } // Overloading 2: 可指定重覆按鍵的次數,以口語化按鍵字串指定按鍵 public static void PressKey(int repeatedTimes, string key) { key=key.ToUpper(); bool ctrlFlag=(key.IndexOf("CTRL-")>=0); bool shiftFlag=(key.IndexOf("SHIFT-")>=0); bool altFlag=(key.IndexOf("ALT-")>=0); byte vk=0; if (!key.EndsWith("-") || key.EndsWith("--")) //排除只按Ctrl, Shift, Alt而不按任何其他Key的情形 vk=(byte) key[key.Length-1]; //取key字串最後一個字元對照出Virtual Key Code triggerKeybdEvent(ctrlFlag, shiftFlag, altFlag, (byte) vk, repeatedTimes); } //Overloading 3: 當按鍵為特殊功能鍵時,第一個參數傳入Shift, Ctrl等口語化字串,第二個參數則直接指定Virtual Key Code public static void PressKey(string controlKey, VKMap vkCode) { PressKey(1, controlKey, vkCode); } //Overloading 4: 同Overloading 3,多了指定重覆按鍵次數的功能 public static void PressKey(int repeatedTimes, string controlKey, VKMap vkCode) { string key=controlKey.ToUpper(); bool ctrlFlag=(key.IndexOf("CTRL-")>=0); bool shiftFlag=(key.IndexOf("SHIFT-")>=0); bool altFlag=(key.IndexOf("ALT-")>=0); triggerKeybdEvent(ctrlFlag, shiftFlag, altFlag, (byte) vkCode, repeatedTimes); } // 以keybd_event API 模擬按鍵動作 private static void triggerKeybdEvent(bool ctrlFlag, bool shiftFlag, bool altFlag, byte virtualKey, int repeatedTimes) { if (ctrlFlag) keybd_event((byte) VKMap.VK_CONTROL, 0, KEYEVENTF_KEYDOWN, IntPtr.Zero); if (shiftFlag) keybd_event((byte) VKMap.VK_SHIFT, 0, KEYEVENTF_KEYDOWN, IntPtr.Zero); if (altFlag) keybd_event((byte) VKMap.VK_ALT, 0, KEYEVENTF_KEYDOWN, IntPtr.Zero); if (virtualKey!=0) { for (int i=0; i=============== ============================== 程式4 private void button1_Click(object sender, System.EventArgs e) { Process pShell=new Process(); pShell.StartInfo.FileName = "notepad.exe"; pShell.Start(); //啟動Notepad System.Threading.Thread.Sleep(1000); //等待Notepad就緒可接受輸入 KbAgent.PressKey(6,"A"); KbAgent.PressKey("Alt-F"); KbAgent.PressKey("A"); } ================================