VC/MFC加滚动条显示大图片SetScrollRange()、SetScrollInfo()两种思路实现及其两者优劣比较

原创 2015年11月18日 13:52:47
SetScrollRange()、SetScrollPos()、GetScrollRange()、GetScrollPos()的代码实现
设置滚动条的滚动范围和初始位置
m_MinHeight = 0;
m_MaxHeight = m_img->height-Sheight;
m_MinWidth  = 0;
m_MaxWidth  = m_img->width - Swidth;//因为nPos其实返回的是顶部的坐标所以要减去一辈控件的高度或宽度
m_ScrollbarCtl.SetScrollRange(m_MinHeight, m_MaxHeight);
m_ScrollbarCtl.SetScrollPos(m_MinHeight);
m_ScrollbarHor.SetScrollRange(m_MinWidth, m_MaxWidth);
m_ScrollbarHor.SetScrollPos(m_MinWidth);
显示图片的函数
void CgunDlg::PicShow()
{   
IplImage* dstImg = cvCreateImage(cvSize(Swidth, Sheight),IPL_DEPTH_8U, 3);
cvSetImageROI(m_img, cvRect(m_pointx, m_pointy, Swidth, Sheight));//
cvCopy(m_img, dstImg);
cvResetImageROI(m_img);
CvvImage cimg;
cimg.CopyOf(dstImg);
cimg.DrawToHDC(hDC, &rect);
}
滚动响应函数声明
void CgunDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
// TODO: Add your message handler code here and/or call default
if (NULL==hDC)
{
MessageBox(_T("请加载图片"));
}
else
{
int iNowPos;

switch (nSBCode)
{
case SB_THUMBTRACK: //拖动滑块
m_ScrollbarCtl.SetScrollPos(nPos);

// 重新加载图片
m_pointy = nPos;
PicShow();

case SB_LINEDOWN: //单击滚动条向下的箭头
iNowPos = m_ScrollbarCtl.GetScrollPos();
iNowPos = iNowPos + 1;
if (iNowPos > m_MaxHeight)
iNowPos = m_MaxHeight;
m_ScrollbarCtl.SetScrollPos(iNowPos);
m_pointy = iNowPos;
// 重新加载图片
PicShow();

break;

case SB_LINEUP: //单击滚动条向上的箭头
iNowPos = m_ScrollbarCtl.GetScrollPos();
iNowPos = iNowPos - 1;
if (iNowPos < m_MinHeight)
iNowPos = m_MinHeight;
m_ScrollbarCtl.SetScrollPos(iNowPos);
m_pointy = iNowPos;
// 重新加载图片
PicShow();

break;
case SB_PAGEDOWN:  //单击箭头与滚块之间的区域
iNowPos = m_ScrollbarCtl.GetScrollPos();
iNowPos = iNowPos + 3;
if (iNowPos > m_MaxHeight)
iNowPos = m_MaxHeight;
m_ScrollbarCtl.SetScrollPos(iNowPos);
m_pointy = iNowPos;
// 重新加载图片
PicShow();

break;
case SB_PAGEUP: //单击箭头与滚块之间的区域
iNowPos = m_ScrollbarCtl.GetScrollPos();
iNowPos = iNowPos - 3;
if (iNowPos < m_MinHeight)
iNowPos = m_MinHeight;
m_ScrollbarCtl.SetScrollPos(iNowPos);
m_pointy = iNowPos;
// 重新加载图片
PicShow();

break;
}
CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
void CgunDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (NULL == hDC)
{
MessageBox(_T("请加载图片"));
}
// TODO:  在此添加消息处理程序代码和/或调用默认值
else
{
int iNowPos;

switch (nSBCode)
{
// if(pScrollBar == &m_Scrollbar){
case SB_THUMBTRACK: //拖动滑块
m_ScrollbarHor.SetScrollPos(nPos);
m_pointx = nPos;
// 重新加载图片
PicShow();

case SB_LINEDOWN: //单击滚动条向下的箭头
iNowPos = m_ScrollbarHor.GetScrollPos();
iNowPos = iNowPos + 1;
if (iNowPos > m_MaxHeight)
iNowPos = m_MaxHeight;
m_ScrollbarHor.SetScrollPos(iNowPos);
m_pointx = iNowPos;
// 重新加载图片
PicShow();

break;

case SB_LINEUP: //单击滚动条向上的箭头
iNowPos = m_ScrollbarHor.GetScrollPos();
iNowPos = iNowPos - 1;
if (iNowPos < m_MinHeight)
iNowPos = m_MinHeight;
m_ScrollbarHor.SetScrollPos(iNowPos);
m_pointx = iNowPos;
// 重新加载图片
PicShow();

break;
case SB_PAGEDOWN:  //单击箭头与滚块之间的区域
iNowPos = m_ScrollbarHor.GetScrollPos();
iNowPos = iNowPos + 3;
if (iNowPos > m_MaxHeight)
iNowPos = m_MaxHeight;
m_ScrollbarHor.SetScrollPos(iNowPos);
m_pointx = iNowPos;
// 重新加载图片
PicShow();

break;
case SB_PAGEUP: //单击箭头与滚块之间的区域
iNowPos = m_ScrollbarHor.GetScrollPos();
iNowPos = iNowPos - 3;
if (iNowPos < m_MinHeight)
iNowPos = m_MinHeight;
m_ScrollbarHor.SetScrollPos(iNowPos);
m_pointx = iNowPos;
// 重新加载图片
PicShow();

break;
//
}
}
CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}

