共用方式為


HOW TO:以程式碼模擬滑鼠和鍵盤事件

Windows Form 提供了幾個選項,用於以程式設計方式模擬滑鼠和鍵盤輸入。 本說明主題將概要說明這些選項。

模擬滑鼠輸入

模擬滑鼠事件的最佳方式是呼叫 OnEventName 方法,此方法會引發您要模擬的滑鼠事件。 通常只有在自訂控制項和表單內才能使用這個選項,因為引發事件的方法會受到保護,而且無法在控制項或表單外進行存取。 例如,下列步驟說明了如何在程式碼中模擬按一下滑鼠右鍵的動作。

若要以程式設計方式按一下滑鼠右鍵

  1. 建立 MouseEventArgs,將它的 Button 屬性設為 MouseButtons.Right 值。

  2. 使用這個 MouseEventArgs 做為引數以呼叫 OnMouseClick 方法。

如需自訂控制項的詳細資訊,請參閱在設計階段開發 Windows Form 控制項

還有其他方式可以模擬滑鼠輸入。 例如,您可以使用程式設計方式設定代表狀態的控制項屬性,而此狀態通常是經由滑鼠輸入來設定 (例如 CheckBox 控制項的 Checked 屬性),或者是直接呼叫附加至您要模擬的事件的委派。

模擬鍵盤輸入

雖然您也可以使用上述用於滑鼠輸入的策略來模擬鍵盤輸入,Windows Form 還是提供了 SendKeys 類別,以便將按鍵動作傳送至使用中的應用程式。

警告

如果應用程式是設計成可搭配國際上現有的各種鍵盤來使用,則使用 SendKeys.Send 可能會產生無法預期的結果,應該要避免。

注意事項注意事項

SendKeys 類別已針對 .NET Framework 3.0 進行更新,以便能夠在 Windows Vista 上執行的應用程式中使用。 Windows Vista 的增強型安全性 (稱為使用者帳戶控制項或 UAC) 會讓之前的實作無法如預期般運作。

SendKeys 類別容易受到時間問題的影響,而某些開發人員必須解決這些問題。 更新的實作仍然容易受到時間問題的影響,但是速度會稍微快一些,而且可能需要解決方法有一些變更。 SendKeys 類別會先嘗試使用之前的實作,而如果失敗,則會使用新的實作。 因此,SendKeys 類別在不同的作業系統上可能會有不同的行為方式。 此外,當 SendKeys 類別使用新的實作時,SendWait 方法將不會在訊息傳送給另一個處理序時等候處理這些訊息。

如果應用程式倚賴一致的行為,而不論作業系統為何,您可以強制 SendKeys 類別使用新的實作,其方式是將下列應用程式設定加入至 app.config 檔中。

<appSettings>

<add key="SendKeys" value="SendInput"/>

</appSettings>

若要強制 SendKeys 類別使用之前的實作,請改用 "JournalHook" 這個值。

若要將按鍵動作傳送至相同的應用程式

  • 呼叫 SendKeys 類別的 SendSendWait 方法。 應用程式目前使用中的控制項就會接收指定的按鍵動作。 當使用者按兩下表單表面時,下列程式碼範例是使用 Send,以模擬按下 ENTER 鍵的動作。 這個範例是假設 Form 含有一個定位點索引為 0 的 Button 控制項。

    ' Send a key to the button when the user double-clicks anywhere 
    ' on the form.
    Private Sub Form1_DoubleClick(ByVal sender As Object, _
        ByVal e As EventArgs) Handles Me.DoubleClick
    
        ' Send the enter key to the button, which raises the click 
        ' event for the button. This works because the tab stop of 
        ' the button is 0.
        SendKeys.Send("{ENTER}")
    End Sub
    
    // Send a key to the button when the user double-clicks anywhere 
    // on the form.
    private void Form1_DoubleClick(object sender, EventArgs e)
    {
        // Send the enter key to the button, which raises the click 
        // event for the button. This works because the tab stop of 
        // the button is 0.
        SendKeys.Send("{ENTER}");
    }
    
        // Send a key to the button when the user double-clicks anywhere
        // on the form.
    private:
        void Form1_DoubleClick(Object^ sender, EventArgs^ e)
        {
            // Send the enter key to the button, which triggers the click
            // event for the button. This works because the tab stop of
            // the button is 0.
            SendKeys::Send("{ENTER}");
        }
    

