/* 滚动条 * * 系统函数: * SetScrollRange(hwnd, iBar, iMin, iMax, bRedraw); 设置滚动条范围 * GetScrollRange * SetScrollPos(hwnd, iBar, iPos, bRedraw); 指定滚动条滑块的位置 * GetScrollPos * * 系统消息 * WM_VSCROLL wParam 低位字代表滚动条动作 * WM_HSCROLL */ #include "stdafx.h" #include "HelloWnd.h" /* // 注意定义的结构方式 struct { int index; TCHAR *szLabel; TCHAR *szDesc; } sysmetrics [] = { SM_CXSCREEN, TEXT("SM_CXSCREEN"), TEXT("Screen width in pixels"), SM_CYSCREEN, TEXT("SM_CYSCREEN"), TEXT("Screen height in pixels") }; */ #include "SysMets.h" // 将以上结构移到头文件中 LRESULT CALLBACK HelloWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { static int cxClient, cyClient; // 客户端的宽度和高度,在窗口发生变化的时候,windows都会发送WM_SIZE消息,该消息的lParam高位保存高度,地位保存宽度 static int cxLowercaseWidth, cxUppercaseWidth; static int cyCharHight; TEXTMETRIC tm; HDC hdc; PAINTSTRUCT ps; static int nVScrollPos = 0; int y = 0; switch(uMsg) { case WM_CREATE: { hdc = GetDC(hwnd); // 在非WM_PAINT消息里面调用此方法获得HDC GetTextMetrics(hdc, &tm); ReleaseDC(hwnd, hdc); cyCharHight = tm.tmHeight + tm.tmExternalLeading; cxLowercaseWidth = tm.tmAveCharWidth; cxUppercaseWidth = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxLowercaseWidth / 2; // 设置滚动条范围 SetScrollRange(hwnd, SB_VERT, 0, NUMLINES-1, FALSE); // 设置滚动条位置 SetScrollPos(hwnd, SB_VERT, nVScrollPos, FALSE); } break; case WM_VSCROLL: // 水平滚动条消息 { switch(LOWORD(wParam)) // 低字位代表滚动条动作 { case SB_LINEUP: nVScrollPos -= 1; break; case SB_LINEDOWN: nVScrollPos += 1; break; case SB_PAGEUP: // 一页 nVScrollPos -= cyClient/ cyCharHight; break; case SB_PAGEDOWN: nVScrollPos += cyClient / cyCharHight; break; case SB_THUMBPOSITION: nVScrollPos = HIWORD(wParam); break; } nVScrollPos = max(0, min(nVScrollPos, NUMLINES -1)); if(nVScrollPos != GetScrollPos(hwnd, SB_VERT)) { SetScrollPos(hwnd, SB_VERT, nVScrollPos, TRUE); InvalidateRect(hwnd, NULL, TRUE); } } break; case WM_PAINT: { hdc = BeginPaint(hwnd, &ps); // WM_PAINT 消息里面使用该方法获得HDC // 绘制文本 for(int i = 0; i<NUMLINES; i++) { y = (i - nVScrollPos) * cyCharHight; TextOut(hdc, 0, y,sysmetrics[i].szLabel, lstrlen(sysmetrics[i].szLabel)); } EndPaint(hwnd,&ps); } break; case WM_SIZE: { // 在窗口每次发生变化的时候,获取客户端高度和宽度 cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); } break; case WM_CLOSE: { if(IDOK == MessageBox(hwnd, _T("是否关闭窗口"), _T("提示"), MB_OK | MB_OKCANCEL)) { DestroyWindow(hwnd); // 销毁窗口 } } break; case WM_DESTROY: { PostQuitMessage(0); // 发送 WM_CLOSE, 形参 0 将会传递给 WPARAM } break; default: return DefWindowProc(hwnd,uMsg,wParam,lParam); } return 0; } int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow) { // 设计一个窗口类 WNDCLASS wndclass; wndclass.style = CS_VREDRAW | CS_HREDRAW; wndclass.lpfnWndProc = HelloWndProc; // 由windows系统调用 wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon(NULL, MAKEINTRESOURCE(IDI_WINLOGO)); wndclass.hCursor = LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW)); wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = _T("hellownd"); // 此处是指定窗口类名称,用于关联窗口,CreateWindow第一个参数 // 注册窗口类 RegisterClass(&wndclass); // 创建窗口 HWND hwnd = CreateWindow(_T("hellownd"), _T("hellownd"), WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL, /*添加了滚动条*/ CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); // WM_CREATE // 显示窗口 ShowWindow(hwnd, SW_SHOW); // WM_SIZE // 更新窗口 UpdateWindow(hwnd); // WM_PAINT // 消息循环 MSG msg; while(GetMessage(&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } UnregisterClass(_T("hellownd"), hInstance); return msg.wParam; // 来自与PostQuitMessage中的参数 }