case WM_SIZE:
○ cxClient = LOWORD (lParam) ;
cyClient = HIWORD (lParam) ;
// Set vertical scroll bar range and page size
si.cbSize = sizeof (si) ;
si.fMask = SIF_RANGE | SIF_PAGE ;
si.nMin = 0 ;
si.nMax = NUMLINES - 1 ;
○ si.nPage = cyClient / cyChar ;
○ SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
// Set horizontal scroll bar range and page size
si.cbSize = sizeof (si) ;
si.fMask = SIF_RANGE | SIF_PAGE ;
si.nMin = 0 ;
si.nMax = 2 + iMaxWidth / cxChar ;
○ si.nPage = cxClient / cxChar ;
○ SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;
return 0 ;
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
iVertPos = si.nPos ;
switch (LOWORD (wParam))
{
case SB_TOP:
si.nPos = si.nMin ;
break ;
case SB_BOTTOM:
si.nPos = si.nMax ;
break ;
case SB_LINEUP:
si.nPos - = 1 ;
break ;
case SB_LINEDOWN:
si.nPos += 1 ;
break ;
case SB_PAGEUP:
si.nPos -= si.nPage ;
break ;
case SB_PAGEDOWN:
si.nPos += si.nPage ;
break ;
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 the window and update it
if (si.nPos != iVertPos)
{
ScrollWindow (hwnd, 0, cyChar * (iVertPos - si.nPos),
NULL, NULL) ;
UpdateWindow (hwnd) ;
}
return 0 ;
case WM_HSCROLL:
// Get all the vertical scroll bar information
si.cbSize = sizeof (si) ;
si.fMask = SIF_ALL ; // Save the position for comparison later on
GetScrollInfo (hwnd, SB_HORZ, &si) ;
iHorzPos = si.nPos ;
switch (LOWORD (wParam))
{
case SB_LINELEFT:
si.nPos -= 1 ;
break ;
case SB_LINERIGHT:
si.nPos += 1 ;
break ; case SB_PAGELEFT:
si.nPos -= si.nPage ;
break ;
case SB_PAGERIGHT:
si.nPos += si.nPage ;
break ;
case SB_THUMBPOSITION:
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 != iHorzPos)
{
ScrollWindow (hwnd, cxChar * (iHorzPos - si.nPos), 0,
NULL, NULL) ;
}
return 0 ;
这段代码是《windows程序设计》第四章说滚动条的时候出现的最后一个示例程序。
我把它粘在win7下的VC里,编译后运行。并没有出现水平滚动条,但是有垂直滚动条。
我设了几个断点如上所示:
单步执行,先从第一个断点到最后一个断点,继续单步执行它又回到第一个断点,一直单步到最后一个断点,再单步一次就到了return 0 了。我不明白为什么第一次单步到最后一个断点的时候不跳到return 0,却回去再执行一次。难道是因为nPage大小变了引起重绘所以又执行一次?期间我跟踪了一下nPage的值: 29 141 3435973836 30 141,如果是重绘引起的话它应该永久循环下去才是啊。
还有就是为什么水平滚动条没有显示,但是如果把 si.nPage= cxClient / cxChar ;这一条语句去掉的话就出现水平滚动条了。把这句去掉或是换成si.nPage = cyClient / cyChar ;的话都能出现。
或是把SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
这两句之间的东西都删掉都可以。如果不到si重新赋值的话,水平滚动条所用的si不就是旧有的吗,这个时候水平滚动条的移动范围准确不?实在不明白为什么,大侠指教,谢谢。
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货