SetScrollInfo()、GetScrollInfo()代码实现
首先要了解以下内容
SCROLLINFO结构
在使用SetScrollInfo()与GetScrollInfo()之前需要设置SCROLLINFO结构变量(如,si),SCROLLINFO结构定义如下,
typedef struct tagSCROLLINFO
{
 UINT cbSize;
 UINT fMask;
 int nMin;
 int nMax;
 UINT nPage;
 int nPos;
 int nTrackPos;
} SCROLLINFO, FAR *LPSCROLLINFO;
参数含义如下:

cbSize为该结构变量的大小,这样设计可以使在以后的扩展时更加方便且能兼容以前版本。
fMask的值影响SetScrollInfo()与GetScrollInfo()函数调用时影响的SCROLLINFO结构的具体变量值。取值如下,
SIF_RANGE——nMin和nMax将为滚动条的范围的最小值和最大值;
SIF_PAGE——nPage将为滚动条大小的值;
SIF_POS——nPos将为滚动条位置的值;
SIF_DISABLENOSCROLL——只在SetScrollInfo()使用,当设置的值使用滚动条无效时,使滚动条无效,而不是移除滚动条;
SIF_TRACKPOS——当拖动滚动条时,nTrackPos将为滚动条当前位置的值;
SIF_ALL——SIF_RANGE | SIF_PAGE | SIF_POS | SIF_TRACKPOS。
nMin为滚动范围最小值。
nMax为滚动范围的最大值。
nPage为滚动条的大小。
nPos为滚动条的位置。
nTrackPos为拖动滚动条时,滚动条的位置。
初始化
SCROLLINFO ver;
//设置垂向的滚动条
ZeroMemory(&ver, sizeof(ver));//0填充的地址和大小
ver.cbSize = sizeof(ver);
ver.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
ver.nMax = m_MaxHeight;
ver.nMin = 0;
ver.nPage = (m_MaxHeight+Sheight) / 100;
ver.nPos = 0;
m_ScrollbarCtl.SetScrollInfo(&ver);
//设置水平的滚动条
ZeroMemory(&ver, sizeof(ver));//0填充的地址和大小
ver.cbSize = sizeof(ver);
ver.fMask = SIF_RANGE | SIF_PAGE | SIF_POS;
ver.nMax = m_MaxWidth;
ver.nMin = 0;
ver.nPage = (m_MaxWidth+Swidth) / 100;
ver.nPos = 0;
m_ScrollbarHor.SetScrollInfo(&ver);
PicShow();
}

