特殊说明:版权归个人所有,请勿转载,谢谢合作。
在使用Windows应用软件时,跨页时会在右侧或下侧出现一个条形状的控件,此控件为滚动条控件。滚动条控件分为垂直滚动条和水平滚动条两种,主要用于上下翻页与左右调整工作区,通过鼠标滚轮与键盘进行控制。滚动条也可以用来显示某个任务的进度,这样滚动条又被称作进度条。
// 创建列表框
g_hScrollBarWnd = CreateWindow("scrollbar", NULL,
WS_CHILD | WS_VISIBLE | SBS_HORZ,
10, 10, 200, 30, hWnd, (HMENU)ID_SCROLL_BAR, g_hIns, NULL);
创建滚动条时,需要指定滚动条的风格,具体风格的取值如表10.9所示。
- 表10.9 滚动条控件风格
| 风格 | 描述 |
| SBS_BOTTOMALIGN | 水平滚动条,滚动条在窗口的底侧 |
| SBS_HORZ | 水平滚动条,滚动条在窗口的右侧 |
| SBS_LEFTALIGN | 靠左对齐的垂直滚动条 |
| SBS_RGHTALIGN | 靠右对齐的垂直滚动条 |
| SBS_SIZEBOX | 对话框式的滚动条 |
| SBS_TOPALIGN | 适用于水平滚动条,顶端与指定的矩形对齐 |
| SBS_VERT | 创建垂直滚动条 |
滚动条创建完成,可以使用SendMessage函数发送相应的控制消息,也可以在过程处理函数中捕获滚动条的消息。滚动条控件响应的消息类型如表10.10所示。
- 表10.10 滚动条控件消息类型
| 消息 | 描述 |
| SBM_ENABLE ARROWS | 激活或者取消滚动条的滚动 |
| SBM_GETPOS | 获得当前滚动条滚动按钮的位置 |
| SBM_GETRANGE | 获得当前滚动条设置的范围 |
| SBM_GETSCROLLINFO | 获得滚动条的相关信息(位置、大小等) |
| SBM_SETPOS | 设置滚动条滚动按钮的位置 |
| SBM_SETRANGE | 设置移动范围 |
| SBM_SETRANGEREDRAW | 当需要重绘滚动条时发送设置最大和最小值位置的消息 |
| SBM_SETSCROLLINFO | 设置滚动条属性 |
| WM_CTLCOLORSCROLLBAR | 当滚动条改变时,向父窗口发送设置背景颜色的消息 |
| WM_HSCROLL | 水平滚动条变化 |
| WM_VSCROLL | 垂直滚动条变化 |
除了知道滚动条消息类型之外,还需要了解滚动条的通知消息码,即点击滚动条时,如何对滚动位置响应的,响应的内容存放在wParam低位字节,可以使用“LOWORD(wParam)”方法来获得。如表10.11所示。
- 表10.11 滚动条通知消息码
| 消息 | 描述 |
| SB_BOTTOM/SB_RIGHT | 滚动到底端/右端(二者消息码相同,可混用) |
| SB_TOP/SB_LEFT | 滚动到顶端/左端(二者消息码相同,可混用) |
| SB_LINEDOWN/SB_LINERIGHT | 向下/向右滚动一行/列(二者消息码相同,可混用) |
| SB_LINEUP/SB_LINELEFT | 向上/向左滚动一行/列(二者消息码相同,可混用) |
| SB_PAGEDOWN/SB_PAGERIGHT | 向下/向右滚动一页(二者消息码相同,可混用) |
| SB_PAGEUP/SB_PAGELEFT | 向上/向左滚动一页(二者消息码相同,可混用) |
| SB_THUMBPOSITION | 滚动到指定位置 |
| SB_THUMBTRACK | 滚动框被拖动 |
| SB_ENDSCROLL | 滚动结束 |
滚动条的操作需要一些常用API的支持,下面简单地介绍了这些API的作用。
BOOL SetScrollRange(HWND hWnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw);
作用:设置所指定滚动条范围的最小值和最大值。
BOOL GetScrollRange( HWND hWnd, int nBar, LPINT lpMinPos, LPINT lpMaxPos );
作用:获取指定滚动条中滚动按钮位置的当前最小值和最大值。
int SetScrollPos(HWND hWnd, int nBar, int nPos, BOOL bRedraw);
作用:设置所指定滚动条中的滚动按钮的位置,如果需要,可重绘滚动条以反映出滚动按钮的新位置。
int GetScrollPos(HWND hWnd, int nBar);
作用:获取指定滚动条中滚动按钮的当前位置。当前位置是一个根据当前滚动范围而定的相对值。例如,如果滚动范围是0到100之间,滚动按钮在中间位置,则其当前位置为50。
int SetScrollInfo(HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw);
作用:设置滚动条参数,包括滚动位置的最大值和最小值,页面大小,滚动按钮的位置。如被请求,函数也可以重画滚动条。
BOOL EnableScrollBar(HWND hWnd, UINT wSBflags, UINT wArrows);
作用:该函数可以激活一个或两个滚动条箭头或是使其失效。
BOOL ShowScrollBar(HWND hWnd, int wBar, BOOL bShow);
作用:该函数显示或隐藏所指定的滚动条。
【例10-6】实现了一个简单的滚动条,通过滚动条的操作,在静态控件内显示当前滚动条的位置值信息。
//**************************************************************
// NAME : Demo_10
//**************************************************************
// POWER : Copyright (c) 2012 for lixinghua.
// AUTHOR : 2012-8-7 8:47 Create by lixinghua for functions.
// VERSION : V1.0.0.1
// NOTE : 手工整理的创建窗口的代码,本程序只创建一个名称为
// MyWin的窗口。
//**************************************************************
//
#include <windows.h>
#include <stdio.h>
// 宏定义,分别定义按钮的ID
#define ID_SCROLL_BAR 0x01
// 回调函数,用于系统消息的处理。
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
HINSTANCE g_hIns = NULL;
HWND g_hScrollBarWnd = NULL; // 组合框句柄
HWND g_hStaticWnd = NULL; // 静态文本控件
//-----------------------------------------------------------------------------
// FUNC : 入口函数
//-----------------------------------------------------------------------------
// IN : hInstance,进程的实例句柄;
// hPrevInstance,前一个进程实例句柄,默认为NULL即可;
// lpCmdLine,命令行参数;
// nCmdShow,当前窗口显示状态。
// OUT : void
// RETURN : 返回为整型,代表窗口的状态,其中APIENTRY描述了
// 压栈的顺序。
// AUTHOR : 2012-2-6 11:18 Create by lixinghua for functions.
// NOTE : 此函数为Win32入口函数。
//-----------------------------------------------------------------------------
//
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
// 定义所用到的参数
//
char szWindowClass[] = { "WinClsName" };
// 窗口类的名称
HWND hWnd = NULL; // 用于存放窗口句柄
char szTitle[] = { "MyWin" }; // 窗口标题名称
MSG msg; // 存放消息的结构体,
// 由系统提供
// 保存进程实例句柄
g_hIns = hInstance;
// 1. 设计一个窗口类
//
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = (WNDPROC)WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = NULL;
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = NULL;
// 2. 注册窗口
//
RegisterClassEx(&wcex);
// 3. 创建窗口
//
HMENU hMenu = NULL;
hWnd = CreateWindow(szWindowClass, szTitle,
WS_OVERLAPPEDWINDOW, CW_USEDEFAULT,
0, CW_USEDEFAULT, 0, NULL, hMenu, hInstance, NULL);
// 判断创建是否成功
if (!hWnd)
{
return FALSE;
}//end if
// 4. 显示并更新窗口
ShowWindow(hWnd, nCmdShow); // 请注意 nCmdShow 参数
UpdateWindow(hWnd);
// 5. 进入消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}//end while
return 0;
}
//-----------------------------------------------------------------------------
// FUNC : 回调函数
//-----------------------------------------------------------------------------
// IN : hWnd,窗口句柄;
// message,要处理的消息ID,以此来区分消息;
// wParam,消息参数,根据消息的不同内容也有所不同;
// lParam,消息参数,根据消息的不同内容也有所不同。
// OUT : void
// RETURN : void
// AUTHOR : 2012-2-6 11:36 Create by lixinghua for functions.
// NOTE : 此函数用于系统消息的处理。
//-----------------------------------------------------------------------------
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps; // 结构体包含了用于绘
// 制窗口客户区的信息
HDC hdc; // 设备环境句柄
int wmId, wmEvent;
char szContext[512] = { 0 }; // 用于存放控件的内容
static int nPos = 0; // 存放选择列表的位置
// 消息处理
//
switch (message)
{
// 创建窗口时响应的事件
case WM_CREATE:
// 创建列表框
g_hScrollBarWnd = CreateWindow("scrollbar", NULL,
WS_CHILD | WS_VISIBLE | SBS_HORZ,
10, 40, 200, 30, hWnd, (HMENU)ID_SCROLL_BAR,g_hIns, NULL);
// 设置滚动条范围0~100
SetScrollRange(g_hScrollBarWnd, SB_CTL, 0, 100, FALSE);
// 创建静态文本框
g_hStaticWnd = CreateWindow("STATIC", "当前值:0",
WS_CHILD | WS_VISIBLE, 10, 10, 200, 20, hWnd, NULL, g_hIns, NULL);
break;
// 水平滚动条操作
case WM_HSCROLL:
switch(LOWORD(wParam))
{
case SB_PAGEDOWN:
case SB_LINEDOWN:
if(nPos >= 100)
nPos = 100;
else
nPos += 10;
break;
case SB_PAGEUP:
case SB_LINEUP:
if(nPos <= 0)
nPos = 0;
else
nPos -= 10;
break;
default:
break;
}//end switch
// 设置滚动条位置
SetScrollPos(g_hScrollBarWnd, SB_CTL, nPos, TRUE);
// 显示当前滚动条的值
sprintf(szContext, "当前值:%d", nPos);
SetWindowText(g_hStaticWnd, szContext);
break;
// 菜单响应事件
case WM_COMMAND:
wmId = LOWORD(wParam);
wmEvent = HIWORD(wParam);
// 点击按钮时,捕获编辑框的内容,并显示。
switch (wParam)
{
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}//end switch
break;
// 图形绘制事件
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
break;
// 窗口销毁消息,关闭窗口时响应。
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
// 调用系统默认消息处理,即交给系统处理。
return DefWindowProc(hWnd, message, wParam, lParam);
}//end switch
return 0;
}
程序执行结果如图10.7所示。

- 图10.7 滚动条示例结果