C# SendKeys 到 Windows 7 中的前台窗口不起作用

标签 c# .net

我正在尝试在 Visual Studio 2012 中使用 C# 构建一个全局热键应用程序,以在 Windows 7 上运行。除了 SendKeys 从未在应用程序中显示之外,我一切正常。

这是我用来发送击键的代码:

更新以使用 GetFocusedWindow 示例进行调试。

StringBuilder className = new StringBuilder(256);
IntPtr hWnd = GetForegroundWindow();
GetClassName(hWnd, className, className.Capacity);
Debug.WriteLine("Foreground window: {0}={1}", hWnd.ToInt32().ToString("X"), className);
hWnd = GetFocusedWindow();
GetClassName(hWnd, className, className.Capacity);
Debug.WriteLine("Focused window: {0}={1}", hWnd.ToInt32().ToString("X"), className);

SendKeys.Send("Hello World");

当我调试程序时,聚焦记事本并按下热键,我收到以下调试消息,并且击键永远不会插入到记事本中:

Foreground Window: 4F02B6=Notepad
Focused Window: 1B6026A=WindowsForms10.Window.8.app.0.bf7d44_r11_ad1

如何将击键发送到当前前台窗口?

最佳答案

前景窗口不一定意味着聚焦窗口。当您向其父窗口发送键时,顶级前景窗口的子窗口可能具有焦点。

从另一个进程检索聚焦的子窗口有点棘手。尝试以下 GetFocusedWindow 实现,使用它代替 GetForegroundWindow(未经测试):

static IntPtr GetFocusedWindow()
{
    uint currentThread = GetCurrentThreadId();

    IntPtr activeWindow = GetForegroundWindow();
    uint activeProcess;
    uint activeThread = GetWindowThreadProcessId(activeWindow, out activeProcess);

    if (currentThread != activeThread)
        AttachThreadInput(currentThread, activeThread, true);
    try
    {
        return GetFocus();
    }
    finally
    {
        if (currentThread != activeThread)
            AttachThreadInput(currentThread, activeThread, false);
    }
}

[DllImport("kernel32.dll")]
static extern uint GetCurrentThreadId();

[DllImport("user32.dll")]
private static extern IntPtr GetForegroundWindow();

[DllImport("user32.dll")]
static extern IntPtr GetFocus();

[DllImport("user32.dll", SetLastError = true)]
static extern bool AttachThreadInput(uint idAttach, uint idAttachTo, bool fAttach);

[DllImport("user32.dll")]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);

已更新以解决评论:

When I use this function it sets the focus to my application window.

很难判断您这边出了什么问题,当焦点位于记事本内时,以下内容对我有用:

private async void Form1_Load(object sender, EventArgs e)
{
    var className = new StringBuilder(200);
    while (true)
    {
        await Task.Delay(500);
        IntPtr focused = GetFocusedWindow();
        GetClassName(focused, className, className.Capacity);
        var classNameStr = className.ToString();
        this.Text = classNameStr;
        if (classNameStr == "Edit")
            SendKeys.Send("Hello!");
    }
}

关于C# SendKeys 到 Windows 7 中的前台窗口不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22369486/

相关文章:

c# - EF如何确定可为空的参数?

c# - 为什么 Guid 不是 c# 中的对象?

c# - ASMX文件上传

c# - 检查是否选择了特定的标签页(事件)

c# - MVC C# 编译 debug = true 仍然捆绑

C# 和 .NET 3.5 - 如何使用不同的凭据启动进程,使用隐藏窗口,并能够捕获标准输出和退出代码?

c# - 从另一个静态类访问表单方法

c# - 集合中的排序值仅在循环中可见

c# - 为什么这两次比较会有不同的结果呢?

c# - 将 DateTime 与数据库中存储的日期进行比较