显示函数不变
滚动响应函数
void CgunDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
// TODO:  在此添加消息处理程序代码和/或调用默认值
// TODO: Add your message handler code here and/or call default
if (NULL==hDC)
{
MessageBox(_T("请加载图片"));
}
else
{
int iNowPos;

switch (nSBCode)
{
SCROLLINFO ver;
case SB_THUMBTRACK: //拖动滑块
//m_ScrollbarCtl.SetScrollPos(nPos);
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
ver.fMask = SIF_POS;
ver.nPos = nPos;
m_ScrollbarCtl.SetScrollInfo(&ver);
// 重新加载图片
m_pointy = nPos;
PicShow();

case SB_LINEDOWN: //单击滚动条向下的箭头
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
m_ScrollbarCtl.GetScrollInfo(&ver, SIF_POS);
iNowPos = ver.nPos;
iNowPos = iNowPos + 1;
if (iNowPos > m_MaxHeight)
iNowPos = m_MaxHeight;
m_ScrollbarCtl.SetScrollPos(iNowPos);
m_pointy = iNowPos;
// 重新加载图片
PicShow();

break;

case SB_LINEUP: //单击滚动条向上的箭头
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
m_ScrollbarCtl.GetScrollInfo(&ver, SIF_POS);
iNowPos = ver.nPos;
iNowPos = iNowPos - 1;
if (iNowPos < m_MinHeight)
iNowPos = m_MinHeight;
m_ScrollbarCtl.SetScrollPos(iNowPos);
m_pointy = iNowPos;
// 重新加载图片
PicShow();

break;
case SB_PAGEDOWN:  //单击箭头与滚块之间的区域
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
m_ScrollbarCtl.GetScrollInfo(&ver, SIF_POS);
iNowPos = ver.nPos;
iNowPos = iNowPos + 3;
if (iNowPos > m_MaxHeight)
iNowPos = m_MaxHeight;
m_ScrollbarCtl.SetScrollPos(iNowPos);
m_pointy = iNowPos;
// 重新加载图片
PicShow();

break;
case SB_PAGEUP: //单击箭头与滚块之间的区域
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
m_ScrollbarCtl.GetScrollInfo(&ver, SIF_POS);
iNowPos = ver.nPos;
iNowPos = iNowPos - 3;
if (iNowPos < m_MinHeight)
iNowPos = m_MinHeight;
m_ScrollbarCtl.SetScrollPos(iNowPos);
m_pointy = iNowPos;
// 重新加载图片
PicShow();

break;
}
CDialogEx::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CgunDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
if (NULL == hDC)
{
MessageBox(_T("请加载图片"));
}
// TODO:  在此添加消息处理程序代码和/或调用默认值
else
{
int iNowPos;

switch (nSBCode)
{
SCROLLINFO ver;
case SB_THUMBTRACK: //拖动滑块
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
ver.fMask = SIF_POS;
ver.nPos = nPos;
m_ScrollbarHor.SetScrollInfo(&ver);
m_pointx = nPos;
// 重新加载图片
PicShow();

case SB_LINEDOWN: //单击滚动条向下的箭头
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
m_ScrollbarHor.GetScrollInfo(&ver, SIF_POS);
iNowPos = ver.nPos;
iNowPos = iNowPos + 1;
if (iNowPos > m_MaxHeight)
iNowPos = m_MaxHeight;
m_ScrollbarHor.SetScrollPos(iNowPos);
m_pointx = iNowPos;
// 重新加载图片
PicShow();

break;

case SB_LINEUP: //单击滚动条向上的箭头
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
m_ScrollbarHor.GetScrollInfo(&ver, SIF_POS);
iNowPos = ver.nPos;
iNowPos = iNowPos - 1;
if (iNowPos < m_MinHeight)
iNowPos = m_MinHeight;
m_ScrollbarHor.SetScrollPos(iNowPos);
m_pointx = iNowPos;
// 重新加载图片
PicShow();

break;
case SB_PAGEDOWN:  //单击箭头与滚块之间的区域
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
m_ScrollbarHor.GetScrollInfo(&ver, SIF_POS);
iNowPos = ver.nPos;
iNowPos = iNowPos + 3;
if (iNowPos > m_MaxHeight)
iNowPos = m_MaxHeight;
m_ScrollbarHor.SetScrollPos(iNowPos);
m_pointx = iNowPos;
// 重新加载图片
PicShow();

break;
case SB_PAGEUP: //单击箭头与滚块之间的区域
ZeroMemory(&ver, sizeof(ver));
ver.cbSize = sizeof(ver);
m_ScrollbarHor.GetScrollInfo(&ver, SIF_POS);
iNowPos = ver.nPos;
iNowPos = iNowPos - 3;
if (iNowPos < m_MinHeight)
iNowPos = m_MinHeight;
m_ScrollbarHor.SetScrollPos(iNowPos);
m_pointx = iNowPos;
// 重新加载图片
PicShow();

break;
//
}
}
CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}

