在我的应用程序中,我需要知道用户何时切换虚拟桌面,例如通过按 Ctrl + Win + →。
尽管通过Hooking这样做是一个好主意。我列出了我编写的示例类以测试我的想法。我以为虚拟桌面更改时,我会得到回调。但是,无论如何更改虚拟桌面,都没有回调。
我还编写了一个测试应用程序,用于创建,打开,切换和关闭桌面。它工作正常,但下面的代码无法检测到任何桌面开关。
public class SwitchDesktopMonitor
{
private delegate void CreateHookDelegate();
private delegate void SetWinEventHookCallback(IntPtr hWinEventHook, uint eventType, IntPtr hWnd, uint objectId, int childId, uint dwEventThread, uint dwmsEventTime);
[DllImport("user32.dll")]
private static extern IntPtr SetWinEventHook(uint eventMin, uint eventMax, IntPtr hmodWinEventProc, SetWinEventHookCallback lpfnWinEventProc, uint idProcess, uint idThread, uint dwFlags);
[DllImport("user32.dll")]
private static extern bool UnhookWinEvent(IntPtr hWinEventHook);
[DllImport("user32.dll", SetLastError = true)]
private static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint processId);
private IntPtr _setWinEventHook;
private readonly SetWinEventHookCallback _hookingCallback;
private readonly Window _window;
public SwitchDesktopMonitor(Window window)
{
_window = window;
_hookingCallback = (hWinEventHook, eventType, hWnd, objectId, childId, dwEventThread, dwmsEventTime) =>
{
Console.WriteLine("-> _hookingCallback - hWinEventHook = {0}, eventType = {1}, hWnd = {2}, objectId = {3}, childId = {4}, dwEventThread = {5}, dwmsEventTime = {6}",
hWinEventHook, eventType, hWnd, objectId, childId, dwEventThread, dwmsEventTime);
};
}
public void Start()
{
Console.WriteLine("{0}.Start", this);
if (_window == null || _window.Dispatcher == null)
{
return;
}
if (_window.Dispatcher.CheckAccess())
{
CreateHook();
}
else
{
_window.Dispatcher.Invoke(new CreateHookDelegate(CreateHook));
}
}
public void Stop()
{
Console.WriteLine("{0}.Stop", this);
if (_setWinEventHook != null)
{
Console.WriteLine("\tUnhookWinEvent = {0}", UnhookWinEvent(_setWinEventHook));
}
}
private void CreateHook()
{
var windowHandle = new WindowInteropHelper(_window).Handle;
uint processId;
uint threadId = GetWindowThreadProcessId(windowHandle, out processId);
Console.WriteLine("\twindowHandle = {0}, processId = {1}, threadId = {2}", windowHandle, processId, threadId);
_setWinEventHook = SetWinEventHook(0x0020, 0x0020, IntPtr.Zero, _hookingCallback, processId, threadId, 0x0000);
Console.WriteLine("\t_setWinEventHook = {0}", _setWinEventHook);
}
}
我不必这样做。我很感激或其他方式。唯一重要的是,我需要检测Windows桌面开关。
答案 0 :(得分:1)
您为事件EVENT_SYSTEM_DESKTOPSWITCH
(0x0020)安装了一个钩子。但是,此处的术语“台式机”在Windows 10中并未将“虚拟台式机”作为在不同窗口集之间进行切换的功能,而是将desktops as a system concept in Windows分隔为不同的操作环境(“正常”,“登录”,“屏幕保护程序”)。
因此,您无法以这种方式检测到虚拟桌面的切换。
相反,请使用此开源库https://github.com/Grabacr07/VirtualDesktop中所示的方法,该库使用Windows Shell中当前未记录的VirtualDesktopNotificationService
COM服务在当前虚拟桌面更改时得到通知。