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

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
VC/MFC加滚动条显示大图片SetScrollRange()、SetScrollInfo()两种思路实现及其两者优劣比较_第1张图片 ​

你可能感兴趣的:(VC++,MFC)