1 / 42

( 第二十七讲 )

( 第二十七讲 ). 吉林大学远程教育课件. Windows A P I 编 程. 学 时: 48. 主讲人 : 翟慧杰. 第五节 滚动条. 滚动条既可以是许多子窗口(如编辑框、 列表框)的附件,又可以独立成为子窗口。 1. 基础知识 滚动条的主要用途在于对某个在一定范围内 变化的属性值或者变量进行动态设置。例如 用滚动条可以方便地控制颜色的深浅,设置 线条的宽度;滚动条也用来显示某个任务的进度,这样滚动条又被称为进度条。. 滚动条的风格如表所示。. 滚动条的消息类型如表所示。. 滚动条有一些重要的函数和方法, 下面分别介绍。

Download Presentation

( 第二十七讲 )

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. (第二十七讲) 吉林大学远程教育课件 Windows A P I编 程 学 时:48 主讲人 : 翟慧杰

  2. 第五节 滚动条 滚动条既可以是许多子窗口(如编辑框、 列表框)的附件,又可以独立成为子窗口。 1.基础知识 滚动条的主要用途在于对某个在一定范围内 变化的属性值或者变量进行动态设置。例如 用滚动条可以方便地控制颜色的深浅,设置 线条的宽度;滚动条也用来显示某个任务的进度,这样滚动条又被称为进度条。

  3. 滚动条的风格如表所示。

  4. 滚动条的消息类型如表所示。

  5. 滚动条有一些重要的函数和方法, 下面分别介绍。 用来设置滚动条类型和活动状态的 函数是EnableScrollBar, 其原型定义如下: BOOL EnableScrollBar( HWND hwnd // 指向父窗口或者滚动条的句柄 UINT wSBflags,//标志滚动条的类型 UINT wArrows //滚动条的滚动按钮设置 ); wSBflag用来设置滚动条的类型,可以取表所示的任意值。

  6. wSBflag的取值 参数 wArrows设置滚动条滚动按钮的活动状态, 取值如表所示。

  7. 显示或隐藏滚动条的函数是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] ;

  8. //定义全局变量,包括滚动条、标签、 // 颜色值和客户区 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)

  9. { MSG msg ; //注册窗口类 MyRegisterClass(hInstance); //应用程序的初始化 if(!InitInstance(hInstance,iCmdShow)) { return FALSE; } while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; }

  10. //函数: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 ;

  11. 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) ; }

  12. //函数: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; }

  13. //函数: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 ;

  14. //定义颜色改变区域 static RECT rcColor; char szbuffer[10] ; int i, cxClient, cyClient ; //定义静态文本区域 HWND hwndstatic; HINSTANCE hInstance; hInstance=(HINSTANCE)GetWindowLong( hwnd,GWL_HINSTANCE)

  15. 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) ;

  16. //创建文本区域,显示应用程序当前状态 hwndstatic = CreateWindow ("static","颜色调整", WS_CHILD | WS_VISIBLE|SS_CENTER, 400,300,100,30, hwnd, (HMENU) 9, hInstance, NULL) ;

  17. //用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) ;

  18. //设置滚动条滚动范围 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) ;

  19. //设置滚动条的位置 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) ; }

  20. 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 ;

  21. 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 ; }

  22. //从滚动条的位置读取颜色值 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] ;

  23. 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 ;

  24. 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) ; }

  25. //函数: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 ;

  26. 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,作为滚动条的标识符。

  27. 滚动条有自己的消息处理函数,但是必须在应用滚动条有自己的消息处理函数,但是必须在应用 程序中指定消息处理函数的句柄,并分配给相应 的滚动条,代码如下: 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) ;

  28. 其中,SetScrollRange函数的原型定义如下: BOOL SetScrollRange( HWND hwnd,//指向父窗口的句柄 Int nBar,//滚动条的活动状态 Int nMinPos, //最小值 int nMaxPos, //最大值 BOOL bRedraw //重画的标志 ); SetScrollPos用来设置滚动条初始位置值,原型定义如下: int SetScrollPos( HWND hwnd ,//指向父窗口的句柄 int nBar, // 设置滚动条的活动状态 int nPos, // 设置滚动条位置值 BOOL bRedraw //重画的标志 );

  29. 当SetScrollPos函数执行成功后,将返 回原来的位置值。初始化滚动条后,滚 动条就能响应用户的操作,这些操作包括 用户按下PageDown、PageUp以及方向键, 而鼠标的拖动则由滚动条自动处理。 滚动条消息处理的代码如下: case WM_HSCROLL: I=GetWindowLong((HWND)lParam,GWL_ID); SWitCh(LOWORD (Wpgram)) { case SB_PAGEDOWN: color[i]+=15 代码中首先判断用户操作的消息类型是否为WMNSCROLL,

  30. 注意,如果创建滚动条时定义的风格为 SB_VERT,则该消息类型应该为 WM_VSCROLL。然后得到当前 滚动条的标识符,消息中参数wParam 的低位字节包含了消息的通知代码, 例如程序中的SB_ PAGEDOWN、 SB_PAGEUP、SB_LINEDOWN、 SB_TOP。它们分别表示用户对键 盘的操作。滚动条每次拖动的步长为15。

  31. 程序运行结果如图所示。

  32. 用鼠标拖动滚动条,则左边矩形区域的颜色 将由浅入深变化,结果如图所示。

  33. 按钮控件实例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);

  34. 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);

  35. 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;

  36. 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);

  37. 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);

  38. 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);

  39. 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);

  40. 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; }

  41. 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; }

More Related