- 滚动条(以滚动列,即纵向为例)
- 滚动条的绘制:系统绘制CreateWindow(..., WS_OVERLAPPEDWINDOW | WS_VSCROLL /*| WS_HSCROLL*/, ...)
- 系统与用户分别需要对滚动条做些什么
- 滚动条处理函式解析
- 滚动条响应视窗处理程式解析
- 为了实现滚动列的实例,参考了《windows程式设计 第五版》,这里使用TextOut(...)函数在显示区域绘制系统字体,这里需要知道每一行字体的高度,才能获取字体的总行数,下面为字体高度解析
- 程序设计(参考《windows程式设计 第五版》)
- Metrics.h
-
#ifndef _METRICS_H__ #define _METRICS_H__ #include <windows.h> #define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0])) typedef struct { int Index; TCHAR * szLabel; TCHAR * szDesc; }ST_METRICS, *PST_METRICS; ST_METRICS sysmetrics[] = { SM_CXSCREEN, TEXT("SM_CXSCREEN"), TEXT("Screen width in pixels"), SM_CYSCREEN, TEXT("SM_CYSCREEN"), TEXT("Screen height in pixels"), SM_CXVSCROLL, TEXT("SM_CXVSCROLL"), TEXT("Vertical scroll width"), SM_CYHSCROLL, TEXT("SM_CYHSCROLL"), TEXT("Horizontal scroll height"), SM_CYCAPTION, TEXT("SM_CYCAPTION"), TEXT("Caption bar height"), SM_CXBORDER, TEXT("SM_CXBORDER"), TEXT("Window border width"), SM_CYBORDER, TEXT("SM_CYBORDER"), TEXT("Window border height"), SM_CXFIXEDFRAME, TEXT("SM_CXFIXEDFRAME"), TEXT("Dialog window frame width"), SM_CYFIXEDFRAME, TEXT("SM_CYFIXEDFRAME"), TEXT("Dialog window frame height"), SM_CYVTHUMB, TEXT("SM_CYVTHUMB"), TEXT("Vertical scroll thumb height"), SM_CXHTHUMB, TEXT("SM_CXHTHUMB"), TEXT("Horizontal scroll thumb width"), SM_CXICON, TEXT("SM_CXICON"), TEXT("Icon width"), SM_CYICON, TEXT("SM_CYICON"), TEXT("Icon height"), SM_CXCURSOR, TEXT("SM_CXCURSOR"), TEXT("Cursor width"), SM_CYCURSOR, TEXT("SM_CYCURSOR"), TEXT("Cursor height"), SM_CYMENU, TEXT("SM_CYMENU"), TEXT("Menu bar height"), SM_CXFULLSCREEN, TEXT("SM_CXFULLSCREEN"), TEXT("Full screen client area width"), SM_CYFULLSCREEN, TEXT("SM_CYFULLSCREEN"), TEXT("Full screen client area height"), SM_CYKANJIWINDOW, TEXT("SM_CYKANJIWINDOW"), TEXT("Kanji window height"), SM_MOUSEPRESENT, TEXT("SM_MOUSEPRESENT"), TEXT("Mouse present flag"), SM_CYVSCROLL, TEXT("SM_CYVSCROLL"), TEXT("Vertical scroll arrow height"), SM_CXHSCROLL, TEXT("SM_CXHSCROLL"), TEXT("Horizontal scroll arrow width"), SM_DEBUG, TEXT("SM_DEBUG"), TEXT("Debug version flag"), SM_SWAPBUTTON, TEXT("SM_SWAPBUTTON"), TEXT("Mouse buttons swapped flag"), SM_CXMIN, TEXT("SM_CXMIN"), TEXT("Minimum window width"), SM_CYMIN, TEXT("SM_CYMIN"), TEXT("Minimum window height"), SM_CXSIZE, TEXT("SM_CXSIZE"), TEXT("Min/Max/Close button width"), SM_CYSIZE, TEXT("SM_CYSIZE"), TEXT("Min/Max/Close button height"), SM_CXSIZEFRAME, TEXT("SM_CXSIZEFRAME"), TEXT("Window sizing frame width"), SM_CYSIZEFRAME, TEXT("SM_CYSIZEFRAME"), TEXT("Window sizing frame height"), SM_CXMINTRACK, TEXT("SM_CXMINTRACK"), TEXT("Minimum window tracking width"), SM_CYMINTRACK, TEXT("SM_CYMINTRACK"), TEXT("Minimum window tracking height"), SM_CXDOUBLECLK, TEXT("SM_CXDOUBLECLK"), TEXT("Double click x tolerance"), SM_CYDOUBLECLK, TEXT("SM_CYDOUBLECLK"), TEXT("Double click y tolerance"), SM_CXICONSPACING, TEXT("SM_CXICONSPACING"), TEXT("Horizontal icon spacing"), SM_CYICONSPACING, TEXT("SM_CYICONSPACING"), TEXT("Vertical icon spacing"), SM_MENUDROPALIGNMENT, TEXT("SM_MENUDROPALIGNMENT"), TEXT("Left or right menu drop"), SM_PENWINDOWS, TEXT("SM_PENWINDOWS"), TEXT("Pen extensions installed"), SM_DBCSENABLED, TEXT("SM_DBCSENABLED"), TEXT("Double-Byte Char Set enabled"), SM_CMOUSEBUTTONS, TEXT("SM_CMOUSEBUTTONS"), TEXT("Number of mouse buttons"), SM_SECURE, TEXT("SM_SECURE"), TEXT("Security present flag"), SM_CXEDGE, TEXT("SM_CXEDGE"), TEXT("3-D border width"), SM_CYEDGE, TEXT("SM_CYEDGE"), TEXT("3-D border height"), SM_CXMINSPACING, TEXT("SM_CXMINSPACING"), TEXT("Minimized window spacing width"), SM_CYMINSPACING, TEXT("SM_CYMINSPACING"), TEXT("Minimized window spacing height"), SM_CXSMICON, TEXT("SM_CXSMICON"), TEXT("Small icon width"), SM_CYSMICON, TEXT("SM_CYSMICON"), TEXT("Small icon height"), SM_CYSMCAPTION, TEXT("SM_CYSMCAPTION"), TEXT("Small caption height"), SM_CXSMSIZE, TEXT("SM_CXSMSIZE"), TEXT("Small caption button width"), SM_CYSMSIZE, TEXT("SM_CYSMSIZE"), TEXT("Small caption button height"), SM_CXMENUSIZE, TEXT("SM_CXMENUSIZE"), TEXT("Menu bar button width"), SM_CYMENUSIZE, TEXT("SM_CYMENUSIZE"), TEXT("Menu bar button height"), SM_ARRANGE, TEXT("SM_ARRANGE"), TEXT("How minimized windows arranged"), SM_CXMINIMIZED, TEXT("SM_CXMINIMIZED"), TEXT("Minimized window width"), SM_CYMINIMIZED, TEXT("SM_CYMINIMIZED"), TEXT("Minimized window height"), SM_CXMAXTRACK, TEXT("SM_CXMAXTRACK"), TEXT("Maximum draggable width"), SM_CYMAXTRACK, TEXT("SM_CYMAXTRACK"), TEXT("Maximum draggable height"), SM_CXMAXIMIZED, TEXT("SM_CXMAXIMIZED"), TEXT("Width of maximized window"), SM_CYMAXIMIZED, TEXT("SM_CYMAXIMIZED"), TEXT("Height of maximized window"), SM_NETWORK, TEXT("SM_NETWORK"), TEXT("Network present flag"), SM_CLEANBOOT, TEXT("SM_CLEANBOOT"), TEXT("How system was booted"), SM_CXDRAG, TEXT("SM_CXDRAG"), TEXT("Avoid drag x tolerance"), SM_CYDRAG, TEXT("SM_CYDRAG"), TEXT("Avoid drag y tolerance"), SM_SHOWSOUNDS, TEXT("SM_SHOWSOUNDS"), TEXT("Present sounds visually"), SM_CXMENUCHECK, TEXT("SM_CXMENUCHECK"), TEXT("Menu check-mark width"), SM_CYMENUCHECK, TEXT("SM_CYMENUCHECK"), TEXT("Menu check-mark height"), SM_SLOWMACHINE, TEXT("SM_SLOWMACHINE"), TEXT("Slow processor flag"), SM_MIDEASTENABLED, TEXT("SM_MIDEASTENABLED"), TEXT("Hebrew and Arabic enabled flag"), SM_MOUSEWHEELPRESENT, TEXT("SM_MOUSEWHEELPRESENT"), TEXT("Mouse wheel present flag"), SM_XVIRTUALSCREEN, TEXT("SM_XVIRTUALSCREEN"), TEXT("Virtual screen x origin"), SM_YVIRTUALSCREEN, TEXT("SM_YVIRTUALSCREEN"), TEXT("Virtual screen y origin"), SM_CXVIRTUALSCREEN, TEXT("SM_CXVIRTUALSCREEN"), TEXT("Virtual screen width"), SM_CYVIRTUALSCREEN, TEXT("SM_CYVIRTUALSCREEN"), TEXT("Virtual screen height"), SM_CMONITORS, TEXT("SM_CMONITORS"), TEXT("Number of monitors"), SM_SAMEDISPLAYFORMAT, TEXT("SM_SAMEDISPLAYFORMAT"), TEXT("Same color format flag") }; #endif /*_METICS_H__*/
ScrollTest.cpp
-
#include "Metrics.h" LRESULT CALLBACK pfnWndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { MSG stMsg; memset(&stMsg, 0, sizeof (stMsg)); HWND stHwnd; memset(&stHwnd, 0, sizeof (stHwnd)); WNDCLASS stWndClass; memset(&stWndClass, 0, sizeof (stWndClass)); const TCHAR szAppName[] = TEXT("SCROLL TEST"); stWndClass.style = CS_HREDRAW | CS_VREDRAW; stWndClass.lpfnWndProc = pfnWndProc; stWndClass.cbClsExtra = 0; stWndClass.cbWndExtra = 0; stWndClass.hInstance = hInstance; stWndClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); stWndClass.hCursor = LoadCursor(NULL, IDC_ARROW); stWndClass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); stWndClass.lpszMenuName = NULL; stWndClass.lpszClassName = szAppName; if (!RegisterClass(&stWndClass)) { MessageBox(NULL, TEXT("Regiester failure"), szAppName, MB_ICONERROR); return 0; } stHwnd = CreateWindow(szAppName, TEXT("SCROLL TEST"), WS_OVERLAPPEDWINDOW | WS_VSCROLL /*| WS_HSCROLL*/, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow(stHwnd, iCmdShow); UpdateWindow(stHwnd); while (GetMessage(&stMsg, NULL, 0, 0)) { TranslateMessage(&stMsg); DispatchMessage(&stMsg); } return stMsg.wParam; } LRESULT CALLBACK pfnWndProc(HWND stHwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam) { HDC stHdc; memset(&stHdc, 0, sizeof (stHdc)); PAINTSTRUCT stPs; memset(&stPs, 0, sizeof (stPs)); RECT stRect; memset(&stRect, 0, sizeof (stRect)); TEXTMETRIC stTextMetric; memset(&stTextMetric, 0, sizeof (stTextMetric)); int iYpos = 0; static int s_iCharWidth = 0; static int s_iCharHeight = 0; static int s_iClientHeight = 0; static int s_iVScrollPos = 0; static int s_iCapitalCharWidth = 0; switch (uiMsg) { case WM_CREATE: stHdc = GetDC(stHwnd);//GDI函式入口 GetTextMetrics(stHdc, &stTextMetric);//获取系统文字字元结构 s_iCharWidth = stTextMetric.tmAveCharWidth;//字元宽度 s_iCapitalCharWidth = (stTextMetric.tmPitchAndFamily & 1 ? 3 : 2) * s_iCharWidth / 2;//大字字元宽度 s_iCharHeight = stTextMetric.tmHeight + stTextMetric.tmExternalLeading;//字元高度 ReleaseDC(stHwnd, stHdc); SetScrollRange(stHwnd, SB_VERT, 0, NUMLINES - 1, FALSE); SetScrollPos(stHwnd, SB_VERT, s_iVScrollPos, TRUE); return 0; case WM_SIZE: s_iClientHeight = HIWORD(lParam); return 0; case WM_VSCROLL: switch (LOWORD(wParam)) { case SB_LINEUP: s_iVScrollPos -= 1; break; case SB_LINEDOWN: s_iVScrollPos += 1; break; case SB_PAGEUP: s_iVScrollPos -= s_iClientHeight / s_iCharHeight; break; case SB_PAGEDOWN: s_iVScrollPos += s_iClientHeight / s_iCharHeight; break; case SB_THUMBPOSITION: s_iVScrollPos = HIWORD(wParam); break; default: break; } s_iVScrollPos = max(0, min(s_iVScrollPos, NUMLINES - 1)); if (s_iVScrollPos != GetScrollPos(stHwnd, SB_VERT)) { SetScrollPos(stHwnd, SB_VERT, s_iVScrollPos, TRUE); InvalidateRect(stHwnd, NULL, TRUE); /*设置滑块新的位置,但是这里没有产生WM_PAINT的触发条件, 使用InvalidateRect强制使用显示区域无效*/ UpdateWindow(stHwnd); //如果系统任务多时,WM_PAINT消息优先级低,需要等待WM_PAINT消息响应 //UpdateWindow可以通知系统立即处理WM_PAINT消息 } return 0; case WM_PAINT: stHdc = BeginPaint(stHwnd, &stPs); for (int iNum = 0; iNum < NUMLINES; iNum++) { iYpos = s_iCharHeight * (iNum - s_iVScrollPos); TextOut(stHdc, 0, iYpos, sysmetrics[iNum].szLabel, lstrlen(sysmetrics[iNum].szLabel)); TextOut(stHdc, 40 * s_iCapitalCharWidth, iYpos, sysmetrics[iNum].szDesc, lstrlen(sysmetrics[iNum].szDesc)); } EndPaint(stHwnd, &stPs); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; default: return DefWindowProc(stHwnd, uiMsg, wParam, lParam); } }
滚动条的实现(1)
最新推荐文章于 2022-04-07 09:52:21 发布