如何在 C# 中使用全局热键来回更改应用程序焦点
How to change back and forth application focus with global hotkey in C#
我正在创建自己的 C# 剪贴板管理器,我有一个全局热键 ALT+H
,它将触发从剪贴板中删除文本格式。我的应用程序在后台运行时只有一个托盘图标。因此这工作正常但我的问题是当我在应用程序中时,例如Word 和我按下我的热键,然后它会向我显示这些应用程序中的各种菜单,我不想要那样。
仅供参考,这与我目前在 SO 上提出的另一个问题非常相关,How to stop further processing global hotkeys in C#。在另一个问题中,这是基于找到热键的解决方案,但我认为可能更好的另一种方法可能是暂时将焦点切换到我的应用程序,一旦我的热键不再适用,就可以切换焦点返回原始应用程序。
但是我不知道如何再次切换回原始应用程序!?
到目前为止,我的代码只关注应用程序更改机制:
Programs.cs:
// Import the required "SetForegroundWindow" method
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
Form1.cs:
// Change focus to my application (when hotkey is active)
Program.SetForegroundWindow(this.Handle);
我不确定这是否真的有效,但我可以看到原始应用程序(例如 Word)失去了焦点,而我的应用程序仍然可以正常工作,所以我希望它能正常工作。
我的问题是 - 如何从原始应用程序获取 hWnd
(?) 句柄以便我可以在完成后切换回它?如果我在任何应用程序中 不是 怎么办?就在 WIndows 桌面上?然后会发生什么-它可以变回那个吗?
我将不胜感激任何可以提供帮助的提示,因为我目前还不是真正的 C# 开发人员 ;-)
我自己找到了解决方案,并将解释对我有用的解决方案。我这里有这段代码:
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
// I get in to here when the clipboard has changed and I need to find the application that has changed the clipboard
// Get the active/originating application handle
IntPtr originatingHandle = GetForegroundWindow();
// ------------------
// Do "some stuff" - this is not required for the application switching but it will get the application process name for the active/originating application
// Get the process ID from the active application
uint processId = 0;
GetWindowThreadProcessId(originatingHandle, out processId);
// Get the process name from the process ID
string appProcessName = Process.GetProcessById((int)processId).ProcessName;
// End "some stuff"
// ------------------
// Change focus to my application - this code is inside my main form (Form1)
SetForegroundWindow(this.Handle);
// Do some more stuff - whatever is required for my application to do
// ...
// Change focus back to the originating application again
SetForegroundWindow(originatingHandle);
至少上面的代码对我有用。
我正在创建自己的 C# 剪贴板管理器,我有一个全局热键 ALT+H
,它将触发从剪贴板中删除文本格式。我的应用程序在后台运行时只有一个托盘图标。因此这工作正常但我的问题是当我在应用程序中时,例如Word 和我按下我的热键,然后它会向我显示这些应用程序中的各种菜单,我不想要那样。
仅供参考,这与我目前在 SO 上提出的另一个问题非常相关,How to stop further processing global hotkeys in C#。在另一个问题中,这是基于找到热键的解决方案,但我认为可能更好的另一种方法可能是暂时将焦点切换到我的应用程序,一旦我的热键不再适用,就可以切换焦点返回原始应用程序。
但是我不知道如何再次切换回原始应用程序!?
到目前为止,我的代码只关注应用程序更改机制:
Programs.cs:
// Import the required "SetForegroundWindow" method
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
Form1.cs:
// Change focus to my application (when hotkey is active)
Program.SetForegroundWindow(this.Handle);
我不确定这是否真的有效,但我可以看到原始应用程序(例如 Word)失去了焦点,而我的应用程序仍然可以正常工作,所以我希望它能正常工作。
我的问题是 - 如何从原始应用程序获取 hWnd
(?) 句柄以便我可以在完成后切换回它?如果我在任何应用程序中 不是 怎么办?就在 WIndows 桌面上?然后会发生什么-它可以变回那个吗?
我将不胜感激任何可以提供帮助的提示,因为我目前还不是真正的 C# 开发人员 ;-)
我自己找到了解决方案,并将解释对我有用的解决方案。我这里有这段代码:
using System.Runtime.InteropServices;
[DllImport("user32.dll")]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
// I get in to here when the clipboard has changed and I need to find the application that has changed the clipboard
// Get the active/originating application handle
IntPtr originatingHandle = GetForegroundWindow();
// ------------------
// Do "some stuff" - this is not required for the application switching but it will get the application process name for the active/originating application
// Get the process ID from the active application
uint processId = 0;
GetWindowThreadProcessId(originatingHandle, out processId);
// Get the process name from the process ID
string appProcessName = Process.GetProcessById((int)processId).ProcessName;
// End "some stuff"
// ------------------
// Change focus to my application - this code is inside my main form (Form1)
SetForegroundWindow(this.Handle);
// Do some more stuff - whatever is required for my application to do
// ...
// Change focus back to the originating application again
SetForegroundWindow(originatingHandle);
至少上面的代码对我有用。