Windows 程序设计 第四章 sysmets2
2012-09-28 19:45
363 查看
/*---------------------------------------------------- SYSMETS2.C -- System Metrics Display Program No. 2 (c) Charles Petzold, 1998 ----------------------------------------------------*/ /* 第一次编译的时候出现下面的提示,后来就没有出现了 --------------------Configuration: chap04sysmets2 - Win32 Debug-------------------- Compiling... sysmets2.c NOTE: WINVER has been defined as 0x0500 or greater which enables Windows NT 5.0 and Windows 98 features. When these headers were released, Windows NT 5.0 beta 1 and Windows 98 beta 2.1 were the current versions. For this release when WINVER is defined as 0x0500 or greater, you can only build beta or test applications. To build a retail application, set WINVER to 0x0400 or visit http://www.microsoft.com/msdn/sdk to see if retail Windows NT 5.0 or Windows 98 headers are available. See the SDK release notes for more information. sysmets2.obj - 0 error(s), 0 warning(s) */ // #define WINVER 0x0500 #define WINVER 0x0501 #include <windows.h> #include "sysmets.h" LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ; int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT ("SysMets2") ; HWND hwnd ; MSG msg ; WNDCLASS 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 ; if (!RegisterClass (&wndclass)) { MessageBox (NULL, TEXT ("This program requires Windows NT!"), szAppName, MB_ICONERROR) ; return 0 ; } hwnd = CreateWindow (szAppName, TEXT ("Get System Metrics No. 2"), WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL) ; ShowWindow (hwnd, iCmdShow) ; UpdateWindow (hwnd) ; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage (&msg) ; DispatchMessage (&msg) ; } return msg.wParam ; } LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static int cxChar, cxCaps, cyChar, cyClient, iVscrollPos /*=1 */ ; HDC hdc ; int i, y ; PAINTSTRUCT ps ; TCHAR szBuffer[10] ; TEXTMETRIC tm ; switch (message) { case WM_CREATE: hdc = GetDC (hwnd) ; GetTextMetrics (hdc, &tm) ; cxChar = tm.tmAveCharWidth ; cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ; cyChar = tm.tmHeight + tm.tmExternalLeading ; ReleaseDC (hwnd, hdc) ; SetScrollRange (hwnd, SB_VERT, 0, NUMLINES - 1, FALSE) ; // 设置滚动条的范围 0 -- NUMLINES - 1 SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ; // 设置(更新) 滚动条的位置, 在创建窗口是iVscrollPos=0 即滑块在最上顶上 return 0 ; case WM_SIZE: cyClient = HIWORD (lParam) ; // 在WM_SIZE消息中, lParam的低位字 是客户区的宽度,高字位是高度 cyClient 高度 return 0 ; case WM_VSCROLL: switch (LOWORD (wParam)) // 在WM_VSCROLL 消息中,wParam的低位字是鼠标在滚动条上的动作,这个值是通知码,有SB_开头 { case SB_LINEUP: // 鼠标点击滚动条最上的那个三角箭 ,点击一下,iVscrollPos 减一. iVscrollPos -= 1 ; break ; case SB_LINEDOWN: iVscrollPos += 1 ; break ; case SB_PAGEUP: // 鼠标点击 滚动条和三角箭的之间的空白位置,发生翻页的 消息. iVscrollPos -= cyClient / cyChar ; break ; case SB_PAGEDOWN: iVscrollPos += cyClient / cyChar ; break ; case SB_THUMBPOSITION: // 鼠标松开 iVscrollPos = HIWORD (wParam) ;// 对于SB_THUMBPOSITION而言, wParam的高位字是滑块的位置 break ; default : break ; } iVscrollPos = max (0, min (iVscrollPos, NUMLINES - 1)) ; // 限定iVscrolPos 在0到NUMLINES - 1 取值范围内 if (iVscrollPos != GetScrollPos (hwnd, SB_VERT)) // 如果iVscrollPos的值变了,则更新其位置,并设置 窗口无效 { SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ; InvalidateRect (hwnd, NULL, TRUE) ; // 客户区无效,则产生 WM_PAINT 消息,TRUE 使其后调用的BeginPaint擦除原有的背景. } return 0 ; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; for (i = 0 ; i < NUMLINES ; i++) { // y是每一行的坐标,为负数时该行文字实际输出到客户区的外面了 // 大于0时,才是输出到 客户区 ,即 i > iVscrollPos时,也就是那些行数位于滑块的下面部分才输出更新吗? // 假设滑块是向下拉,实际是原来滑块下面的内容在上升,就是这部分需要重绘 ? /* 测试了发现: 如果滑块在最底下,即iVscrollPos = NUMLINES-1, 在for循环中,i取0到NUMLINES-2时,y都为负数,客户区没有输出,当 i = NUMLINES-1时, y= 0,此刻y对应客户区的第一行,显示的内容对应是sysmetrics[i] 即 sysmetrics的最后一行. */ y = cyChar * (i - iVscrollPos) ; TextOut (hdc, 0, y, sysmetrics[i].szLabel, lstrlen (sysmetrics[i].szLabel)) ; TextOut (hdc, 22 * cxCaps, y, sysmetrics[i].szDesc, lstrlen (sysmetrics[i].szDesc)) ; SetTextAlign (hdc, TA_RIGHT | TA_TOP) ; TextOut (hdc, 22 * cxCaps + 40 * cxChar, y, szBuffer, wsprintf (szBuffer, TEXT ("%5d"), GetSystemMetrics (sysmetrics[i].iIndex))) ; SetTextAlign (hdc, TA_LEFT | TA_TOP) ; } EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
如果iVscrollPos初始化为1 则创建窗口时滑块的位置如下:
-----
//-------------------------------
//--- 如果把滑块拉到底,则显示的是 原库文件中 最后一行(最后一个元素).....如下图:
-----
相关文章推荐
- Windows程序设计第四章总结
- 第四章 WINDOWS绘图程序设计
- 第四章 时钟 windows程序设计 王艳平版
- windows程序设计第四章 输出文字
- windows程序设计第四章sysmets3程序详解
- Windows环境下32位汇编程序设计C版code--第四章
- MFC Windows 程序设计 第四章 菜单
- windows程序设计:第四章(1):文本输出
- windows程序设计-第四章 system1.c
- [学习笔记]Windows程序设计:第四章 文本输出
- 《Windows程序设计-第二版》第四章最后一个04Clock大例子中的GDI句柄泄漏问题
- 第四章 简单的打字程序 windows程序设计 王艳平版
- Windows程序设计——第四章《输出文字》要点摘要
- windows程序设计第五版 第四章SYSMETS3.C 示例分析(自己的笔记)
- 第四章 查找记事本程序的窗口句柄 windows程序设计 王艳平版
- 第四章 绘图 windows程序设计 王艳平版
- windows程序设计-第四章 system2.c 新增滚动条功能
- 第四章定时器 windows程序设计王艳平版
- Windows 程序设计 第四章 sysmets1
- 【Windows程序设计】获取窗口的各种尺寸