Actualizar
Si bien no es la solución más elegante, un método que parece funcionar es observar el valor de registro relevante. Aquí hay un ejemplo usando WMI para hacer esto. Me encantaría saber de alguien si hay una solución mejor que esta.
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"); } } }Pregunta inicial
Estoy interesado en hacer algunas optimizaciones en mi aplicación Windows Forms en función de si un usuario está en "Modo tableta" (o no) usando la nueva característica de Windows 10 Continuum.
Hay alguna guía sobre cómo hacer esto en un proyecto UWP en https://msdn.microsoft.com/en-us/library/windows/hardware/dn917883(v=vs.85).aspx (es decir, verifique la vista actual UserInteractionMode para ver si es UserInteractionMode.Mouse o UserInteractionMode.Touch), sin embargo, no estoy seguro de si puedo hacer lo mismo en Windows Forms o cómo.
¿Habría alguna forma de llamar a las API de UWP necesarias desde mi aplicación de Windows Forms, o hay algún equivalente de Windows Forms que pueda usar?
Para saber si el sistema está en modo tableta o no, consulte la métrica del sistema ConvertibleSlateMode así (no probado, pero debería funcionar bien desde 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; } }(Documentación aquí )
He buscado en todas partes cómo saber si Windows 10 está en modo tableta y aquí está la solución más simple que encontré:
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)Según este artículo , no puede escuchar el mensaje WM_SETTINGCHANGE . Aquí hay una breve muestra de 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); }Para Windows 10, debe realizar una interfaz COM con algunas cosas de WinRT, para verificar si está en UserInteractionMode.Mouse (escritorio) o UserInteractionMode.Touch (tableta).
Las cosas de Com Interop parecen bastante complicadas, pero parece ser la única forma si está en una aplicación win32 estándar.