如何通过代码在Windows 10上启用平板模式?

8
我曾阅读过各种关于如何检测Windows 10设备是否处于平板模式的方法,尤其是下面的主题; 如何在Windows Forms应用程序中检测Window 10进入平板模式? 我想通过代码(.Net C#)启用/禁用平板模式,但我找不到任何资源来实现这一点。我已尝试更改注册表键并发送HWND_BROADCAST以指示发生了更改,但这不会启动平板模式更改。
我还尝试使用类似Spy ++的应用程序,但看不到发送的消息。
是否存在一种方法来实现这一点?

我非常确定这个方法不存在。 - David Leitner
@DavidLeitner 必须有某些事件,因为微软已经在他们的应用程序中利用了它。它可能不会在 .NET Framework 中公开,但它肯定存在于 WinAPI 的某个地方。 - Gregory A Beamer
@gdbgeek 你想强制将某人切换到平板模式吗? - Gregory A Beamer
@GregoryABeamer几乎正确。我有一个2合1的设备,当我拆下键盘时它不会自动切换到平板模式。我可以检测到键盘被移除的时候。当这种情况发生时,我想启用平板模式。 - gdbgeek
使用Windows窗体应用程序,我可以看到消息正在广播,但从我的应用程序中执行相同操作并不会改变模式。 - gdbgeek
显示剩余2条评论
3个回答

4

在C#中没有真正的方法来做到这一点。当然,您可以更改注册表键,但是您需要注销/登录才能从或切换到平板模式。

HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\ImmersiveShell\TabletMode

启用:1 或 禁用:0

由于我在平板模式下启动 WPF 应用程序时遇到了问题,因此我使用了 AutoHotKey 脚本。您也可以创建 .exe 文件。来源:https://autohotkey.com/boards/viewtopic.php?t=15619

#NoEnv
SetBatchLines -1
ListLines Off
#NoTrayIcon 


TABLETMODESTATE_DESKTOPMODE := 0x0
TABLETMODESTATE_TABLETMODE := 0x1

TabletModeController_GetMode(TabletModeController, ByRef mode) {
    return DllCall(NumGet(NumGet(TabletModeController+0),3*A_PtrSize), "Ptr", TabletModeController, "UInt*", mode)
}

TabletModeController_SetMode(TabletModeController, _TABLETMODESTATE, _TMCTRIGGER := 4) {
    return DllCall(NumGet(NumGet(TabletModeController+0),4*A_PtrSize), "Ptr", TabletModeController, "UInt", _TABLETMODESTATE, "UInt", _TMCTRIGGER)  
}

ImmersiveShell := ComObjCreate("{C2F03A33-21F5-47FA-B4BB-156362A2F239}", "{00000000-0000-0000-C000-000000000046}")
TabletModeController := ComObjQuery(ImmersiveShell, "{4fda780a-acd2-41f7-b4f2-ebe674c9bf2a}", "{4fda780a-acd2-41f7-b4f2-ebe674c9bf2a}")

if (TabletModeController_GetMode(TabletModeController, mode) == 0)
    TabletModeController_SetMode(TabletModeController, mode == TABLETMODESTATE_DESKTOPMODE ? TABLETMODESTATE_TABLETMODE : TABLETMODESTATE_DESKTOPMODE)

ObjRelease(TabletModeController), TabletModeController := 0
ObjRelease(ImmersiveShell), ImmersiveShell := 0 ; Can be freed after TabletModeController is created, instead   

1

这里研究一下 - 你需要关注用户交互模式的示例。

注意:这是针对UWP(通用Windows平台),也就是Windows 10+,如果你不仅仅针对Win 10,则需要为其他版本的Windows编写代码。


0
根据j-krue的回答和AutoHotKey脚本。来源:https://autohotkey.com/boards/viewtopic.php?t=15619。 以下代码在Windows 10上经过测试,可以正常切换平板模式,无需重新登录或重启。
sruct ITabletModeController : IUnknown
{
    virtual HRESULT STDMETHODCALLTYPE GetMode(int* piMode) = 0;
    virtual HRESULT STDMETHODCALLTYPE SetMode(int iMode, int iModeTrigger) = 0;
};

// IID_IServiceProvider: {6D5140C1-7436-11CE-8034-00AA006009FA}
// CLSID_ImmersiveShell: {C2F03A33-21F5-47FA-B4BB-156362A2F239}
DEFINE_GUID(CLSID_ImmersiveShell, 0xC2F03A33, 0x21F5, 0x47FA, 0xB4, 0xBB, 0x15, 0x63, 0x62, 0xA2, 0xF2, 0x39);
DEFINE_GUID(IID_ITabletModeController, 0x4FDA780A, 0xACD2, 0x41F7, 0xB4, 0xF2, 0xEB, 0xE6, 0x74, 0xC9, 0xBF, 0x2A);
static void EnableTabletMode(BOOL bEnable)
{
    ::CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
    IServiceProvider* pServiceProvider = NULL;
    HRESULT hr = CoCreateInstance(CLSID_ImmersiveShell, NULL, CLSCTX_LOCAL_SERVER, IID_IServiceProvider, (PVOID*)&pServiceProvider);
    if (SUCCEEDED(hr))
    {
        ITabletModeController* pTabletController = NULL;
        hr = pServiceProvider->QueryService(IID_ITabletModeController, IID_ITabletModeController, (void**)&pTabletController);
        if (SUCCEEDED(hr) && pTabletController)
        {
            // iMode: 0 = Desktop, 1 = Tablet
            int iMode = -1;
            hr = pTabletController->GetMode(&iMode);
            int iToMode = bEnable ? 1 : 0;
            if (iMode != -1 && iMode != iToMode)
            {
                hr = pTabletController->SetMode(iToMode, 4);
            }
            pTabletController->Release();
        }
        pServiceProvider->Release();
    }

    ::CoUninitialize();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接