从其他应用程序C#获取密钥

时间:2011-11-26 11:10:21

标签: c# windows keyboard postmessage user32

我想让用户在其他应用程序上按下该键。例如,在记事本中,而不是程序本身。这是我的编码,使用PostMessage方法连续发送密钥到记事本但是,我希望在按下某个键时停止它。

using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Threading;

       [DllImport("user32.dll")]
public static extern IntPtr FindWindow(
    string ClassName,
    string WindowName);

[DllImport("User32.dll")]
public static extern IntPtr FindWindowEx(
    IntPtr Parent,
    IntPtr Child,
    string lpszClass,
    string lpszWindows);

[DllImport("User32.dll")]
public static extern Int32 PostMessage(
    IntPtr hWnd,
    int Msg,
    int wParam,
    int lParam);

private const int WM_KEYDOWN = 0x100;

public Form1()
{
    InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
    Thread t = new Thread(new ThreadStart(Test));
    t.Start();
}

Boolean ControlKeyDown = true;

public void Test()
{
    // retrieve Notepad main window handle
    IntPtr Notepad = FindWindow("Notepad", "Untitled - Notepad");

    if (!Notepad.Equals(IntPtr.Zero))
    {
        // retrieve Edit window handle of Notepad
        IntPtr Checking = FindWindowEx(Notepad, IntPtr.Zero, "Edit", null);

        if (!Checking.Equals(IntPtr.Zero))
        {

            while (ControlKeyDown)
            {                        
                Thread.Sleep(100);

                PostMessage(Checking, WM_KEYDOWN, (int)Keys.A, 0);                                                             
            }
        }
    }
}

因此,当用户在记事本中按下ControlKeyDown键时,我的想法就设置为falseX。通过互联网进行研究后,我发现了这段代码并编辑了:

protected override void OnKeyDown(KeyEventArgs kea)
{
    if (kea.KeyCode == Keys.X)
    ControlKeyDown = false;
}

是的,通过这个,它肯定会停止循环,但这不是我想要的,因为它会在用户按下程序上的X键但不在记事本中时停止循环。这是因为KeyEventArgsSystem.Windows.Forms.KeyEventArgs而不是记事本。

需要帮助:(

2 个答案:

答案 0 :(得分:2)

我猜你正在寻找键盘挂钩。 See this article,它是c ++,但你似乎在p / invoke中敏捷,所以你可能很容易得到如何移植它。

答案 1 :(得分:0)

您可能需要查看user32.dll中的SetWindowsHookEx函数。

我还使用gma.UserActivity库在项目中执行此操作。