特殊说明:版权归个人所有,请勿转载,谢谢合作。
在使用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 滚动条示例结果