CWnd::SetScrollInfo()函数到底怎么设置???

dragon17162 2012-02-10 04:38:36
翻遍了互联网,就是找不到SetScrollInfo的应用实例,全部都是照抄。。。除了无语别无选择。。。

假如要显示的内容是200像素,而显示窗口只有100(这里应该是可显示区域,去掉边框还有滚动条自身的宽度),那么如何用
SetScrollInfo()函数来设置滚动条呢?不管我怎么设置,都不对!!

// 设置滚动条参数
SCROLLINFO info;
info.cbSize = sizeof( SCROLLINFO );
info.fMask = SIF_ALL;
info.nMin = 0;
info.nMax = 200 - 100;
info.nPage = 20;
info.nPos = 10;
info.nTrackPos = 0;

但是当拖动滚动条松下时,最大值总是到不了200-100,网上竟然找不到具体nMax指什么,可是这滚动条无处不在啊,几乎看到的很多软件都有用到滚动条。。。

nMax不就是要显示的内容高度 - 窗口的高度吗?

对了,我使用的是CWnd::SetScrollInfo()函数而不是WIN32 API函数!
...全文
466 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
fengge8ylf 2012-04-06
  • 打赏
  • 举报
回复
我现在也在迷惑这个问题了
Eleven 2012-02-20
  • 打赏
  • 举报
回复
MSDN上不是有个例子代码吗?可以参考一下
HDC hdc; 
PAINTSTRUCT ps;
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;
size_t * abcLength; // length of an abc[] item

// Create an array of lines to display.
#define LINES 28
static TCHAR *abc[] = {
TEXT("anteater"), TEXT("bear"), TEXT("cougar"),
TEXT("dingo"), TEXT("elephant"), TEXT("falcon"),
TEXT("gazelle"), TEXT("hyena"), TEXT("iguana"),
TEXT("jackal"), TEXT("kangaroo"), TEXT("llama"),
TEXT("moose"), TEXT("newt"), TEXT("octopus"),
TEXT("penguin"), TEXT("quail"), TEXT("rat"),
TEXT("squid"), TEXT("tortoise"), TEXT("urus"),
TEXT("vole"), TEXT("walrus"), TEXT("xylophone"),
TEXT("yak"), TEXT("zebra"),
TEXT("This line contains words, but no character. Go figure."),
TEXT("")
};

switch (uMsg)
{
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;

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;
case WM_HSCROLL:
// Get all the vertial scroll bar information
si.cbSize = sizeof (si);
si.fMask = SIF_ALL;
// Save the position for comparison later on
GetScrollInfo (hwnd, SB_HORZ, &si);
xPos = si.nPos;
switch (LOWORD (wParam))
{
// user clicked left arrow
case SB_LINELEFT:
si.nPos -= 1;
break;

// user clicked right arrow
case SB_LINERIGHT:
si.nPos += 1;
break;

// user clicked the scroll bar shaft left of the scroll box
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;

// user clicked the scroll bar shaft right of the scroll box
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;

// user dragged the scroll box
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
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_HORZ, &si, TRUE);
GetScrollInfo (hwnd, SB_HORZ, &si);

// If the position has changed, scroll the window
if (si.nPos != xPos)
{
ScrollWindow(hwnd, xChar * (xPos - si.nPos), 0, NULL, NULL);
}
return 0;

case WM_VSCROLL:
// Get all the vertial 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;

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);
}
return 0;

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.
//
hr = StringCchLength(abc[i], 55, abcLength);
if ((FAILED(hr))|(abcLength == NULL))
{
//
// TODO: write error handler
//
}

}
// Indicate that painting is finished
EndPaint (hwnd, &ps);
return 0;

case WM_DESTROY :
PostQuitMessage (0);
return 0;
}
return DefWindowProc (hwnd, uMsg, wParam, lParam);
}
dragon17162 2012-02-20
  • 打赏
  • 举报
回复
谢谢楼上的朋友,这篇文章真是好哇!

可是最后关于SetScrollInfo()的部分有些看不太明白:

但新滚动条函数的一个好的功能是当使用与滚动条范围一样大的页面时,它已经为您做出了大量的逻辑功能。

这样之后,Windows会把最大的滚动条位置限制为si.nMax-si.nPage+1,而不是si.nMax。

这里关于nMax的设置还是有些疑问,和页面大小有关系吗?我现在设置的nMax有时对有时不对!
dragon17162 2012-02-20
  • 打赏
  • 举报
回复
看了,可还是不理解!!

我只问,这里nMax,nPage该设置为多少,是像素吗?和窗口客户区高度,实际要显示内容的高度该怎么关联起来,假如实际内容高度大于窗口客户区高度。。。
dragon17162 2012-02-14
  • 打赏
  • 举报
回复
不是吧,没人知道?

16,548

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • AIGC Browser
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