Улучшение Single-Finger сдвига
Если вы создаете приложение, предназначенное для Windows Touch, оно автоматически обеспечивает базовую поддержку сдвигов. Однако вы можете использовать сообщение WM_GESTURE , чтобы обеспечить расширенную поддержку сдвига одним пальцем.
Общие сведения
Чтобы улучшить сдвиг одним пальцем, выполните следующие действия, как описано в последующих разделах этой статьи:
- Создайте приложение с полосами прокрутки и отключенными щелчками.
- Добавлена поддержка сообщений сдвига жестов.
- Включите отказ.
Создание приложения с полосами прокрутки и отключенными flicks
Перед началом работы необходимо создать приложение с полосами прокрутки. Этот процесс описан в разделе Устаревшая поддержка сдвига с помощью полос прокрутки . Если вы хотите начать с примера содержимого, перейдите в этот раздел и создайте приложение с полосами прокрутки, а затем отключите жесты. Если у вас уже есть приложение с функционируюющими полосами прокрутки, отключите щелчки, как описано в этом разделе.
Добавлена поддержка настраиваемого сдвига для сообщений жестов
Для поддержки сообщений сдвига жестов их необходимо обрабатывать в методе WndProc . Сообщения жестов используются для определения горизонтальных и вертикальных изменений для сообщений сдвига. Разностные значения используются для обновления объекта полосы прокрутки, который обновляет пользовательский интерфейс.
Сначала обновите параметры версии Windows в файле targetver.h, чтобы включить Windows Touch. В следующем коде показаны различные параметры версии Windows, которые должны заменить параметры в targetver.h.
#ifndef WINVER // Specifies that the minimum required platform is Windows Vista.
#define WINVER 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
#ifndef _WIN32_WINNT // Specifies that the minimum required platform is Windows Vista.
#define _WIN32_WINNT 0x0601 // Change this to the appropriate value to target other versions of Windows.
#endif
Затем добавьте файл UXTheme.h в проект и библиотеку uxtheme.lib к дополнительным зависимостям проекта.
#include <uxtheme.h>
Затем добавьте следующие переменные в начало функции WndProc . Они будут использоваться в вычислениях для сдвига.
// The following are used for the custom panning handler
BOOL bResult = FALSE;
static int scale = 8; // altering the scale value will change how fast the page scrolls
static int lastY = 0; // used for panning calculations (initial / previous vertical position)
static int lastX = 0; // used for panning calculations (initial / previous horizontal position)
GESTUREINFO gi;
Затем добавьте обработчик для сообщения WM_GESTURE , чтобы полосы прокрутки обновлялись с разностями на основе жестов сдвига. Это дает вам гораздо более детализированный контроль сдвига.
Следующий код получает структуру GESTUREINFO из lParam, сохраняет последнюю координату y из структуры и определяет изменение позиции для обновления объекта полосы прокрутки. Следующий код следует поместить в инструкцию WndProc switch.
case WM_GESTURE:
// Get all the vertial scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo (hWnd, SB_VERT, &si);
yPos = si.nPos;
ZeroMemory(&gi, sizeof(GESTUREINFO));
gi.cbSize = sizeof(GESTUREINFO);
bResult = GetGestureInfo((HGESTUREINFO)lParam, &gi);
if (bResult){
// now interpret the gesture
switch (gi.dwID){
case GID_BEGIN:
lastY = gi.ptsLocation.y;
CloseGestureInfoHandle((HGESTUREINFO)lParam);
break;
// A CUSTOM PAN HANDLER
// COMMENT THIS CASE OUT TO ENABLE DEFAULT HANDLER BEHAVIOR
case GID_PAN:
si.nPos -= (gi.ptsLocation.y - lastY) / scale;
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
yOverpan -= lastY - gi.ptsLocation.y;
lastY = gi.ptsLocation.y;
if (gi.dwFlags & GF_BEGIN){
BeginPanningFeedback(hWnd);
yOverpan = 0;
} else if (gi.dwFlags & GF_END) {
EndPanningFeedback(hWnd, TRUE);
yOverpan = 0;
}
if (si.nPos == si.nMin || si.nPos >= (si.nMax - si.nPage)){
// we reached the bottom / top, pan
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
return DefWindowProc(hWnd, message, lParam, wParam);
case GID_ZOOM:
// Add Zoom handler
return DefWindowProc(hWnd, message, lParam, wParam);
default:
// You have encountered an unknown gesture
return DefWindowProc(hWnd, message, lParam, wParam);
}
}else{
DWORD dwErr = GetLastError();
if (dwErr > 0){
// something is wrong
// 87 indicates that you are probably using a bad
// value for the gi.cbSize
}
}
return DefWindowProc (hWnd, message, wParam, lParam);
Теперь, когда вы выполняете жест панорамирования в окне, вы увидите прокрутку текста с инерцией. На этом этапе может потребоваться изменить текст на большее количество строк, чтобы можно было просматривать сдвиг больших разделов текста.
Обратная связь по границам в WndProc
Обратная связь границы — это тип визуальной обратной связи, выдаваемой пользователям, когда они достигают конца области сдвига. Он активируется приложением при достижении границы. В предыдущем примере реализации сообщения WM_GESTURE конечное условие (si.nPos == si.yPos)
из WM_GESTURE случае используется для проверки того, что вы достигли конца области сдвига. Следующие переменные используются для отслеживания значений и проверки ошибок.
// The following are used for panning feedback (Window Bounce)
static int animCount = 0;
static DWORD dwErr = 0;
static BOOL isOverpan = FALSE;
static long xOverpan = 0;
static long yOverpan = 0;
Регистр жеста сдвиг обновляется для активации обратной связи границ. Следующий код иллюстрирует GID_PAN регистр из обработчика сообщений WM_GESTURE .
case GID_PAN:
si.nPos -= (gi.ptsLocation.y - lastY) / scale;
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
yOverpan -= lastY - gi.ptsLocation.y;
lastY = gi.ptsLocation.y;
if (gi.dwFlags & GF_BEGIN){
BeginPanningFeedback(hWnd);
yOverpan = 0;
} else if (gi.dwFlags & GF_END) {
EndPanningFeedback(hWnd, TRUE);
yOverpan = 0;
}
if (si.nPos == si.nMin){
// we reached the top, pan upwards in y direction
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}else if (si.nPos >= (si.nMax - si.nPage)){
// we reached the bottom, pan downwards in y direction
UpdatePanningFeedback(hWnd, 0, yOverpan, gi.dwFlags & GF_INERTIA);
}
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
return DefWindowProc(hWnd, message, lParam, wParam);
Теперь окно приложения должно иметь обратную связь границы, когда пользователь перемещается за пределы нижней части области полосы прокрутки.
Связанные темы