VC对话框实现添加滚动条实现滚动效果
对话框滚动条及滚动效果实现,用的api主要有: ScrollWindow, SetScrollInfo, GetScrollInfo, SetWindowOrgEx。涉及的数据结构为SCROLLINFO。
实现的原理为:设置窗口显示的滚动条;响应滚动条的消息,在其中记录窗口原点的x和y坐标,并滚动窗口;在OnPaint中设置窗口原点,并绘图。
SCROLLINFO
typedef struct tagSCROLLINFO
{
UINT cbSize;
UINT fMask;
int nMin;
int nMax;
UINT nPage;
int nPos;
int nTrackPos;
} SCROLLINFO, FAR *LPSCROLLINFO;
cbSize: SCROLLINFO结构长度字节数,该值在设置和查询参数时都必须填写。
fMask: 指定结构中的哪些成员是有效,该值共有如下5种选择,可以选择多种用“OR”组合起来,该值在设置和查询参数时都必须填写。
SIF_ALL : 整个结构都有效
SIF_DISABLENOSCROLL : 该值仅在设定参数时使用,视控件参数设定的需要来对本结构的成员进行取舍。
SIF_PAGE : nPage成员有效
SIF_POS : nPos成员有效
SIF_RANGE : nMin和nMax成员有效
nMin: 滚动范围最小值
nMax: 滚动范围最大值
nPage: 页尺寸,用来确定比例滚动框的大小,一般设置为窗口在宽或高,分别对应用于横向滚动条和竖向滚动条
nPos: 滚动框的位置
nTrackPos: 拖动时滚动框的位置,该参数只能查询,不能设置。
API 及其参数解释
BOOL SetWindowOrgEx(HDC hdc, int X, int Y, LPPOINT lpPoint);
该函数用指定的坐标设置设备环境的窗口原点。
hdc:指向设备环境的句柄。
X:指定新窗口原点的逻辑X坐标。
Y:指定新窗口原点的逻辑Y坐标。
lpPoint:指向POINT结构的指针,先前的窗口原点存放在此结构中,如果lpPoint的值为NULL,则什么也没返回。
返回值:如果函数调用成功,返回值为非零值,否则为零。
void ScrollWindow(int xAmount, int yAmount, LPCRECT lpRect = NULL, LPCRECT lpClipRect = NULL);
XAmount: [in]指定水平滚动的距离,以设备单位计。如果窗口类风格为CS_OWNDC或CS_CLASSDC,则此参数则使用逻辑单位而非设备单位。当向左滚动窗体内容时,参数值必须为负。
YAmount: [in]指定垂直滚动的距离,以设备单位计。如果窗口类风格为CS_OWNDC或CS_CLASSDC,则此参数则使用逻辑单位而非设备单位。当向上滚动窗体内容时,参数值必须为负。
lpRect: [in]指向RECT结构的指针,该结构指定了将要滚动的客户区范围。若此参数为NULL,则整个客户区域将被滚动。
lpClipRect: [in]指向RECT结构的指针,该结构指定了要滚动的裁剪区域。只有这个矩形中的位才会被滚动。在矩形之外的位不会被影响,即使它们是在lpRect矩形之内。假如lpClipRect为NULL,则不会在滚动矩形上进行裁剪。
BOOL SetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE);
fnBar:指定被设定参数的滚动条的类型。这个参数可以是下面值,含义如下:
SB_CTL:设置滚动条控件。而参数hwnd必须是滚动条控件的句柄。
SB_HORZ:设置所给定的窗体上标准水平滚动条参数。
SB_VERT:设置所给定的窗体上标准垂直滚动条参数。
lpsi:指向SCROLLINFO结构。在调用SetScrollInfo之前,设置SCROLLINFO结构中cbSize成员以标识结构大小,设置成员fMask以说明待设置的滚动条参数,并且在适当的成员中制定新的参数值。成员fMask可以为下面所列复合值,含义如下:
SIF_DISABLENOSCROLL:如果滚动条的新参数使其为没必要,则使滚动条无效而不再移动它。
SIF_PAGE:设置滚动页码值到由Ipsi指向的SCROLLINFO结构的nPage成员中。
SIF_POS:设置滚动位置值到由lpsi指向的SCROLLINFO结构的nPos成员中。
SIF_RANGE:设置滚动范围值到由lpsl指向的SCROLLINFO结构的nMin和nMax成员中。
fRedraw:指定滚动条是否重画以反映滚动条的变化。如果这个参数为TRUE,滚动条将被重画,否则不被重画。
BOOL GetScrollInfo(int nBar, LPSCROLLINFO lpScrollInfo, UINT nMask = SIF_ALL);
读取滚动条的信息,数据从lpScrollInfo中返回。各参数意义同SetScrollInfo
实例
1.在初始化等需要添加滚动条时,使用下面的代码添加滚动条。注意:不限于初始化,程序需要时都可以重新设置
// 给对话框添加滚动条 SB_VERT:垂直方向,SB_HORZ:水平方向
SCROLLINFO si;
si.cbSize = sizeof(SCROLLINFO);
si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE;
si.nPos = ;
si.nMin = ;
si.nMax = rc.Height() * ;
si.nPage = rc.Height();
SetScrollInfo(SB_VERT, &si, FALSE);
si.nMax = rc.Width() * ;
si.nPage = rc.Width();
SetScrollInfo(SB_HORZ, &si, FALSE);
2.响应WM_VSCROLL 和 WM_HSCROLL 消息,在消息响应函数中滚动窗口,并记录需要显示的窗口原点。
ON_WM_VSCROLL()
ON_WM_HSCROLL()
void CPrintDlgAppDlg::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
SCROLLINFO si = {sizeof(si)};
si.fMask = SIF_ALL;
GetScrollInfo(SB_VERT, &si); int nPrevPos = si.nPos;
switch(nSBCode)
{
case SB_TOP:
si.nPos = si.nMin;
break;
case SB_BOTTOM:
si.nPos = si.nMax;
break;
case SB_LINEUP:
si.nPos -= ;
break;
case SB_LINEDOWN:
si.nPos += ;
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;
}
si.fMask = SIF_POS;
SetScrollInfo(SB_VERT, &si, TRUE);
if (si.nPos != nPrevPos)
{
m_nYPos += si.nPos - nPrevPos;
ScrollWindow(, nPrevPos - si.nPos, NULL, NULL);
Invalidate(FALSE);
UpdateWindow();
} CDialog::OnVScroll(nSBCode, nPrevPos, pScrollBar);
} void CPrintDlgAppDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
SCROLLINFO si = {sizeof(si)};
si.fMask = SIF_ALL;
GetScrollInfo(SB_HORZ, &si); int nPrevPos = si.nPos;
switch(nSBCode)
{
case SB_LEFT:
si.nPos = si.nMin;
break;
case SB_RIGHT:
si.nPos = si.nMax;
break;
case SB_LINELEFT:
si.nPos -= ;
break;
case SB_LINERIGHT:
si.nPos += ;
break;
case SB_PAGELEFT:
si.nPos -= si.nPage;
break;
case SB_PAGERIGHT:
si.nPos += si.nPage;
break;
case SB_THUMBTRACK:
si.nPos = si.nTrackPos;
break;
default:
break;
}
si.fMask = SIF_POS;
SetScrollInfo(SB_HORZ, &si, TRUE);
if (si.nPos != nPrevPos)
{
m_nXPos += si.nPos - nPrevPos;
ScrollWindow(nPrevPos - si.nPos, , NULL, NULL);
Invalidate(FALSE);
UpdateWindow();
} CDialog::OnHScroll(nSBCode, nPrevPos, pScrollBar);
}
3.在OnPaint消息中,设置窗口原点并绘图。需要注意的时,为了避免滚动时图形叠加,需要创建一块内存DC,其大小应为窗口滚动区域的大小。
void CPrintDlgAppDlg::OnPaint()
{
CPaintDC dc(this); // device context for painting // 用指定的坐标设置设备环境的窗口原点
SetWindowOrgEx(dc.m_hDC, m_nXPos, m_nYPos, NULL); // 创建一块和窗口滑动区域一样大的内存DC,这样才不会出现窗口图形叠加的问题
CRect rc(, , , );
SCROLLINFO si = {sizeof(SCROLLINFO)};
si.fMask = SIF_RANGE;
GetScrollInfo(SB_VERT, &si);
rc.bottom = si.nMax;
GetScrollInfo(SB_HORZ, &si);
rc.right = si.nMax; CDC memDC;
memDC.CreateCompatibleDC(&dc);
CBitmap memBitmap;
memBitmap.CreateCompatibleBitmap(&dc, rc.Width(), rc.Height());
CBitmap* pOldBmp = memDC.SelectObject(&memBitmap);
memDC.FillSolidRect(&rc, RGB(, , ));
CFont font;
font.CreateFont(, , , , FW_NORMAL, FALSE, FALSE, , ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
DEFAULT_PITCH | FF_SWISS, _T("Arial"));
memDC.SetBkMode(TRANSPARENT);
memDC.SetTextColor(RGB(, , ));
CFont* pOldFont = memDC.SelectObject(&font);
int nH = ;
CRect rcText(, rc.top, rc.right, rc.top + nH);
CString str;
CTime time;
for (int i = ; i < ; i++)
{
::OffsetRect(&rcText, , nH);
if (rcText.bottom > rc.bottom)
{
break;
}
time = CTime::GetCurrentTime();
str.Format(_T("当前行:[%d] "), i);
str += time.Format(_T("%Y年%m%d日 %H时%M分%S秒 <%c>"));
str += _T(" -------------------- ");
str += str;
str += str;
memDC.DrawText(str, rcText, DT_LEFT);
} dc.BitBlt(, , rc.Width(), rc.Height(), &memDC, , , SRCCOPY); memDC.SelectObject(pOldFont);
memDC.SelectObject(pOldBmp);
memDC.DeleteDC();
memBitmap.DeleteObject();
}
VC对话框实现添加滚动条实现滚动效果的更多相关文章
- swiper添加了自动滚动效果,然后用手指划过页面,发现自动滚动效果不生效了
我给swiper添加了自动滚动效果,然后用手指划过页面,发现自动滚动效果不生效了,哪里出了问题呢? 添加参数 autoplayDisableOnInteraction : false,
- VC++对话框中添加状态栏的方法
方法一:1.添加成员变量CStatusBarCtrl m_StatusBar;2.在OnInitDialog()中加入: m_StatusBar.Create(WS_ ...
- css 给div 添加滚动条样式hover 效果
css .nui-scroll { margin-left: 100px; border: 1px solid #000; width: 200px; height: 100px; ...
- VC对话框使用OnEraseBkgnd函数位图背景并透明
1.使用OnEraseBkgnd函数实现对话框位图背景 BOOL CDisplayBmpBackGroundDlg::OnEraseBkgnd(CDC *pDC) { CRect rect; GetC ...
- jquery控制div随滚动条滚动效果
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>jquery div随滚动条 ...
- 纯css解决div隐藏浏览器原生滚动条,但保留鼠标滚动效果的问题
当我们的内容超出了我们的div,往往会出现滚动条,影响美观.尤其是当我们在做一些导航菜单的时候.滚动条一出现就破坏了UI效果. 我们不希望出现滚动条,也不希望超出去的内容被放逐,就要保留鼠标滚动的效 ...
- 纯css,div隐藏滚动条,保留鼠标滚动效果。
示例1: html,body { height: 100%; } body { overflow: hidden; } .full-screen { position: relative; width ...
- 为div添加滚动效果:
为div添加滚动效果: .xxxx{ width: 100%; height: 100%; overflow: hidden; overflow-y: auto;} 代码片段 <div clas ...
- CSS隐藏overflow默认滚动条同时保留滚动效果
主要应用于移动端场景,仿移动端滚动效果.对于隐藏滚动条,众所周知overflow:hidden,但是想要的滚动效果也没了. 所以对于移动端webkit内核提供一个伪类选择器: .element::-w ...
随机推荐
- js for循环实例
1.求1-100的寄数和? //2.奇数求和 var ppt=0 for(var i=1;i<=100;i+=2){ ppt+=i } 2.求1-100的偶数和 var num=0 for(va ...
- Paper Reading - Show, Attend and Tell: Neural Image Caption Generation with Visual Attention ( ICML 2015 )
Link of the Paper: https://arxiv.org/pdf/1502.03044.pdf Main Points: Encoder-Decoder Framework: Enco ...
- SpringCloud IDEA 教学 (一) Eureka的简介与服务注册中心的建立
写在开头 SpringCloud进来成为业界排名靠前的微服务框架,最核心功能就是搭建微服务,并在此基础上衍生出一系列功能,如断路器(Hystrix).断路监控.管理配置.Zuul.OAuth2等功能. ...
- Codeforces 96D Volleyball(最短路径)
Petya loves volleyball very much. One day he was running late for a volleyball match. Petya hasn't b ...
- 福大软工1816:Alpha(7/10)
Alpha 冲刺 (7/10) 队名:Jarvis For Chat 组长博客链接 本次作业链接 团队部分 团队燃尽图 工作情况汇报 张扬(组长) 过去两天完成了哪些任务: 文字/口头描述: 1.完成 ...
- catalan卡塔兰数
令h(0)=1,h(1)=1,卡塔兰数数满足递归式:h(n)= h(0)*h(n-1) + h(1)*h(n-2) + ... + h(n-1)h(0) (其中n>=2),这是n阶递推关系;还可 ...
- lintcode-170-旋转链表
170-旋转链表 给定一个链表,旋转链表,使得每个节点向右移动k个位置,其中k是一个非负数 样例 给出链表1->2->3->4->5->null和k=2 返回4-> ...
- C# .net 获取外网ip
public string GetIP() { string strUrl = "http://www.ip138.com/ip2city.asp"; //获得IP的网址了 Uri ...
- centos升级python(从2.6.6升级到2.7.8)
***先安装readline,否则升级后python回退和方向键不能使用 yum install readline-devel.x86_64 1.#wget www.python.org/ftp/ ...
- 数据存储到MySQL并返回新插入的id值
当对数据库进行插入数据后,有时会需要刚插入的数据的id值,以作他用,整理如下: conn = pymysql.connect(, user=DB_USER, passwd=DB_PASSWORD, d ...