以下示例显示如何使应用程序滚动文本以响应水平和垂直滚动条的输入。
HDC hdc;
PAINTSTRUCT ps;
TEXTMETRIC tm;
SCROLLINFO si;
/ *显示文本需要这些变量。*/
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 */
static int xMax; /* maximum horiz. scrolling position */
static int yMax; /* maximum vert. scrolling position */
int xInc; /* horizontal scrolling increment */
int yInc; /* vertical scrolling increment */
int i; /* loop counter */
int x, y; /* horiz. and vert. printing coords */
int FirstLine; /* first line in the invalidated area */
int LastLine; /* last line in the invalidated area */
/ *创建要显示的行数组。*/
"elephant", "frog", "gazelle", "hyena", "iguana", "jackal",
static char *abc[] = { "anteater", "bear", "cougar", "dingo",
“大象”,“青蛙”,“瞪羚”,“鬣狗”,“鬣蜥”,“豺狼”
“袋鼠”,“骆驼”,“驼鹿”,“蝾螈”,“章鱼”,“企鹅”
“鹌鹑”,“大鼠”,“鱿鱼”,“乌龟”,“乌鸦”,“野兽”
“海象”,“木琴”,“牦牛”,“斑马”,
"This line contains many words, but no character. Go figure." };
开关(uMsg){
case WM_CREATE :
/ *获取客户区的设备上下文的句柄。*/
hdc = GetDC (hwnd);
/ *从文本指标中提取字体维度。*/
GetTextMetrics (hdc, &tm);
xChar = tm.tmAveCharWidth;
xUpper = (tm.tmPitchAndFamily & 1 ? 3 : 2) * xChar/2;
yChar = tm.tmHeight + tm.tmExternalLeading;
/ *释放设备上下文。*/
ReleaseDC (hwnd, hdc);
/*
*设置客户区域的任意最大宽度。
*(xClientMax是宽度为48的平均值之和
*小写字母和12个大写字母。)
*/
xClientMax = 48 * xChar + 12 * xUpper;
return 0;
case WM_SIZE:
/ *检索客户区域的维度。*/
yClient = HIWORD (lParam);
xClient = LOWORD (lParam);
/*
*确定最大垂直滚动位置。
*这两个被添加到线下面的额外空间
*文字。
*/
yMax = max (0, LINES + 2 - yClient/yChar);
/*
*确保当前垂直滚动位置
*不超过最大值。
*/
yPos = min (yPos, yMax);
/*
*调整垂直滚动范围和滚动框
*位置来反映新的yMax和yPos值。
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = yMax;
si.nPage = yClient / yChar;
si.nPos = yPos;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
/*
*确定最大水平滚动位置。
*两者被添加到右侧的额外空间
*文字行。
*/
xMax = max (0, 2 + (xClientMax - xClient)/xChar);
/*
*确保当前水平滚动位置
*不超过最大值。
*/
xPos = min (xPos, xMax);
/*
*调整水平滚动范围和滚动框
*位置反映新的xMax和xPos值。
*/
si.cbSize = sizeof(si);
si.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
si.nMin = 0;
si.nMax = xMax;
si.nPage = xClient / xChar;
si.nPos = xPos;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
return 0;
case WM_PAINT:
/ *准备画画窗口。*/
hdc = BeginPaint(hwnd, &ps);
/*
*使用当前的垂直滚动位置和
*无效矩形的坐标来确定
*应该绘制的新线条的范围
*客户区。
*/
FirstLine = max (0, yPos + ps.rcPaint.top/yChar - 1);
LastLine = min (LINES, yPos + ps.rcPaint.bottom/yChar);
/ *显示这些行。*/
for (i = FirstLine;i < LastLine;i++) {
x = xChar * (1 - xPos);
y = yChar * (1 - yPos + i);
TextOut (hdc, x, y, abc[i], lstrlen(abc[i]));
}
/ *表示绘画完成。*/
EndPaint(hwnd, &ps);
break;
case WM_HSCROLL:
开关(LOWORD(wParam)){
/ *用户点击滚动条左侧的轴。*/
case SB_PAGEUP:
xInc = -8;
break;
/ *用户点击滚动框右侧的轴。*/
case SB_PAGEDOWN:
xInc = 8;
break;
/ *用户点击左箭头。*/
case SB_LINEUP:
xInc = -1;
break;
/ *用户点击右箭头。*/
case SB_LINEDOWN:
xInc = 1;
break;
/ *用户拖动滚动框。*/
case SB_THUMBTRACK:
xInc = HIWORD(wParam) - xPos;
break;
默认:
xInc = 0;
}
/*
*如果应用水平滚动增量没有
*将滚动位置从滚动范围中移出,
*增加滚动位置,调整位置
*的滚动框,并更新窗口。
*/
if (xInc = max (-xPos, min (xInc, xMax - xPos))) {
xPos += xInc;
ScrollWindowEx(hwnd,-xChar * xInc,0,
(CONST RECT *) NULL, (CONST RECT *) NULL,
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = xPos;
SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
UpdateWindow (hwnd);
}
return 0;
case WM_VSCROLL:
开关(LOWORD(wParam)){
/ *用户点击滚动框上方的轴。*/
case SB_PAGEUP:
yInc = min(-1, -yClient / yChar);
break;
/ *用户点击滚动条下方的轴。*/
case SB_PAGEDOWN:
yInc = max(1, yClient / yChar);
break;
/ *用户点击顶部箭头。*/
case SB_LINEUP:
yInc = -1;
break;
/ *用户点击底部箭头。*/
case SB_LINEDOWN:
yInc = 1;
break;
/ *用户拖动滚动框。*/
case SB_THUMBTRACK:
yInc = HIWORD(wParam) - yPos;
break;
默认:
yInc = 0;
}
/*
*如果应用垂直滚动增量没有
*将滚动位置从滚动范围中移出,
*增加滚动位置,调整位置
*的滚动框,并更新窗口。UpdateWindow
*发送WM_PAINT消息。
*/
if (yInc = max(-yPos, min(yInc, yMax - yPos))) {
yPos += yInc;
ScrollWindow(hwnd,0,-yChar * yInc,
(CONST RECT *) NULL, (CONST RECT *) NULL,
(HRGN) NULL, (LPRECT) NULL, SW_INVALIDATE);
si.cbSize = sizeof(si);
si.fMask = SIF_POS;
si.nPos = YPos;
SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
UpdateWindow (hwnd);
}
return 0;