两个函数:GetScrolnfo和SetScrollnfo
一个结构:SCROLLINFO
两个消息:WM_CREATE和WM_SIZE
滚动条结构体
typedef struct tagSCROLLINFO { UINT cbSize; UINT fMask; int nMin; int nMax; UINT nPage; int nPos; int nTrackPos; } SCROLLINFO, *LPSCROLLINFO;
cbSize:以字节为单位,结构体大小。就调用者这个参数设置为 sizeof(SCROLLINFO)
fMask:指定要设置或检索的滚动条参数。该成员可以是以下值的组合:
nMin:滚动条最小位置
nMax:滚动条最大位置
nPage:滚动页大小
nPos:停止拖动滚顶条后,滚动条位
获取滚动条信息
BOOL GetScrollBarInfo(
HWND hwnd,
LONG idObject,
PSCROLLBARINFO psbi
);
hWnd:是一个滚动条控件的句柄。否则是一个具有WS_VSCROLL或WS_HSCROLL样式的窗口句柄
idObject:指定滚动条对象。这个参数可以是以下值之一
int SetScrollInfo( HWND hwnd, int nBar, LPCSCROLLINFO lpsi, BOOL redraw );
hwnd:滚动条控件或带标准滚动条的窗体句柄,由nBar参数决定。
nBar:指定被设定参数的滚动条的类型。这个参数可以是下面值
就像所有消息一样,WM_VSCROLL和WM_HSCROLL消息都伴随着wParam和IParam消息参数。当滚动条是窗口的一部分时,可以忽略IParam参数:它只用于滚动条是子窗口时,通常是在对话框中。
wParam参数被分为低位字和高位字。wParam的低位字代表了鼠标在滚动条上的动作。这个值被称为“通知码”,由一个以SB开头的标识符定义(SB代表滚动条)
如果在滚动条的不同部分按住鼠标键不放,程序可能收到多条滚动条消息。当松开鼠标键时,程序会收到一条带有SB_ENDSCROLL通知码的消息。程序通常可以忽略带SB_ENDSCROLL的消息。Windows并不会自己改变滑块的位置,应用程序需要调用SetScrollPos函数来改变它。
将鼠标放在滑块上然后按下鼠标键时,可以移动滑块。这将会生成带SB_THUMBTRACK 和SB_THUMBPOSITION 通知码的滚动条消息。当wParam的低位字是SB_THUMBTRACK时,wParam的高位字是用户拖动滑块的当前位置。这个位置处于滚动条范围的最小值和最大值之间。当wParam的低位字是SB_THUMBPOSITION时,wParam的高位字是用户松开鼠标键时滑块的最终位置。对于其他的滚动条动作,wParam的高位字应被忽略。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<Windows.h> 2 #include<tchar.h> 3 #include<stdio.h> 4 #define NUM 1000 5 6 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); 7 8 int WinMain(HINSTANCE hInst, HINSTANCE tmp, LPSTR szCmd, int nShow) 9 { 10 WNDCLASS WndClass; 11 TCHAR* ClassName = TEXT("MyClass"); 12 HWND hwnd; 13 MSG msg; 14 HBRUSH hBrush; 15 16 hBrush = CreateSolidBrush(RGB(0x20, 0x85, 0x41)); 17 WndClass.cbClsExtra = 0; 18 WndClass.cbWndExtra = 0; 19 WndClass.hbrBackground = hBrush; 20 WndClass.hCursor = LoadCursor(NULL, IDC_ARROW); 21 WndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 22 WndClass.hInstance = hInst; 23 WndClass.lpfnWndProc = WindProc; 24 WndClass.lpszClassName = ClassName; 25 WndClass.lpszMenuName = NULL; 26 WndClass.style = CS_VREDRAW | CS_HREDRAW; 27 28 if (!RegisterClass(&WndClass)) 29 { 30 MessageBox(NULL, TEXT("Gegister Class Fail!!"), TEXT("error"), MB_OK); 31 return 0; 32 } 33 34 //WS_VSCROLL窗口滚动条 35 hwnd = CreateWindow(ClassName, TEXT("Hello"), WS_OVERLAPPEDWINDOW | WS_VSCROLL, 0, 0, 500, 300, NULL, NULL, hInst, NULL); 36 if (hwnd == NULL) 37 { 38 MessageBox(NULL, TEXT("Create Window Fail!!"), TEXT("error"), MB_OK); 39 return 0; 40 } 41 ShowWindow(hwnd, nShow); 42 UpdateWindow(hwnd); 43 44 while (GetMessage(&msg, NULL, 0, 0)) 45 { 46 TranslateMessage(&msg); 47 DispatchMessage(&msg); 48 } 49 50 return 0; 51 } 52 53 LRESULT CALLBACK WindProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) 54 { 55 HDC hdc; 56 PAINTSTRUCT pt; 57 TEXTMETRIC ts; 58 TCHAR buf[1024]; 59 int i; //行数 60 static int cyChar; //字体大小 61 static int cy; //客户区高度 62 static SCROLLINFO si; 63 static int position = 0; 64 switch (message) 65 { 66 case WM_CREATE: 67 hdc = GetDC(hwnd); 68 GetTextMetrics(hdc, &ts); 69 ReleaseDC(hwnd, hdc); 70 cyChar = ts.tmHeight; 71 si.cbSize = sizeof(si); 72 return 0; 73 case WM_SIZE: 74 //窗口高度 75 cy = HIWORD(lParam); 76 si.fMask = SIF_ALL; 77 si.nMax = NUM - 1; 78 si.nMin = 0; 79 si.nPage = cy / cyChar; 80 si.nPos = position; 81 si.nTrackPos = 0; 82 SetScrollInfo(hwnd, SB_VERT, &si, TRUE); 83 case WM_VSCROLL: 84 //当滚动条是窗口的一部分时,可以忽略IParam参数 85 switch (LOWORD(wParam)) 86 { 87 case SB_BOTTOM: 88 si.nPos = si.nMax; 89 break; 90 case SB_LINEDOWN: 91 si.nPos++; 92 break; 93 case SB_LINEUP: 94 si.nPos--; 95 break; 96 case SB_PAGEDOWN: 97 si.nPos = si.nPos + cy / cyChar; 98 break; 99 case SB_PAGEUP: 100 si.nPos = si.nPos - cy / cyChar; 101 break; 102 case SB_THUMBPOSITION: 103 si.nPos = HIWORD(wParam); 104 break; 105 default: 106 break; 107 } 108 si.fMask = SIF_POS; 109 SetScrollInfo(hwnd, SB_VERT, &si, TRUE); 110 GetScrollBarInfo(hwnd, SB_VERT, &si); 111 position = si.nPos; 112 //UpdateWindow(hwnd);//窗口必须有无效区,否则刷新也是白刷。替换为InvalidateRect强制刷新 113 //InvalidateRect函数会产生WM_PAINT消息 114 InvalidateRect(hwnd, NULL, FALSE); 115 return 0; 116 case WM_PAINT: 117 GetScrollBarInfo(hwnd, SB_VERT, &si); 118 hdc = BeginPaint(hwnd, &pt); 119 for (i = 0; i < NUM; i++) 120 { 121 _stprintf(buf, TEXT("---------------%d--------------"), si.nPos + i); 122 TextOut(hdc, 0, i * cyChar, buf, _tcslen(buf)); 123 } 124 EndPaint(hwnd, &pt); 125 return 0; 126 case WM_DESTROY: 127 PostQuitMessage(0);//发送WM_QUIT消息 128 return 0; 129 default: 130 break; 131 } 132 133 return DefWindowProc(hwnd, message, wParam, lParam); 134 }
创建画刷
HBRUSH CreateSolidBrush(
COLORREF color
);
初始化一个指定颜色的画刷。画笔可以随后被选为任何设备上下文的当前刷子。
获取当前字体信息
BOOL GetTextMetrics(
HDC hdc,
LPTEXTMETRIC lptm
);
该函数把程序当前的字体信息,存放到TEXTMETRIC