web-dev-qa-db-fra.com

Comment détecter le moment où Windows 10 entre en mode tablette dans une application Windows Forms?

Mettre à jour

Bien que ce ne soit pas la solution la plus élégante, une méthode qui semble fonctionner consiste à surveiller la valeur de registre correspondante. Voici un exemple d'utilisation de WMI pour cela. Je serais heureux d'entendre qui que ce soit s'il existe une meilleure solution que celle-ci.

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");
        }
    }
}

Question originale

Je souhaite effectuer quelques optimisations dans mon application Windows Forms en fonction du fait qu'un utilisateur est en "mode tablette" ou non à l'aide de la nouvelle fonctionnalité Windows 10 Continuum.

Vous trouverez des indications sur la procédure à suivre dans un projet UWP à l'adresse suivante: https://msdn.Microsoft.com/en-us/library/windows/hardware/dn917883(v=vs.85).aspx (c'est-à-dire vérifiez UserInteractionMode de la vue actuelle pour voir s'il s'agit de UserInteractionMode.Mouse ou UserInteractionMode.Touch), mais je ne suis pas sûr si ou comment je peux faire la même chose dans Windows Forms.

Aurais-je le moyen d'appeler les API UWP nécessaires à partir de mon application Windows Forms ou existe-t-il un équivalent de Windows Forms que je peux utiliser?

28
Adam Stiskala

Pour savoir si le système est en mode tablette ou non, interrogez la métrique système ConvertibleSlateMode comme suit (non testé, mais cela devrait fonctionner correctement dès 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;
   }
}

(Documentation ici )

8
Cheese Lover

J'ai cherché partout comment savoir si Windows 10 est en mode tablette et voici la solution la plus simple que j'ai trouvée:

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)
2
Gary Shaw

Selon cet article , vous ne pouvez pas écouter le message WM_SETTINGCHANGE. Voici un court exemple 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);
        }

Sous Windows 10, vous devez ensuite effectuer une interface COM avec certains éléments WinRT pour vérifier si vous êtes dans UserInteractionMode.Mouse (bureau) ou UserInteractionMode.Touch (tablette).

Le contenu de Com Interop semble plutôt délicat, mais il semble que ce soit le seul moyen si vous êtes dans une application stock win32.

1
Usul