如何以编程方式将 Windows 11 22H2 从平板电脑模式切换到桌面模式?

nos*_*tio 6 .net c# c++ windows winapi

我的 Lenovo Yoga 7i 笔记本电脑默认以平板电脑模式启动,因此我最终会看到大型桌面/任务栏图标和其他令人不快的 UI 工件。

Lenovo Yoga Mode Control for Windows这可以通过安装并运行Lenovo 专有服务 ( )来解决,YMC.EXE该服务因过度使用 CPU 而臭名昭著。

就我而言,YMC 在 Windows 服务管理器中设置为Manual。为了让 Windows 回到桌面模式,我必须从管理控制台手动启动和停止 YMC:net start ymc && net stop ymc每次系统重新启动时。

我正在寻找一种编程方法来执行 YMC 正在执行的操作,将 Windows 11 切换到桌面模式。,将其包装为一个小型实用程序应用程序。

到目前为止我找到的唯一相关答案是这个,提到了未记录的内容ITabletModeController

var pSP = (IServiceProvider)Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_ImmersiveShell));
var pTMC = (ITabletModeController)pSP.QueryService(typeof(ITabletModeController).GUID, typeof(ITabletModeController).GUID);
if (pTMC != null)
{
    // 0 = Desktop, 1 = Tablet
    int nMode = 0;
    int nRet = pTMC.GetMode(ref nMode);
    nRet = pTMC.SetMode(nMode==0?1:0, 4);
}
Run Code Online (Sandbox Code Playgroud)

我尝试了一下没有效果。ChatGPT 也没有帮助:)

dar*_*der 3

好吧,我将其作为答案发布,因为我认为评论太多了。如果与问题无关,请评论,以便我删除它。我没有,Lenovo Yoga 7i但我Acer Travelmate Spin也有平板电脑模式。

根据GetSystemMetrics , GetSystemMetrics(SM_CONVERTIBLESLATEMODE); // 0x2003 我们似乎能够读取是否处于 slate 模式01位置slate 0 = tablet以及slate 1 = laptop or other devices根据Convertibleslatemode

文档声称:

反映笔记本电脑或平板模式的状态,0 表示平板模式,否则非零。当此系统指标发生变化时,系统通过 WM_SETTINGCHANGE 发送一条 LPARAM 中包含“ConvertibleSlateMode”的广播消息。请注意,此系统指标不适用于台式电脑。在这种情况下,请使用 GetAutoRotationState。

我尝试通过以下方式自己进行广播:

DWORD_PTR res;
SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM) L"ConvertibleSlateMode", SMTO_ABORTIFHUNG, 1000, &res);
Run Code Online (Sandbox Code Playgroud)

这没有用。

然后我意识到有一个注册表项 at: Computer\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\PriorityControlcallConvertibleSlateMode反映了之前提到的值slate 0 and 1

如果您处于平板电脑模式 ( slate 0) 并将 regkey 的值设置为 1,则会进入桌面模式。我不确定是否需要广播(上面提到的),但对我来说,它可以(在平板电脑模式下)将 regkey 设置为 0,然后设置为 1。

在 C++ 中,这可以通过以下方式完成:

void setRegKey(const DWORD value) {
    HKEY hKey;
    LONG regStatus = RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\PriorityControl", 0, KEY_SET_VALUE, &hKey);

    if (regStatus != ERROR_SUCCESS) {
        std::cout << "Error opening registry key.\n";
        return;
    }

    const wchar_t* valueName = L"ConvertibleSlateMode";


    regStatus = RegSetValueExW(hKey, valueName, 0, REG_DWORD, (BYTE*)&value, sizeof(DWORD));

    if (regStatus != ERROR_SUCCESS) {
        std::cout << "Error setting registry value.\n";
        RegCloseKey(hKey);
        return;
    }

    RegCloseKey(hKey);

    std::cout << "Registry value set successfully.\n";
}
Run Code Online (Sandbox Code Playgroud)

然后在主要部分:

int main() {
    setRegKey(0);
    setRegKey(1);
}
Run Code Online (Sandbox Code Playgroud)

编辑:正如@BenVoigt 和@KeshavV 提到的。您很可能也可以按照以下步骤操作:Windows 10 平板电脑模式注册表设置:“当此设备自动打开或关闭平板电脑模式时”

更多相关链接:
GetSystemMetrics
WM_SETTINGCHANGE
SendMessageTimeout
ConvertibleslateMode