区别:
OnHScroll和OnVScroll只提供16位的位置数据。GetScrollInfo和SetScrollInfo提供32位的滚动条位置数据。因此,一个应用程序在处理GetScrollInfo或SetScrollInfo时,可以调用GetScrollInfo来获取32位的滚动条位置数据。
用GetScrollInfo支持长整数,弃用GetScrollPos,这是MSDN中对32程序的建议,所以尽量运用后者。否则当你显示超大图片时就会遇到错误
关于源代码我已经上传CSDN
下载地址:
方法1:http://download.csdn.net/detail/vivid_song/9276615
方法2:http://download.csdn.net/detail/vivid_song/9279507
 ​

SCROLLINFO结构的使用

在窗口程序中添加滚动条很容易,只要在CreateWindow中将WS(window style)添加WS_VSCROLL与WS_HSCROLL即可,然后再调用相应的函数就可以使用了。 滚动条有范围和位...
  • Augusdi
  • Augusdi
  • 2013年03月14日 12:27
  • 5841

CWnd::SetScrollInfo

函数功能:该函数设置滚动条参数,包括滚动位置的最大值和最小值,页面大小,滚动按钮的位置。如被请求,函数也可以重画滚动条。  函数原型:int SetScrollInfo(HWND hWnd;int f...
  • dragoo1
  • dragoo1
  • 2017年01月17日 21:31
  • 294

滚动条 实现的细节代码 SCROLLINFO

今天分析了以前的一段自绘 滚动条的代码, 终于明白了滚动条的细节。  对于Edit 来说 SCROLLINFO si1; si1.nMin:0, si1.nMax:14, si1.nPage:6, s...
  • abcpanpeng
  • abcpanpeng
  • 2011年01月15日 22:11
  • 4531

SCROLLINFO结构的使用

SCROLLINFO结构的使用
  • xuxiaofei77
  • xuxiaofei77
  • 2010年07月29日 09:45
  • 757

SCROLLINFO结构详解

在刚开始使用SCROLLINFO结构时感觉很不顺手,尤其其中的成员fMask理解不太深刻,经过查询资料才理解一二。     在使用滚动条功能时,如果要设置它的范围和位置可以用以前的函数,例...
  • cqyczj
  • cqyczj
  • 2014年04月24日 07:14
  • 378

滚动条 实现的细节代码 SCROLLINFO

今天分析了以前的一段自绘 滚动条的代码, 终于明白了滚动条的细节。 对于Edit 来说 SCROLLINFO si1; si1.nMin:0, si1.nMax:14...
  • Blue_Dream_
  • Blue_Dream_
  • 2010年06月01日 13:11
  • 2410

解决VC滚动条16位限制 tag: 滚动条, OnVScroll, 16位, 32位,SB_THUMBTRACK, SCROLLINFO , nTrackPos

被这东西困扰了半天,郁闷;特留下记录,希望能帮你在这上面少浪费时间。   OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar){   ...
  • casablinca
  • casablinca
  • 2008年08月25日 15:46
  • 1540

GetScrollInfo

函数功能:该函数找到滚动条的参数,包括滚动条位置的最小值、最大值,页面大小,滚动按钮的位置, 函数原型:BOOL GetScrolllnfo(HWND hWnd,int fnBar,LPSCROLLI...
  • cdlff
  • cdlff
  • 2008年11月22日 17:16
  • 1204

滚动条范围位置函数(SetScrollRange、SetScrollPos、GetScrollRange、GetScrollPos)

滚动条的范围是一对整数,默认情况下,滚动条的范围是0~100。 SetScrollRange(hwnd,iBar,iMin,iMax,bRedraw)这里的iBar参数要么是SB_VERT,要么是S...
  • ghevinn
  • ghevinn
  • 2014年07月02日 10:22
  • 8385

SetScrollRange

函数功能:该函数设置所指定滚动条位置的最大最小值。  函数原型:BOOL SetScrollRange(HWND hWnd,int nBar,int nMinPos,int nMaxPos,BOOL ...
  • cdlff
  • cdlff
  • 2008年11月22日 18:11
  • 762
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:VC/MFC加滚动条显示大图片SetScrollRange()、SetScrollInfo()两种思路实现及其两者优劣比较
举报原因:
原因补充:

(最多只允许输入30个字)