因此,我将 GetForegroundWindow() 方法挂接到应用程序的焦点事件,但它显示了异常行为。
如果我通过用鼠标单击其窗口或按 alt+tab 来聚焦应用程序,
GetForegroundWindow()
将返回相应的窗口句柄,这一切都很好。
但是,如果我通过单击任务栏上的图标来聚焦应用程序,该方法将返回资源管理器句柄,并且任何进一步单击应用程序窗口都不会改变任何内容 - 窗口已经聚焦,Windows 不会发送任何信息不再关注焦点事件。感觉资源管理器已经成为应用程序的父级。
但是如果您按 alt+tab 两次,重新聚焦应用程序,
GetForegroundWindow()
将返回正确的句柄。
我还尝试通过 GetWindowInfo 调用获取窗口焦点状态,但它显示相同的结果。
请帮忙,资源管理器出了什么问题或者我做错了什么?
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
[DllImport("user32.dll")]
public static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
public delegate void WinEventDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
private const uint EVENT_SYSTEM_FOREGROUND = 0x0003;
private const uint EVENT_SYSTEM_CAPTURESTART = 0x0008;
private const uint WINEVENT_OUTOFCONTEXT = 0x0000;
private WinEventDelegate _focusDelegate;
private IntPtr _focusChangedHookPointer;
// It's const like this only for StackOverflow. I just simplified everything.
private IntPtr MY_WINDOW_HANDLE = 1315754;
private void FocusChangedHook(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
{
var foregroundWindowHandle = GetForegroundWindow();
Debug.WriteLine($"Handle Id: {foregroundWindowHandle}");
Debug.WriteLine($"Is Foreground: {foregroundWindowHandle == MY_WINDOW_HANDLE}");
}
private void Start()
{
_focusDelegate = FocusChangedHook;
_focusChangedHookPointer = SetWinEventHook(EVENT_SYSTEM_FOREGROUND, EVENT_SYSTEM_CAPTURESTART, IntPtr.Zero, _focusDelegate, 0, 0, WINEVENT_OUTOFCONTEXT);
}
我会使用 Application.Activated Event 而不是焦点。