我可以在 WPF 项目中控制 Windows 设置焦点辅助(开/关)吗

问题描述 投票:0回答:1

我想在我的 C# WPF 项目中实现一项功能,在应用程序中,用户可以使用复选框打开/关闭焦点辅助(Windows 10 中的设置),该复选框会自动将焦点辅助设置切换为“打开”,或者如果取消选中“关闭”。

如果可能的话,我不想打开“聚焦辅助”窗口让用户手动单击开/关。

我尝试搜索如何能够控制这些设置,我所能找到的就是实现类

Windows.System
,但是,唯一的控件似乎是
Windows.System.RemoteDesktop
Windows.System.Power
Windows.System.Display
和缺少
FocusAssist

有人能指出我正确的方向吗?

c# wpf winapi windows-10
1个回答
0
投票

我想出了以下内容。在 Windows 10 22H2 19045.3803 中测试。

备注:

  • 在 Windows Focus Assist 设置下,必须将

    When I'm duplicating my display
    When I'm playing a game
    设置为
    On
    ,具体取决于您打算以编程方式激活的模式。

  • Windows 似乎会跟踪哪个进程/应用程序负责激活 Focus Assist。如果这不是您的应用程序,则无法将其关闭(如果您找到解决方法,请告诉我)。

  • 为了打开聚焦辅助,您有时需要先发出命令将其关闭(即使它已经关闭)。为了获得最佳效果,请始终关闭然后再打开。

     using System.Runtime.InteropServices;
    
     while(true)
     {
    
         var focusAssistMode = Console.ReadLine() == "on" ? FocusAssistMode.Fullscreen : FocusAssistMode.Off;
    
         var result = FocusAssistHelper.SetFocusAssistMode(focusAssistMode);
    
         if (result == 0)
         {
             Console.WriteLine("Success");
         }
         else
         {
             Console.WriteLine($"Failed with error code {result}");
         };
    
     }
    
     public static class FocusAssistHelper
     {
    
         [DllImport("ntdll.dll", SetLastError = true)]
         static extern int ZwUpdateWnfStateData(
             ref ulong StateName,
             IntPtr Buffer,
             int Length,
             Guid TypeId,
             IntPtr ExplicitScope,
             uint MatchingChangeStamp,
             bool CheckStamp
         );
    
         const ulong WNF_SHEL_QUIET_MOMENT_SHELL_MODE_CHANGED = 0xd83063ea3bf5075UL;
    
         public static int SetFocusAssistMode(FocusAssistMode mode)
         {
    
             var modeAsByteArray = BitConverter.GetBytes((uint)mode);
    
             var bufferPtr = Marshal.AllocHGlobal(modeAsByteArray.Length);
    
             try
             {
    
                 Marshal.Copy(modeAsByteArray, 0, bufferPtr, modeAsByteArray.Length);
    
                 var stateName = WNF_SHEL_QUIET_MOMENT_SHELL_MODE_CHANGED;
    
                 return ZwUpdateWnfStateData(ref stateName, bufferPtr, modeAsByteArray.Length, Guid.Empty, IntPtr.Zero, 0, false);
    
             }
             finally
             {
                 Marshal.FreeHGlobal(bufferPtr);
             }
    
         }
    
     }
    
     public enum FocusAssistMode : uint
     {
         Off = 0,
         Game = 1,
         Fullscreen = 2,
     }
    
© www.soinside.com 2019 - 2024. All rights reserved.