若要將按鍵動作傳送至不同的應用程式

  • 啟動會接收按鍵動作的應用程式視窗,然後呼叫 SendSendWait 方法。 因為沒有 Managed 方法可用來啟動另一個應用程式,所以您必須使用原生 Windows 方法強制將焦點放在其他應用程式上。 下列程式碼範例是使用平台叫用以呼叫 FindWindow 和 SetForegroundWindow 方法而啟動 [小算盤] 應用程式視窗,然後再呼叫 SendWait 將一系列的計算發送至 [小算盤] 應用程式。

    注意事項注意事項

    FindWindow 呼叫的正確參數,可找出因您的 Windows 版本而異的 [小算盤] 應用程式。 下列程式碼可尋找 Windows 7 上的 [小算盤] 應用程式。 在 Windows Vista,將第一個參數變更為 "SciCalc"。 您可以使用 Visual Studio 隨附的 Spy++ 工具來判斷正確的參數。

    ' Get a handle to an application window.
    Declare Auto Function FindWindow Lib "USER32.DLL" ( _
        ByVal lpClassName As String, _
        ByVal lpWindowName As String) As IntPtr
    
    ' Activate an application window.
    Declare Auto Function SetForegroundWindow Lib "USER32.DLL" _
        (ByVal hWnd As IntPtr) As Boolean
    
    ' Send a series of key presses to the Calculator application.
    Private Sub button1_Click(ByVal sender As Object, _
        ByVal e As EventArgs) Handles button1.Click
    
        ' Get a handle to the Calculator application. The window class
        ' and window name were obtained using the Spy++ tool.
        Dim calculatorHandle As IntPtr = FindWindow("CalcFrame", "Calculator")
    
        ' Verify that Calculator is a running process.
        If calculatorHandle = IntPtr.Zero Then
            MsgBox("Calculator is not running.")
            Return
        End If
    
        ' Make Calculator the foreground application and send it 
        ' a set of calculations.
        SetForegroundWindow(calculatorHandle)
        SendKeys.SendWait("111")
        SendKeys.SendWait("*")
        SendKeys.SendWait("11")
        SendKeys.SendWait("=")
    End Sub
    
    // Get a handle to an application window.
    [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
    public static extern IntPtr FindWindow(string lpClassName,
        string lpWindowName);
    
    // Activate an application window.
    [DllImport("USER32.DLL")]
    public static extern bool SetForegroundWindow(IntPtr hWnd);
    
    // Send a series of key presses to the Calculator application.
    private void button1_Click(object sender, EventArgs e)
    {
        // Get a handle to the Calculator application. The window class
        // and window name were obtained using the Spy++ tool.
        IntPtr calculatorHandle = FindWindow("CalcFrame","Calculator");
    
        // Verify that Calculator is a running process.
        if (calculatorHandle == IntPtr.Zero)
        {
            MessageBox.Show("Calculator is not running.");
            return;
        }
    
        // Make Calculator the foreground application and send it 
        // a set of calculations.
        SetForegroundWindow(calculatorHandle);
        SendKeys.SendWait("111");
        SendKeys.SendWait("*");
        SendKeys.SendWait("11");
        SendKeys.SendWait("=");
    }
    
            // Get a handle to an application window.
        public:
            [DllImport("USER32.DLL", CharSet = CharSet::Unicode)]
            static IntPtr FindWindow(String^ lpClassName, String^ lpWindowName);
        public:
            // Activate an application window.
            [DllImport("USER32.DLL")]
            static bool SetForegroundWindow(IntPtr hWnd);
    
            // Send a series of key presses to the Calculator application.
        private:
            void button1_Click(Object^ sender, EventArgs^ e)
            {
                // Get a handle to the Calculator application. The window class
                // and window name were obtained using the Spy++ tool.
                IntPtr calculatorHandle = FindWindow("CalcFrame", "Calculator");
    
                // Verify that Calculator is a running process.
                if (calculatorHandle == IntPtr::Zero)
                {
                    MessageBox::Show("Calculator is not running.");
                    return;
                }
    
                // Make Calculator the foreground application and send it
                // a set of calculations.
                SetForegroundWindow(calculatorHandle);
                SendKeys::SendWait("111");
                SendKeys::SendWait("*");
                SendKeys::SendWait("11");
                SendKeys::SendWait("=");
            }
    

範例

下列程式碼範例是先前程式碼範例的完整應用程式。

Imports System
Imports System.Runtime.InteropServices
Imports System.Drawing
Imports System.Windows.Forms

Namespace SimulateKeyPress

    Class Form1
        Inherits Form
        Private WithEvents button1 As New Button()

        <STAThread()> _
        Public Shared Sub Main()
            Application.EnableVisualStyles()
            Application.Run(New Form1())
        End Sub

        Public Sub New()
            button1.Location = New Point(10, 10)
            button1.TabIndex = 0
            button1.Text = "Click to automate Calculator"
            button1.AutoSize = True
            Me.Controls.Add(button1)
        End Sub

        ' Get a handle to an application window.
        Declare Auto Function FindWindow Lib "USER32.DLL" ( _
            ByVal lpClassName As String, _
            ByVal lpWindowName As String) As IntPtr

        ' Activate an application window.
        Declare Auto Function SetForegroundWindow Lib "USER32.DLL" _
            (ByVal hWnd As IntPtr) As Boolean

        ' Send a series of key presses to the Calculator application.
        Private Sub button1_Click(ByVal sender As Object, _
            ByVal e As EventArgs) Handles button1.Click

            ' Get a handle to the Calculator application. The window class
            ' and window name were obtained using the Spy++ tool.
            Dim calculatorHandle As IntPtr = FindWindow("CalcFrame", "Calculator")

            ' Verify that Calculator is a running process.
            If calculatorHandle = IntPtr.Zero Then
                MsgBox("Calculator is not running.")
                Return
            End If

            ' Make Calculator the foreground application and send it 
            ' a set of calculations.
            SetForegroundWindow(calculatorHandle)
            SendKeys.SendWait("111")
            SendKeys.SendWait("*")
            SendKeys.SendWait("11")
            SendKeys.SendWait("=")
        End Sub

        ' Send a key to the button when the user double-clicks anywhere 
        ' on the form.
        Private Sub Form1_DoubleClick(ByVal sender As Object, _
            ByVal e As EventArgs) Handles Me.DoubleClick

            ' Send the enter key to the button, which raises the click 
            ' event for the button. This works because the tab stop of 
            ' the button is 0.
            SendKeys.Send("{ENTER}")
        End Sub

    End Class
End Namespace
using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Windows.Forms;

namespace SimulateKeyPress
{
    class Form1 : Form
    {
        private Button button1 = new Button();

        [STAThread]
        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.Run(new Form1());
        }

        public Form1()
        {
            button1.Location = new Point(10, 10);
            button1.TabIndex = 0;
            button1.Text = "Click to automate Calculator";
            button1.AutoSize = true;
            button1.Click += new EventHandler(button1_Click);

            this.DoubleClick += new EventHandler(Form1_DoubleClick);
            this.Controls.Add(button1);
        }

        // Get a handle to an application window.
        [DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
        public static extern IntPtr FindWindow(string lpClassName,
            string lpWindowName);

        // Activate an application window.
        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        // Send a series of key presses to the Calculator application.
        private void button1_Click(object sender, EventArgs e)
        {
            // Get a handle to the Calculator application. The window class
            // and window name were obtained using the Spy++ tool.
            IntPtr calculatorHandle = FindWindow("CalcFrame","Calculator");

            // Verify that Calculator is a running process.
            if (calculatorHandle == IntPtr.Zero)
            {
                MessageBox.Show("Calculator is not running.");
                return;
            }

            // Make Calculator the foreground application and send it 
            // a set of calculations.
            SetForegroundWindow(calculatorHandle);
            SendKeys.SendWait("111");
            SendKeys.SendWait("*");
            SendKeys.SendWait("11");
            SendKeys.SendWait("=");
        }

        // Send a key to the button when the user double-clicks anywhere 
        // on the form.
        private void Form1_DoubleClick(object sender, EventArgs e)
        {
            // Send the enter key to the button, which raises the click 
            // event for the button. This works because the tab stop of 
            // the button is 0.
            SendKeys.Send("{ENTER}");
        }
    }
}
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.dll>

using namespace System;
using namespace System::Runtime::InteropServices;
using namespace System::Drawing;
using namespace System::Windows::Forms;

namespace SimulateKeyPress
{

    public ref class Form1 : public Form
    {
    public:
        Form1()
        {
            Button^ button1 = gcnew Button();
            button1->Location = Point(10, 10);
            button1->TabIndex = 0;
            button1->Text = "Click to automate Calculator";
            button1->AutoSize = true;
            button1->Click += gcnew EventHandler(this, &Form1::button1_Click);

            this->DoubleClick += gcnew EventHandler(this, 
                &Form1::Form1_DoubleClick);
            this->Controls->Add(button1);
        }

        // Get a handle to an application window.
    public:
        [DllImport("USER32.DLL", CharSet = CharSet::Unicode)]
        static IntPtr FindWindow(String^ lpClassName, String^ lpWindowName);
    public:
        // Activate an application window.
        [DllImport("USER32.DLL")]
        static bool SetForegroundWindow(IntPtr hWnd);

        // Send a series of key presses to the Calculator application.
    private:
        void button1_Click(Object^ sender, EventArgs^ e)
        {
            // Get a handle to the Calculator application. The window class
            // and window name were obtained using the Spy++ tool.
            IntPtr calculatorHandle = FindWindow("CalcFrame", "Calculator");

            // Verify that Calculator is a running process.
            if (calculatorHandle == IntPtr::Zero)
            {
                MessageBox::Show("Calculator is not running.");
                return;
            }

            // Make Calculator the foreground application and send it
            // a set of calculations.
            SetForegroundWindow(calculatorHandle);
            SendKeys::SendWait("111");
            SendKeys::SendWait("*");
            SendKeys::SendWait("11");
            SendKeys::SendWait("=");
        }

        // Send a key to the button when the user double-clicks anywhere
        // on the form.
    private:
        void Form1_DoubleClick(Object^ sender, EventArgs^ e)
        {
            // Send the enter key to the button, which triggers the click
            // event for the button. This works because the tab stop of
            // the button is 0.
            SendKeys::Send("{ENTER}");
        }
    };
}

[STAThread]
int main()
{
    Application::EnableVisualStyles();
    Application::Run(gcnew SimulateKeyPress::Form1());
}

編譯程式碼

這項範例需要:

  • System、System.Drawing 和 System.Windows.Forms 組件的參考。

如需從 Visual Basic 或 Visual C# 的命令列建置這個範例的詳細資訊,請參閱從命令列建置 (Visual Basic)使用 csc.exe 建置命令列。 您也可以透過將程式碼貼入新的專案,在 Visual Studio 中建置此範例。 如需詳細資訊,請參閱HOW TO:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例HOW TO:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例HOW TO:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例HOW TO:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例如何:使用 Visual Studio 編譯及執行完整的 Windows Form 程式碼範例.

請參閱

其他資源

Windows Form 中的使用者輸入