Search code examples
c++winapiwindows-runtimec++-winrt

How to use Windows.UI.ViewManagement.UIViewSettings from WinRT/C++?


We have a pure Win32/C++ app from which we want to be able to detect Tablet Mode on Windows 10.

I have the following code which came from somewhere which uses WRL to access the Windows.UI.ViewManagement.UIViewSettings.UserInteractionMode property:

WRL::ComPtr<IUIViewSettingsInterop> interop;
if (SUCCEEDED(Windows::Foundation::GetActivationFactory(WRL::Wrappers::HStringReference(
    RuntimeClass_Windows_UI_ViewManagement_UIViewSettings).Get(),
    &interop)) && interop)
{
    WRL::ComPtr<vm::IUIViewSettings> pViewSettings;
    if (SUCCEEDED(interop->GetForWindow(hWnd, IID_PPV_ARGS(&pViewSettings))) && pViewSettings)
    {
        vm::UserInteractionMode currentMode;
        if (SUCCEEDED(pViewSettings->get_UserInteractionMode(&currentMode)))
            return currentMode == vm::UserInteractionMode::UserInteractionMode_Touch;
    }
}

This works fine, however we also have another function using WinRT and I gather WinRT is the current technology we should be using for this, so I was trying to work out how to convert the WRL code.

I came up with this code, which compiles fine, but throws an exception in GetForCurrentView():

auto uiSettings = winrt::Windows::UI::ViewManagement::UIViewSettings::GetForCurrentView();
return uiSettings.UserInteractionMode() == winrt::Windows::UI::ViewManagement::UserInteractionMode::Touch;

The error is HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND). I'm assuming there's something I'm meant to be doing to initialise the "current view", similar to how the WRL code provides a window handle to GetForWindow, but I haven't been able to work out how or what that is.


Solution

  • Thanks to @RaymondChen the C++/WinRT equivalent of the WRL code in my question is:

    auto uiSettings = winrt::capture<winrt::Windows::UI::ViewManagement::UIViewSettings>
        (winrt::get_activation_factory<winrt::Windows::UI::ViewManagement::UIViewSettings>()
            .as<IUIViewSettingsInterop>(), &IUIViewSettingsInterop::GetForWindow, hWnd);
    return uiSettings.UserInteractionMode() == winrt::Windows::UI::ViewManagement::UserInteractionMode::Touch;