如何在Windows窗体应用程序中检测Windows 10何时进入平板电脑模式

本文关键字:Windows 何时进 检测 平板电脑 模式 窗体 应用程序 | 更新日期: 2023-09-27 18:00:39

更新

虽然不是最优雅的解决方案,但一种似乎有效的方法是查看相关的注册表值。下面是一个使用WMI执行此操作的示例。如果有比这更好的解决方案,我很乐意听取任何人的意见。

using System;
using System.Management;
using System.Security.Principal;
using System.Windows.Forms;
using Microsoft.Win32;
public partial class MainForm : Form
{
    public MainForm()
    {
        this.InitializeComponent();
        this.UpdateModeFromRegistry();
        var currentUser = WindowsIdentity.GetCurrent();
        if (currentUser != null && currentUser.User != null)
        {
            var wqlEventQuery = new EventQuery(string.Format(@"SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_USERS' AND KeyPath='{0}''SOFTWARE''Microsoft''Windows''CurrentVersion''ImmersiveShell' AND ValueName='TabletMode'", currentUser.User.Value));
            var managementEventWatcher = new ManagementEventWatcher(wqlEventQuery);
            managementEventWatcher.EventArrived += this.ManagementEventWatcher_EventArrived;
            managementEventWatcher.Start();
        }
    }
    private void ManagementEventWatcher_EventArrived(object sender, EventArrivedEventArgs e)
    {
        this.UpdateModeFromRegistry();
    }
    private void UpdateModeFromRegistry()
    {
        var tabletMode = (int)Registry.GetValue("HKEY_CURRENT_USER''SOFTWARE''Microsoft''Windows''CurrentVersion''ImmersiveShell", "TabletMode", 0);
        if (tabletMode == 1)
        {
            Console.Write(@"Tablet mode is enabled");
        }
        else
        {
            Console.Write(@"Tablet mode is disabled");
        }
    }
}

原始问题

我有兴趣在我的Windows窗体应用程序中根据用户是否处于"Tablet模式"(或是否处于)使用新的Windows 10 Continuum功能进行一些优化。

有一些关于如何在UWP项目中做到这一点的指导https://msdn.microsoft.com/en-us/library/windows/hardware/dn917883(v=vs.85).aspx(即检查当前视图的UserInteractionMode,看看它是UserInteractionMode.Mouse还是UserInteractionMode.Touch),但我不确定是否或如何在Windows窗体中执行相同操作。

有没有什么方法可以从我的Windows窗体应用程序中调用必要的UWP API,或者我可以使用一些等效的Windows窗体?

如何在Windows窗体应用程序中检测Windows 10何时进入平板电脑模式

要了解系统是否处于平板电脑模式,请像这样查询系统度量ConvertibleSlateMode(未测试,但早在XP时就可以正常工作):

public static class TabletPCSupport
{
   private static readonly int SM_CONVERTIBLESLATEMODE = 0x2003;
   private static readonly int SM_TABLETPC = 0x56;
   private static Boolean isTabletPC = false;
   public static Boolean SupportsTabletMode { get { return isTabletPC; }}
   public static Boolean IsTabletMode 
   {
       get
       {
           return QueryTabletMode();
       }
   }
   static TabletPCSupport ()
   {
        isTabletPC = (GetSystemMetrics(SM_TABLETPC) != 0);
   }
   [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "GetSystemMetrics")]
   private static extern int GetSystemMetrics (int nIndex);
   private static Boolean QueryTabletMode ()
   {
       int state = GetSystemMetrics(SM_CONVERTIBLESLATEMODE);
       return (state == 0) && isTabletPC;
   }
}

(此处为文档)

我到处寻找如何判断Windows 10是否处于平板电脑模式,这里是我找到的最简单的解决方案:

bool bIsTabletMode = false;
var uiMode = UIViewSettings.GetForCurrentView().UserInteractionMode;
if (uiMode == Windows.UI.ViewManagement.UserInteractionMode.Touch)
 bIsTabletMode = true;
else
 bIsTabletMode = false;

// (Could also compare with .Mouse instead of .Touch)

根据本文,您不能收听WM_SETTINGCHANGE消息。下面是一个简短的c#示例:

protected override void WndProc(ref Message m)
        {
            
            const int WM_WININICHANGE = 0x001A,
                WM_SETTINGCHANGE = WM_WININICHANGE;
            if (m.Msg == WM_SETTINGCHANGE)
            {
                if (Marshal.PtrToStringUni(m.LParam) == "UserInteractionMode")
                {
                    MessageBox.Show(Environment.OSVersion.VersionString);
                }
            }
            base.WndProc(ref m);
        }

对于Windows 10,你应该用一些WinRT的东西执行一些COM接口,以检查你是否处于UserInteractionMode.Mouse(桌面)或UserInteractionMode.Touch(平板电脑)。

Com Interop的东西看起来相当棘手,但如果你在一个股票win32应用程序中,这似乎是唯一的方法。