我正在尝试在 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/