WM系统滚动条设定
来源:互联网 发布:oracle数据库集群方案 编辑:程序博客网 时间:2024/05/29 17:28
WM滚动条的操作原理,要创建一个带滚动条的窗口,使用createwindow创建时带入WS_VSCROLL和WS_HSCROLLod类型就能创建一个带滚动条的窗口,然后在程序中调用SetScrollInfo,配置滚动条。滚动条操作分三部:范围刷新,消息体响应,重绘界面
范围刷新:在这里填充SCROLLINFO结构,建立一系列界面与滚动条尺寸范围的对应关系
下面要填充一个scrollinfo结构,代码显示的是对纵向滚动条定位数据的填充:
//尺寸
SCROLLINFO sbi = {sizeof(SCROLLINFO)};
//客户区域
RECT rcClient;
GetClientRect(hWnd, &rcClient);
//窗口类型,需要根据窗口类型设定客户区域,因为如果纵横携有滚动条的话,需要把滚动条所占的区域从客户区域去掉,才是真正的客户显示区
DWORD dwStyle = GetWindowLong(hWnd, GWL_STYLE);
rcClient.right -= (dwStyle | WS_HSCROLL) ? 0 : GetSystemMetrics(SM_CXVSCROLL);
rcClient.bottom -= (dwStyle | WS_VSCROLL) ? 0 : GetSystemMetrics(SM_CYHSCROLL);
//计算超出,就是在显示区外的尺寸。(计算超出提供给手势操作使用)
g_nMaxXExtent = g_nBmpWidth - rcClient.right;
g_nMaxYExtent = g_nBmpHeight - rcClient.bottom;
//这是滑块的位置点,位置点和段量是有关系的,段量是10,后面就是10,20,30…
g_nXPos = 0;
g_nYPos = 0;
//info的标志位,SIF_DISABLENOSCROLL表示当界面不需要滚动时,滚动条还在界面上,设为灰化状态,如果不设这段标志,将把滚动条移掉
sbi.fMask= SIF_ALL | SIF_DISABLENOSCROLL;
//最小段位,段位表示这是一个分段,这里设的段为量是1,起始每个值都要除以段量,段量表示的是一次移动的位移。如果移动一次走一个Item的话,段量就是Item的高
sbi.nMin = 0;
//最大分段数量,总尺寸(包括显示和没显示的部分)
sbi.nMax = g_nBmpHeight - 1;
//显示区域的分段数量,与最大段位一样,但只算显示区域的分段
sbi.nPage = rcClient.bottom;
//滑块所在的段位
sbi.nPos = 0;
//滑块前一次所在的段位
sbi.nTrackPos =0;
SetScrollInfo(hWnd, SB_VERT, &sbi, FALSE);
至此一段滚动的数据信息就传入了滚动条。滚动条会依此刷新状态,这一部的操作不用我们实现,系统会自动更形滚动条。下面就要操作滚动消息体WM_VSCROLL或WMHSCROLL,消息响应参数中,wParam代表对滚动条的操作,比如点向下箭头,向上箭头。响应这些动作并设定响应值.根据响应值刷新屏幕
//根据纵横判断取出自增量(段量)
int increment = (WM_VSCROLL==message) ? g_nVertItemSize : g_nHorizItemSize;
//纵横判断
int nBar = (WM_VSCROLL==message) ? SB_VERT:SB_HORZ;
//滑块起始位置
int * pnVal = (WM_VSCROLL==message) ? &g_nYPos:&g_nXPos;
//起始段位,根据动作操作这个值完成滚动
int nVal = (*pnVal)/increment;
//最大段数量
int nMax = 0;
int nDelta = 0;
SCROLLINFO sbi = {sizeof(SCROLLINFO)};
sbi.fMask = SIF_ALL;
GetScrollInfo(hWnd, nBar, &sbi);
int pos = sbi.nPos;
//计算显示外的段量
nMax = sbi.nMax - (sbi.nPage -1);
switch (LOWORD(wParam))
{
//到最下
case SB_BOTTOM:
nVal = nMax;
break;
//点向下按钮
case SB_LINEDOWN:
nVal = pos + 1;
break;
//点向上按钮
case SB_LINEUP:
nVal = pos - 1;
break;
//点在滑块下的滚动空白区
case SB_PAGEDOWN:
nVal = pos + 5;
break;
//点在滑块上的滚动空白区
case SB_PAGEUP:
nVal = pos - 5;
break;
//到最上
case SB_TOP:
nVal = 0;
break;
//在滑块上拖
case SB_THUMBTRACK:
nVal = sbi.nTrackPos;
break;
//直接定位
case SB_THUMBPOSITION:
//滚动结束
case SB_ENDSCROLL:
default:
break;
}
//新的滑块段位,这里有个最小和最大值保护
nVal = max(nVal, 0);
nVal = min(nVal, nMax);
//差值量
nDelta = *pnVal;
*pnVal = nVal * increment;
nDelta -= *pnVal;
//如果与原位有空间就开始执行滚动
if (nVal != pos)
{
RECT rcClient;
//刷新滑块位置
SetScrollPos(hWnd, nBar, nVal, TRUE);
GetClientRect(hWnd, &rcClient);
//判断一下纵横,区别取值
int dx = (WM_VSCROLL==message) ? 0 : nDelta;
int dy = (WM_VSCROLL==message) ? nDelta : 0;
//移动窗口位置,可以不用移动窗口位置,而只通过更新界面元素调整显示
ScrollWindowEx(hWnd, dx, dy, &rcClient, &rcClient, NULL, NULL, SW_INVALIDATE);
//更新窗口元素
UpdateWindow(hWnd);
}
最终界面实现移动,同时还需要根据窗口位置重绘图形,重绘图形的操作是在OnPaint中响应实现的:
PAINTSTRUCT ps;
HDC hdc;
hdc = BeginPaint(hWnd, &ps);
CRect rcClient;
GetClientRect(hWnd, &rcClient);
//FillRect(hdc,&rcClient,(HBRUSH)GetStockObject(WHITE_BRUSH));
//------------------------------使用位图操作的传统方式---------------------------
// 依据滚动位置调整贴图
BitBlt( ps.hdc,
ps.rcPaint.left,
ps.rcPaint.top,
ps.rcPaint.right - ps.rcPaint.left,
ps.rcPaint.bottom - ps.rcPaint.top,
g_hMemDC,
g_nXPos + ps.rcPaint.left,
g_nYPos + ps.rcPaint.top,
SRCCOPY);
EndPaint(hWnd, &ps);
- WM系统滚动条设定
- 如何设定浏览器滚动条的颜色
- 设定最外层滚动条的位置
- .Net中的AutoScrollPosition问题 (panel 滚动条的位置设定)
- 滚动条样式的设定(ipad也好用)
- 设定html table 过宽下方出现滚动条
- 系统滚动条类TileList举例说明
- Ubuntu修改系统滚动条的方法
- [转].Net中的AutoScrollPosition问题 (panel 滚动条的位置设定)
- [转].Net中的AutoScrollPosition问题 (panel 滚动条的位置设定)
- div 固定高度,设定比例的宽度,超出指定高度时竖直滚动条出现
- css 中div不用设定高度,自动根据内容出现滚动条
- 滚动条
- 滚动条
- 滚动条
- 滚动条
- 滚动条
- 滚动条
- 通过IP查询机器名
- PostgreSQL与MySQL两大开源数据库论高下
- 事务隔离级别
- 使用母版页面后获取Form表单提交值
- shell 关于 while 循环中赋值的问题
- WM系统滚动条设定
- 你选狮子还是选狼
- 函数指针
- vs2008“无法在web服务器上启动调试”解决方法
- 重组datatable填充datasource
- JAVA与足球队的相似点
- Bootloader Startup.s 学习笔记一
- 结合jquery插件实现头像裁剪
- fedora 12 yum config