420 likes | 542 Views
( 第二十七讲 ). 吉林大学远程教育课件. Windows A P I 编 程. 学 时: 48. 主讲人 : 翟慧杰. 第五节 滚动条. 滚动条既可以是许多子窗口(如编辑框、 列表框)的附件,又可以独立成为子窗口。 1. 基础知识 滚动条的主要用途在于对某个在一定范围内 变化的属性值或者变量进行动态设置。例如 用滚动条可以方便地控制颜色的深浅,设置 线条的宽度;滚动条也用来显示某个任务的进度,这样滚动条又被称为进度条。. 滚动条的风格如表所示。. 滚动条的消息类型如表所示。. 滚动条有一些重要的函数和方法, 下面分别介绍。
E N D
(第二十七讲) 吉林大学远程教育课件 Windows A P I编 程 学 时:48 主讲人 : 翟慧杰
第五节 滚动条 滚动条既可以是许多子窗口(如编辑框、 列表框)的附件,又可以独立成为子窗口。 1.基础知识 滚动条的主要用途在于对某个在一定范围内 变化的属性值或者变量进行动态设置。例如 用滚动条可以方便地控制颜色的深浅,设置 线条的宽度;滚动条也用来显示某个任务的进度,这样滚动条又被称为进度条。
滚动条有一些重要的函数和方法, 下面分别介绍。 用来设置滚动条类型和活动状态的 函数是EnableScrollBar, 其原型定义如下: BOOL EnableScrollBar( HWND hwnd // 指向父窗口或者滚动条的句柄 UINT wSBflags,//标志滚动条的类型 UINT wArrows //滚动条的滚动按钮设置 ); wSBflag用来设置滚动条的类型,可以取表所示的任意值。
wSBflag的取值 参数 wArrows设置滚动条滚动按钮的活动状态, 取值如表所示。
显示或隐藏滚动条的函数是ShowScrollBar, 其原型定义如下: BOOL ShowScrollBar( HWND hwnd ,//指向父窗日的句柄 int wBar ,//滚动条活动状态的标志 BOOL bShow//滚动条是否可见,当为TRUE时可见,相反则隐藏 ); 其中参数 wBar取值如表所示。 2.应用程序举例 滚动条的应用: #include <windows.h> #include <stdlib.h> LRESULT CALLBACK ScrollProc (HWND, UINT, WPARAM, LPARAM) ; WNDPROC fnOldScr[3] ;
//定义全局变量,包括滚动条、标签、 // 颜色值和客户区 HWND hwndScrol[3], hwndLabel[3], HWND hwndValue[3], hwndRect ; int color[3], iFocus,i; //定义三种颜色 static char *szColorLabel[] = { "红色", "绿色", "蓝色" } ; static char szAppName[]="颜色调整"; LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); //函数:WinMain //作用:主应用函数 Int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{ MSG msg ; //注册窗口类 MyRegisterClass(hInstance); //应用程序的初始化 if(!InitInstance(hInstance,iCmdShow)) { return FALSE; } while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; }
//函数:MyRegisterClass //作用:注册窗口类 ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wndclass ; wndclass.cbSize = sizeof (wndclass) ; wndclass.style = CS_HREDRAW | CS_VREDRAW ; wndclass.lpfnWndProc = WndProc ; wndclass.cbClsExtra = 0 ; wndclass.cbWndExtra = 0 ; wndclass.hInstance = hInstance ;
wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION) ; wndclass.hCursor = LoadCursor (NULL, IDC_ARROW) ; wndclass.hbrBackground =(HBRUSH)GetStockObject (WHITE_BRUSH) ; wndclass.lpszMenuName = NULL ; wndclass.lpszClassName = szAppName ; wndclass.hIconSm = LoadIcon (NULL, IDI_APPLICATION) ; return RegisterClassEx (&wndclass) ; }
//函数:InitInstance //作用:初始化应用程序 BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hwnd ; hwnd = CreateWindow (szAppName, "颜色选择", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, nCmdShow) ; UpdateWindow (hwnd) ; return TRUE; }
//函数:WndProc //作用:消息处理函数 LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {//定义颜色结构变量 static COLORREF crPrim[3] = { RGB (255, 0, 0), RGB (0, 255, 0),RGB (0, 0, 255) } ; static HBRUSH hBrush[3], hBrushStatic ; static int cyChar ;
//定义颜色改变区域 static RECT rcColor; char szbuffer[10] ; int i, cxClient, cyClient ; //定义静态文本区域 HWND hwndstatic; HINSTANCE hInstance; hInstance=(HINSTANCE)GetWindowLong( hwnd,GWL_HINSTANCE)
switch (iMsg) { case WM_CREATE : for (i = 0 ; i < 3 ; i++) hBrush[i] = CreateSolidBrush (crPrim[i]) ; //定义画刷 hBrushStatic = CreateSolidBrush ( GetSysColor (COLOR_BTNHIGHLIGHT)) ; cyChar = HIWORD (GetDialogBaseUnits ()) ; //创建文本区域,用来存放滚动条 hwndRect = CreateWindow ("static", NULL, WS_CHILD | WS_VISIBLE | SS_WHITERECT, 0, 0, 0, 0, hwnd, (HMENU) 9, hInstance, NULL) ;
//创建文本区域,显示应用程序当前状态 hwndstatic = CreateWindow ("static","颜色调整", WS_CHILD | WS_VISIBLE|SS_CENTER, 400,300,100,30, hwnd, (HMENU) 9, hInstance, NULL) ;
//用For 循环来苏实现滚动条、标签、数值的显示 for (i = 0 ; i < 3 ; i++) { hwndScrol[i] = CreateWindow ("scrollbar", NULL, WS_CHILD | WS_VISIBLE |SBS_HORZ, 0, 0, 0, 0, hwnd, (HMENU) i, hInstance, NULL) ; hwndLabel[i] = CreateWindow ("static", szColorLabel[i], WS_CHILD | WS_VISIBLE | SS_CENTER, 0, 0, 0, 0, hwnd, (HMENU) (i + 3), hInstance, NULL) ; hwndValue[i] = CreateWindow ("static", "0", WS_CHILD | WS_VISIBLE | SS_CENTER, 0,0,0,0, hwnd, (HMENU) (i + 6), hInstance, NULL) ; fnOldScr[i] = (WNDPROC) SetWindowLong (hwndScrol[i], GWL_WNDPROC, (LONG) ScrollProc) ;
//设置滚动条滚动范围 SetScrollRange (hwndScrol[i], SB_CTL, 0, 255,FALSE) ; //设置滚动条初始位置 SetScrollPos (hwndScrol[i], SB_CTL, 20,FALSE) ; } return 0 ; case WM_SIZE : //获取客户区大小 cxClient = LOWORD (lParam) ; cyClient = HIWORD (lParam) ; //设置颜色变化区域 SetRect (&rcColor, 0, 0, cxClient/2, cyClient) ; MoveWindow (hwndRect, cxClient/2,0,cxClient / 2, cyClient, TRUE) ;
//设置滚动条的位置 for (i = 0 ; i < 3 ; i++) { MoveWindow (hwndScrol[i], cxClient/2+60,(i+2)*cyClient/6-100, cxClient/3, cyClient/12,TRUE) ; MoveWindow (hwndLabel[i], cxClient/2+20,(i+2)*cyClient/6-100, 40,cyClient/12, TRUE) ; MoveWindow (hwndValue[i], cxClient-40,(i+2)*cyClient/6-100, 40, cyClient/12, TRUE) ; }
SetFocus (hwnd) ; return 0 ; case WM_SETFOCUS : SetFocus (hwndScrol[iFocus]) ; return 0 ; case WM_HSCROLL : i = GetWindowLong ((HWND) lParam, GWL_ID) ; //设置滚动条滚动的步长 switch (LOWORD (wParam)) { case SB_PAGEDOWN : color[i] += 15 ; case SB_LINEDOWN : color[i] = min (255, color[i] + 1) ; break ;
case SB_PAGEUP : color[i] -= 15 ; case SB_LINEUP : color[i] = max (0, color[i] - 1) ; break ; case SB_TOP : color[i] = 0 ; break ; case SB_BOTTOM : color[i] = 255 ; break ; case SB_THUMBPOSITION : case SB_THUMBTRACK : color[i] = HIWORD (wParam) ; break ; default : break ; }
//从滚动条的位置读取颜色值 SetScrollPos (hwndScrol[i], SB_CTL, color[i], TRUE) ; //显示颜色值 SetWindowText (hwndValue[i], itoa (color[i], szbuffer, 10)) ; //释放画刷资源 DeleteObject ((HBRUSH) SetClassLong(hwnd, GCL_HBRBACKGROUND,(LONG) CreateSolidBrush(RGB (color[0], color[1], color[2])))) ; //重画颜色变化区域 InvalidateRect (hwnd, &rcColor, TRUE) ; return 0 ; case WM_CTLCOLORSCROLLBAR : //获取当前活动资源的标识符 i = GetWindowLong ((HWND) lParam, GWL_ID) ; return (LRESULT) hBrush[i] ;
case WM_CTLCOLORSTATIC : /*获取当前活动资源的标识符,如果大于 3且小于8则读取系统颜色值*/ i = GetWindowLong ((HWND) lParam, GWL_ID) ; if (i >= 3 && i <= 8) { SetTextColor ((HDC) wParam, crPrim[i % 3]) ; SetBkColor ((HDC) wParam, GetSysColor (COLOR_BTNHIGHLIGHT)); return (LRESULT) hBrushStatic ; } break ;
case WM_SYSCOLORCHANGE : DeleteObject (hBrushStatic) ; hBrushStatic = CreateSolidBrush ( GetSysColor (COLOR_BTNHIGHLIGHT)) ; return 0 ; case WM_DESTROY : //释放画刷资源 DeleteObject ((HBRUSH) SetClassLong (hwnd, GCL_HBRBACKGROUND, (LONG) GetStockObject (WHITE_BRUSH))) ; for (i = 0 ; i < 3 ; DeleteObject (hBrush[i++])) ; DeleteObject (hBrushStatic) ; PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, iMsg, wParam, lParam) ; }
//函数:ScrollProc //作用:滚动条消息处理 LRESULT CALLBACK ScrollProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) { int i = GetWindowLong (hwnd, GWL_ID) ; switch (iMsg) { case WM_KEYDOWN : //响应TAB键,当i小于3时,则转向下一个滚动条,否则重新开始 if (wParam == VK_TAB) SetFocus (hwndScrol[(i + (GetKeyState (VK_SHIFT) < 0 ? 2 : 1)) % 3]) ; break ;
case WM_SETFOCUS : iFocus = i ; break ; } Return CallWindowProc(fnOldScr[i],hwnd,iMsg,wParam,lParam); } 本应用程序的主要功能是创建三个滚动条,分别控制红、黄、蓝三种颜色的深浅。 程序在消息循环函数中首先创建滚动条,代码如下: hwndScrol[i] = CreateWindow ("scrollbar", NULL, WS_CHILD | WS_VISIBLE |SBS_HORZ,0, 0, 0, 0, hwnd, (HMENU) i, hInstance, NULL) ; 第一个参数为“scrollbar”,表示创建的子窗口是滚动条;第三个参数中的SBS_ HORZ表示滚动条是水平的;由于有三个滚动条将被创建,所以第九个参数为(HMENU)i,作为滚动条的标识符。
滚动条有自己的消息处理函数,但是必须在应用滚动条有自己的消息处理函数,但是必须在应用 程序中指定消息处理函数的句柄,并分配给相应 的滚动条,代码如下: fnOldScr[i] = (WNDPROC) SetWindowLong ( hwndScrol[i], GWL_WNDPROC, (LONG) ScrollProc) ; 第一个参数hWndScrol为滚动条的名称,第三个参数ScrollProc则为指向滚动条消息处理函数的指针。 创建滚动条后,需要对它初始化,包括设置滚动条的初始位置以及滚动条滚动的范围,代码如下: SetScrollRange (hwndScrol[i], SB_CTL, 0, 255,FALSE) ; //设置滚动条初始位置 SetScrollPos (hwndScrol[i], SB_CTL, 20,FALSE) ;
其中,SetScrollRange函数的原型定义如下: BOOL SetScrollRange( HWND hwnd,//指向父窗口的句柄 Int nBar,//滚动条的活动状态 Int nMinPos, //最小值 int nMaxPos, //最大值 BOOL bRedraw //重画的标志 ); SetScrollPos用来设置滚动条初始位置值,原型定义如下: int SetScrollPos( HWND hwnd ,//指向父窗口的句柄 int nBar, // 设置滚动条的活动状态 int nPos, // 设置滚动条位置值 BOOL bRedraw //重画的标志 );
当SetScrollPos函数执行成功后,将返 回原来的位置值。初始化滚动条后,滚 动条就能响应用户的操作,这些操作包括 用户按下PageDown、PageUp以及方向键, 而鼠标的拖动则由滚动条自动处理。 滚动条消息处理的代码如下: case WM_HSCROLL: I=GetWindowLong((HWND)lParam,GWL_ID); SWitCh(LOWORD (Wpgram)) { case SB_PAGEDOWN: color[i]+=15 代码中首先判断用户操作的消息类型是否为WMNSCROLL,
注意,如果创建滚动条时定义的风格为 SB_VERT,则该消息类型应该为 WM_VSCROLL。然后得到当前 滚动条的标识符,消息中参数wParam 的低位字节包含了消息的通知代码, 例如程序中的SB_ PAGEDOWN、 SB_PAGEUP、SB_LINEDOWN、 SB_TOP。它们分别表示用户对键 盘的操作。滚动条每次拖动的步长为15。
用鼠标拖动滚动条,则左边矩形区域的颜色 将由浅入深变化,结果如图所示。
按钮控件实例2 #include <windows.h> #define IDE_AUTOCHECKBOX 100 #define IDE_AUTORADIOBUTTON 200 #define IDE_AUTO3STATE 300 #define IDE_CHECKBOX 400 #define IDE_DEFPUSHBUTTON 500 #define IDE_PUSHBUTTON 600 #define IDE_RADIOBUTTON 700 HWND hWnd; HWND hCtlButton[8]; int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int); LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW|CS_VREDRAW|CS_DBLCLKS; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon= LoadIcon(NULL,(LPCTSTR)IDI_APPLICATION); wcex.hCursor = LoadCursor(NULL,IDC_ARROW); wcex.hbrBackground = (HBRUSH)COLOR_WINDOW; wcex.lpszMenuName = NULL; wcex.lpszClassName = "WndCls"; wcex.hIconSm = LoadIcon(NULL,(LPCTSTR)IDI_APPLICATION);
if(!RegisterClassEx(&wcex)) return FALSE; int SW_XFS = GetSystemMetrics(SM_CXSCREEN); int SW_YFS = GetSystemMetrics(SM_CYSCREEN); hWnd = CreateWindowEx(NULL, "WndCls", "Demo of Button Control", WS_OVERLAPPEDWINDOW, 0, 0, SW_XFS, SW_YFS-25, NULL, NULL, hInstance, NULL); if(!hWnd) return FALSE;
ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); hCtlButton[0] = CreateWindowEx( NULL, "BUTTON", "自动复选框(方框)", WS_CHILD|WS_VISIBLE|BS_AUTOCHECKBOX, 10, 10, 200, 30, hWnd, (HMENU)IDE_AUTOCHECKBOX, hInstance, NULL);
hCtlButton[1] = CreateWindowEx(NULL, "BUTTON", “自动复选框(园框)”, WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, 10, 40,200, 30, hWnd, (HMENU)IDE_AUTORADIOBUTTON, hInstance, NULL); hCtlButton[2] = CreateWindowEx(NULL, "BUTTON", “自动复选框(园框)”, WS_CHILD|WS_VISIBLE|BS_AUTORADIOBUTTON, 10,70, 200,30, hWnd, (HMENU)IDE_AUTORADIOBUTTON, hInstance, NULL);
hCtlButton[3] = CreateWindowEx(NULL, "BUTTON", "三态复选框(方框)", WS_CHILD|WS_VISIBLE|BS_AUTO3STATE, 10,100,200,30, hWnd, (HMENU)IDE_AUTO3STATE, hInstance, NULL); hCtlButton[4] = CreateWindowEx(NULL, "BUTTON", "复选框(方框)", WS_CHILD|WS_VISIBLE|BS_CHECKBOX, 10,130,200,30, hWnd, (HMENU)IDE_CHECKBOX, hInstance, NULL);
hCtlButton[5] = CreateWindowEx(NULL, "BUTTON", “下压式按钮”, WS_CHILD|WS_VISIBLE|BS_DEFPUSHBUTTON, 10,160,200,30, hWnd, (HMENU)IDE_DEFPUSHBUTTON, hInstance, NULL); hCtlButton[6] = CreateWindowEx(NULL, "BUTTON", “下压式按钮”, WS_CHILD|WS_VISIBLE|BS_PUSHBUTTON, 10,190,200,30, hWnd, (HMENU)IDE_PUSHBUTTON, hInstance, NULL);
hCtlButton[7] = CreateWindowEx(NULL, "BUTTON", “复选框(园框)”, WS_CHILD|WS_VISIBLE|BS_RADIOBUTTON, 10,220,200,30, hWnd, (HMENU)IDE_RADIOBUTTON, hInstance, NULL); MSG msg; while(GetMessage(&msg,NULL,0,0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch(message) { case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd,message,wParam,lParam); } return 0; }