В этом проекте демонстрируется определение режима работы ноутбука-трансформера (режим планшета либо режим ноутбука) под управлением Windows 8(.1), а также новый режим управления с помощью мыши и сенсорного экрана в Windows 10. Режим управления с помощью мыши и сенсорного экрана аналогичен режиму планшета и ноутбука, но в Windows 10 пользователи получили возможность вручную переключать режим, тогда как в Windows 8 режим переключается только в зависимости от физического состояния устройства. Поэтому пользователи Windows 10 могут использовать расширенный графический пользовательский интерфейс, предназначенный для сенсорного управления, даже на устройствах, не являющихся трансформерами: важно только наличие сенсорного экрана. Эта новая возможность реализована на основе новых API UWP (Universal Windows Platform). Нужно добавить несколько строк кода в приложения, предназначенные для Windows 8, чтобы воспользоваться этой функцией в Windows 10. В этом документе показана доработка приложений Win32 для использования API UWP с помощью WRL (библиотеки шаблонов C++ среды выполнения Windows) в Windows 10. Сведения о включении приложений UWP см. в образце кода Microsoft.
Настройка вручную
Проведите по экрану от правого края экрана к середине, чтобы открыть Центр поддержки (меню чудо-кнопок в Windows 8).
Коснитесь кнопки «Режим планшета» для переключения между режимом сенсорного управления и режимом управления с помощью мыши.
Выбор с помощью оборудования
Когда устройство-трансформер обнаруживает изменение физического состояния, оно оповещает об этом ОС.
ОС запрашивает подтверждение у пользователя. Если пользователь подтверждает, ОС переключает режим.
Для проверки перейдите в раздел «Настройки» -> «Система» -> «Планшетный режим» и установите флажок «Всегда запрашивать разрешение перед переключением режима».
В зависимости от ОС в образце приложения на основе диалоговых окон произойдет следующее.
В Windows 8 передается сообщение WM_SETTINGCHANGE (lParam == “ConvertibleSlateMode”) при изменении физического состояния, а в Windows 10 передается WM_SETTINGCHANGE (lParam == “UserInteractionMode”) в окно верхнего уровня. При этом также передается и прежнее сообщение. Приложение должно определять версию ОС и выбирать тот или иной код в зависимости от нее. В противном случае приложение в Windows 10 будет дважды реагировать на описанные выше сообщения.
После того как приложение получает сообщение, оно опрашивает текущее состояние, поскольку сообщение только уведомляет ОС об изменении режима, но не о текущем состоянии. Не существует API Win32, позволяющего опрашивать новое состояние напрямую, но можно использовать WRL для доступа к компонентам Windows RT из приложения Win32, как показано в следующем фрагменте кода.
В этом образце кода показана реализация обнаружения режимов работы трансформера в Windows 8/8.1 и Windows 10 с помощью Win32. В приложениях для Магазина Windows под управлением Windows 8 не было возможности обнаруживать события трансформеров. В Windows 10 поддерживаются API UWP, чтобы универсальные приложения могли использовать функциональность трансформеров. Вместо использования аналогичного API Win32 представлен метод использования API UWP из приложения Win32. Следует отметить, что API UWP не имеют особого уведомления для этого события; они используют события изменения размера окна с последующей проверкой текущего состояния. Если состояние отличается от сохраненного, то предполагается, что оно изменилось. Если использовать сообщения Win32 неудобно (например, в приложениях Java*), можно использовать событие изменения размера окна в Java и вызвать оболочку JNI для подтверждения состояния.
Требования
- Windows 10
- Visual Studio* 2015. Новый API отсутствует в Visual Studio 2013
Описание режима управления с помощью мыши и сенсорного экрана в Windows 10
Настройка вручную
Проведите по экрану от правого края экрана к середине, чтобы открыть Центр поддержки (меню чудо-кнопок в Windows 8).
Коснитесь кнопки «Режим планшета» для переключения между режимом сенсорного управления и режимом управления с помощью мыши.
Выбор с помощью оборудования
Когда устройство-трансформер обнаруживает изменение физического состояния, оно оповещает об этом ОС.
ОС запрашивает подтверждение у пользователя. Если пользователь подтверждает, ОС переключает режим.
Для проверки перейдите в раздел «Настройки» -> «Система» -> «Планшетный режим» и установите флажок «Всегда запрашивать разрешение перед переключением режима».
Образец приложения
В зависимости от ОС в образце приложения на основе диалоговых окон произойдет следующее.
- Windows 10: при ручном или автоматическом переключении будет зарегистрировано событие режима сенсорного управления/управления с помощью мыши и время этого события.
- Windows 8: будут зарегистрированы события изменения физического состояния и их время (режим планшета/режим ноутбука).
В Windows 8 передается сообщение WM_SETTINGCHANGE (lParam == “ConvertibleSlateMode”) при изменении физического состояния, а в Windows 10 передается WM_SETTINGCHANGE (lParam == “UserInteractionMode”) в окно верхнего уровня. При этом также передается и прежнее сообщение. Приложение должно определять версию ОС и выбирать тот или иной код в зависимости от нее. В противном случае приложение в Windows 10 будет дважды реагировать на описанные выше сообщения.
void CMy2in1LogDlg::OnSettingChange(UINT uFlags, LPCTSTR lpszSection)
{
CDialogEx::OnSettingChange(uFlags, lpszSection);
// TODO: Add your message handler code here
if (lpszSection != NULL)
{
CString strMsg = CString(lpszSection);
if (m_dwVersionMajor < 10 && strMsg == _T("ConvertibleSlateMode"))
{
CString strTime;
GetTime(strTime);
BOOL bSlate = GetSystemMetrics(SM_CONVERTIBLESLATEMODE) == 0;
CString strMsg = CString(bSlate ? _T("Slate Mode") : _T("Clamshell Mode"));
m_ctrlEvents.InsertItem(m_iEvent, strTime);
m_ctrlEvents.SetItemText(m_iEvent, 1, strMsg);
m_iEvent++;
return;
}
if (m_dwVersionMajor >= 10 && strMsg == _T("UserInteractionMode"))
{
CString strTime, strMsg;
GetTime(strTime);
int mode;
if (GetUserInteractionMode(mode) == S_OK)
{
if (mode == UserInteractionMode_Mouse)
strMsg.Format(_T("Mouse Mode"));
else if (mode == UserInteractionMode_Touch)
strMsg.Format(_T("Touch Mode"));
m_ctrlEvents.InsertItem(m_iEvent, strTime);
m_ctrlEvents.SetItemText(m_iEvent, 1, strMsg);
m_iEvent++;
}
}
}
}
После того как приложение получает сообщение, оно опрашивает текущее состояние, поскольку сообщение только уведомляет ОС об изменении режима, но не о текущем состоянии. Не существует API Win32, позволяющего опрашивать новое состояние напрямую, но можно использовать WRL для доступа к компонентам Windows RT из приложения Win32, как показано в следующем фрагменте кода.
HRESULT CMy2in1LogDlg::GetUserInteractionMode(int & iMode)
{
ComPtr<IUIViewSettingsInterop> uiViewSettingsInterop;
HRESULT hr = GetActivationFactory(
HStringReference(RuntimeClass_Windows_UI_ViewManagement_UIViewSettings).Get(), &uiViewSettingsInterop);
if (SUCCEEDED(hr))
{
ComPtr<IUIViewSettings> uiViewSettings;
hr = uiViewSettingsInterop->GetForWindow(this->m_hWnd, IID_PPV_ARGS(&uiViewSettings));
if (SUCCEEDED(hr))
{
UserInteractionMode mode;
hr = uiViewSettings->get_UserInteractionMode(&mode);
if (SUCCEEDED(hr))
{
switch (mode)
{
case UserInteractionMode_Mouse:
iMode = UserInteractionMode_Mouse;
break;
case UserInteractionMode_Touch:
iMode = UserInteractionMode_Touch;
break;
default:
break;
}
}
}
}
return S_OK;
}
Заключение и другие возможности
В этом образце кода показана реализация обнаружения режимов работы трансформера в Windows 8/8.1 и Windows 10 с помощью Win32. В приложениях для Магазина Windows под управлением Windows 8 не было возможности обнаруживать события трансформеров. В Windows 10 поддерживаются API UWP, чтобы универсальные приложения могли использовать функциональность трансформеров. Вместо использования аналогичного API Win32 представлен метод использования API UWP из приложения Win32. Следует отметить, что API UWP не имеют особого уведомления для этого события; они используют события изменения размера окна с последующей проверкой текущего состояния. Если состояние отличается от сохраненного, то предполагается, что оно изменилось. Если использовать сообщения Win32 неудобно (например, в приложениях Java*), можно использовать событие изменения размера окна в Java и вызвать оболочку JNI для подтверждения состояния.