Устаревшая поддержка сдвига с помощью полос прокрутки
В этом разделе описывается поддержка сдвига с помощью полос прокрутки в приложениях windows.
В Windows 7 жесты сдвига создают сообщения WM_*SCROLL, чтобы включить поддержку сдвига прежних версий. Так как приложения могут поддерживать не все сообщения WM_*SCROLL, сдвиг может работать неправильно. В этом разделе описываются действия, которые необходимо предпринять для обеспечения того, чтобы устаревший интерфейс сдвига в приложениях работал так, как ожидает пользователь.
Общие сведения
В следующих разделах объясняется, как включить устаревший интерфейс сдвига.
- Создайте приложение с полосами прокрутки.
- Отключение flicks.
- Настройка интерфейса сдвига.
Создание приложения с полосами прокрутки
Запустите новый проект Win32 с помощью мастера Microsoft Visual Studio. Убедитесь, что в качестве типа приложения задано приложение Windows. Не нужно включать поддержку активной библиотеки шаблонов (ATL). На следующем рисунке показано, как будет выглядеть проект после его запуска.
Затем включите полосы прокрутки на изображении. Измените код создания окна в InitInstance , чтобы вызов функции CreateWindow создавал окно с полосами прокрутки. В следующем примере кода показано, как это сделать:
hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW | WS_VSCROLL, // style
200, // x
200, // y
550, // width
300, // height
NULL,
NULL,
hInstance,
NULL
);
После изменения кода создания окна приложение будет иметь полосу прокрутки. На следующем рисунке показано, как приложение может выглядеть на этом этапе.
После изменения кода создания окна добавьте в приложение объект полосы прокрутки и текст для прокрутки. Поместите следующий код в начало метода WndProc .
TEXTMETRIC tm;
SCROLLINFO si;
// These variables are required to display text.
static int xClient; // width of client area
static int yClient; // height of client area
static int xClientMax; // maximum width of client area
static int xChar; // horizontal scrolling unit
static int yChar; // vertical scrolling unit
static int xUpper; // average width of uppercase letters
static int xPos; // current horizontal scrolling position
static int yPos; // current vertical scrolling position
int i; // loop counter
int x, y; // horizontal and vertical coordinates
int FirstLine; // first line in the invalidated area
int LastLine; // last line in the invalidated area
HRESULT hr;
int abcLength = 0; // length of an abc[] item
int lines = 0;
// Create an array of lines to display.
static const int LINES=28;
static LPCWSTR abc[] = {
L"anteater", L"bear", L"cougar",
L"dingo", L"elephant", L"falcon",
L"gazelle", L"hyena", L"iguana",
L"jackal", L"kangaroo", L"llama",
L"moose", L"newt", L"octopus",
L"penguin", L"quail", L"rat",
L"squid", L"tortoise", L"urus",
L"vole", L"walrus", L"xylophone",
L"yak", L"zebra",
L"This line contains words, but no character. Go figure.",
L""
};
Затем реализуйте логику приложения для настройки текстовых вычислений для текстовых метрик. Следующий код должен заменить существующий WM_CREATE регистр в функции WndProc .
case WM_CREATE :
// Get the handle to the client area's device context.
hdc = GetDC (hWnd);
// Extract font dimensions from the text metrics.
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
// Free the device context.
ReleaseDC (hWnd, hdc);
// Set an arbitrary maximum width for client area.
// (xClientMax is the sum of the widths of 48 average
// lowercase letters and 12 uppercase letters.)
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
Затем реализуйте логику приложения для пересчета блока текста при изменении размера окна. Следующий код следует поместить в переключатель сообщений в WndProc.
case WM_SIZE:
// Retrieve the dimensions of the client area.
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
// Set the vertical scrolling range and page size
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = LINES - 1;
si.nPage = yClient / yChar;
SetScrollInfo(hWnd, SB_VERT, &si, TRUE);
// Set the horizontal scrolling range and page size.
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE;
si.nMin = 0;
si.nMax = 2 + xClientMax / xChar;
si.nPage = xClient / xChar;
SetScrollInfo(hWnd, SB_HORZ, &si, TRUE);
return 0;
Затем реализуйте логику приложения для сообщений вертикальной прокрутки. Следующий код следует поместить в переключатель сообщений в WndProc.
case WM_VSCROLL:
// Get all the vertical scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
GetScrollInfo (hWnd, SB_VERT, &si);
// Save the position for comparison later on
yPos = si.nPos;
switch (LOWORD (wParam))
{
// user clicked the HOME keyboard key
case SB_TOP:
si.nPos = si.nMin;
break;
// user clicked the END keyboard key
case SB_BOTTOM:
si.nPos = si.nMax;
break;
// user clicked the top arrow
case SB_LINEUP:
si.nPos -= 1;
break;
// user clicked the bottom arrow
case SB_LINEDOWN:
si.nPos += 1;
break;
// user clicked the scroll bar shaft above the scroll box
case SB_PAGEUP:
si.nPos -= si.nPage;
break;
// user clicked the scroll bar shaft below the scroll box
case SB_PAGEDOWN:
si.nPos += si.nPage;
break;
// user dragged the scroll box
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
// user positioned the scroll box
// This message is the one used by Windows Touch
case SB_THUMBPOSITION:
si.nPos = HIWORD(wParam);
break;
default:
break;
}
// Set the position and then retrieve it. Due to adjustments
// by Windows it may not be the same as the value set.
si.fMask = SIF_POS;
SetScrollInfo (hWnd, SB_VERT, &si, TRUE);
GetScrollInfo (hWnd, SB_VERT, &si);
// If the position has changed, scroll window and update it
if (si.nPos != yPos)
{
ScrollWindow(hWnd, 0, yChar * (yPos - si.nPos), NULL, NULL);
UpdateWindow (hWnd);
}
break;
Затем обновите код, чтобы перерисовать окно. Следующий код должен заменить вариант WM_PAINT по умолчанию в WndProc.
case WM_PAINT:
// Prepare the window for painting
hdc = BeginPaint (hWnd, &ps);
// Get vertical scroll bar position
si.cbSize = sizeof (si);
si.fMask = SIF_POS;
GetScrollInfo (hWnd, SB_VERT, &si);
yPos = si.nPos;
// Get horizontal scroll bar position
GetScrollInfo (hWnd, SB_HORZ, &si);
xPos = si.nPos;
// Find painting limits
FirstLine = max (0, yPos + ps.rcPaint.top / yChar);
LastLine = min (LINES - 1, yPos + ps.rcPaint.bottom / yChar);
for (i = FirstLine; i <= LastLine; i++)
{
x = xChar * (1 - xPos);
y = yChar * (i - yPos);
// Note that "55" in the following depends on the
// maximum size of an abc[] item.
//
abcLength = wcslen(abc[i]);
hr = S_OK;
if ((FAILED(hr)))
{
MessageBox(hWnd, L"err", L"err", NULL);
}else{
TextOut(hdc, x, y, abc[i], abcLength);
}
}
// Indicate that painting is finished
EndPaint (hWnd, &ps);
return 0;
Теперь при сборке и запуске приложения в нем должен быть стандартный текст и вертикальная полоса прокрутки. На следующем рисунке показано, как может выглядеть приложение.
Отключение Flicks
Чтобы улучшить процесс сдвига в приложении, следует отключить жесты. Для этого задайте свойства окна для значения hWnd при его инициализации. Значения, используемые для щелчков, хранятся в заголовке tpcshrd.h, который также должен быть включен. Следующий код следует поместить в директивы include и в функцию InitInstance после создания hWnd.
Примечание
Это полезно для приложений, которым требуется немедленная обратная связь о событии касания или нажатия пера вместо проверки порогового значения времени или расстояния.
#include <tpcshrd.h>
[...]
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow){
[...]
const DWORD_PTR dwHwndTabletProperty =
TABLET_DISABLE_PRESSANDHOLD | // disables press and hold (right-click) gesture
TABLET_DISABLE_PENTAPFEEDBACK | // disables UI feedback on pen up (waves)
TABLET_DISABLE_PENBARRELFEEDBACK | // disables UI feedback on pen button down (circle)
TABLET_DISABLE_FLICKS; // disables pen flicks (back, forward, drag down, drag up)
SetProp(hWnd, MICROSOFT_TABLETPENSERVICE_PROPERTY, reinterpret_cast<HANDLE>(dwHwndTabletProperty));
Настройка интерфейса сдвига
По умолчанию может потребоваться другой режим сдвига, отличный от возможностей Windows 7. Чтобы улучшить процесс сдвига, необходимо добавить обработчик для сообщения WM_GESTURE . Дополнительные сведения см. в разделе Улучшение Single-Finger сдвига.
Связанные темы