下面的代码是来自于书上的,我那就按照自己的理解给下面的代码来一个自己的成果总结。
下面是一个头文件sysmets.h
/*-----------------------------------------------
SYSMETS.H -- System metrics display structure
-----------------------------------------------*/
#define NUMLINES ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))
struct
{
int iIndex ;
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"),
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 dragable width"),
SM_CYMAXTRACK, TEXT ("SM_CYMAXTRACK"),
TEXT ("Maximum dragable 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")
} ;
下面是源码
/*----------------------------------------------------
SYSMETS4.C -- System Metrics Display Program No. 4
(c) Charles Petzold, 1998
----------------------------------------------------*/
#define WINVER 0x0500
#include <windows.h>
#include "sysmets.h"
LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);//回调函数的声明
int WINAPI WinMain(HINSTANCE hInstance,//当前实例句柄
HINSTANCE hPrevInstance,//先前实例句柄
LPSTR szCmdLine,//命令行
int iCmdShow)//显示状态
{
static TCHAR szAppName[]=TEXT("Sysmets4");
HWND hwnd;//当前实例的句炳
MSG msg;//消息
WNDCLASS wndclass;//窗口类名
wndclass.style=CS_HREDRAW | CS_VREDRAW;//窗口风格,分别为水平重画和竖直重画
wndclass.cbClsExtra=0;//窗口扩展,一般为0
wndclass.cbWndExtra=0;//窗口实例扩展,一般为0
wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);//窗口背景颜色,此处为白色
wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);//窗口图标
wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);//窗口鼠标光标
wndclass.hInstance=hInstance;//实例句柄
wndclass.lpfnWndProc=WndProc;//回调函数
wndclass.lpszClassName=szAppName;//窗口类的名字
wndclass.lpszMenuName=NULL;//菜单名,此处没有
if(!RegisterClass(&wndclass))//注册窗口
{
MessageBox(NULL,TEXT("Program requires Windows NT!"),
szAppName,MB_ICONERROR);
return 0;
}
hwnd=CreateWindow(szAppName,TEXT("Get System Metrics No.4"),//创建窗口
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
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,cyChar,cxCaps,cxClient,cyClient,iMaxWidth;
HDC hdc;
int i,x,y,iVertPos,iHorzPos,iPaintBeg,iPaintEnd;
PAINTSTRUCT ps;//绘图结构
SCROLLINFO si;//滚动条结构
TCHAR szBuffer[10];//字符串
TEXTMETRIC tm;//字体信息结构
switch(message)
{
case WM_CREATE:
hdc=GetDC(hwnd);
GetTextMetrics(hdc,&tm);//获取系统字体信息,用tm来保存
cxChar=tm.tmAveCharWidth;//平均字符的宽度
cyChar=tm.tmHeight+tm.tmExternalLeading;//字符总高度=字符平均高度+字符间距
cxCaps=(tm.tmPitchAndFamily&1?3:2)*cxChar/2;//大写字符的平均宽度
ReleaseDC(hwnd,hdc);//获取环境信息之后,释放句柄
iMaxWidth=40*cxChar+22*cxCaps;//窗口总宽度
return 0;
case WM_SIZE:
cxClient=LOWORD(lParam);//窗口宽度
cyClient=HIWORD(lParam);//窗口高度
si.cbSize=sizeof(si);
si.fMask=SIF_RANGE | SIF_PAGE;
si.nMax=NUMLINES-1;
si.nMin=0;
si.nPage=cyClient/cyChar;
SetScrollInfo(hwnd,SB_VERT,&si,TRUE);//修改竖直滚动条的信息
si.cbSize=sizeof(si);
si.fMask=SIF_RANGE | SIF_PAGE;
si.nMin=0;
si.nMax=2+iMaxWidth / cxChar;
si.nPage=cxClient/cxChar;
SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);//修改水平滚动条的信息
return 0;
case WM_VSCROLL:
si.cbSize=sizeof(si);
si.fMask=SIF_ALL;
GetScrollInfo(hwnd,SB_VERT,&si);//获取竖直滚动条的消息
iVertPos=si.nPos;
switch(LOWORD(wParam))
{
case SB_TOP:
si.nPos=si.nMin;
break;
case SB_BOTTOM:
si.nPos=si.nMax;
break;
case SB_LINEUP:
si.nPos-=1;
break;
case SB_LINEDOWN:
si.nPos+=1;
break;
case SB_PAGEUP:
si.nPos-=si.nPage;
break;
case SB_PAGEDOWN:
si.nPos+=si.nPage;
case SB_THUMBTRACK:
si.nPos=si.nTrackPos;
break;
default:
break;
}
si.fMask=SIF_POS;
SetScrollInfo(hwnd,SB_VERT,&si,TRUE);//重新修改操作之后的竖直滚动条的信息
GetScrollInfo(hwnd,SB_VERT,&si);//获取改动后的信息
if(si.nPos!=iVertPos)
{
ScrollWindow(hwnd,0,cyChar*(iVertPos-si.nPos),NULL,NULL);
UpdateWindow(hwnd);
}
return 0;
case WM_HSCROLL:
si.cbSize=sizeof(si);
si.fMask=SIF_ALL;
GetScrollInfo(hwnd,SB_HORZ,&si);//获取水平滚动条的信息
iHorzPos=si.nPos;
switch(LOWORD(wParam))
{
case SB_LINELEFT:
si.nPos-=1;
break;
case SB_LINERIGHT:
si.nPos+=1;
break;
case SB_PAGELEFT:
si.nPos-=si.nPage;
break;
case SB_PAGERIGHT:
si.nPos+=si.nPage;
break;
case SB_THUMBPOSITION:
si.nPos=si.nTrackPos;
break;
default:
break;
}
si.fMask=SIF_POS;
SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);//修改操作后的水平滚动条的信息
GetScrollInfo(hwnd,SB_HORZ,&si);//获取改动后的消息
if(si.nPos!=iHorzPos)
{
ScrollWindow(hwnd,cxChar*(iHorzPos-si.nPos),0,NULL,NULL);
}
return 0;
case WM_KEYDOWN://按键操作,把按键的信息通过SendMessage函数传递给滚动条,进而操纵滚动条
switch(wParam)
{
case VK_HOME:
SendMessage(hwnd,WM_VSCROLL,SB_TOP,0);
break;
case VK_END:
SendMessage(hwnd,WM_VSCROLL,SB_BOTTOM,0);
break;
case VK_PRIOR:
SendMessage(hwnd,WM_VSCROLL,SB_PAGEUP,0);
break;
case VK_NEXT:
SendMessage(hwnd,WM_VSCROLL,SB_PAGEDOWN,0);
break;
case VK_UP:
SendMessage(hwnd,WM_VSCROLL,SB_LINEUP,0);
break;
case VK_DOWN:
SendMessage(hwnd,WM_VSCROLL,SB_LINEDOWN,0);
break;
case VK_LEFT:
SendMessage(hwnd,WM_HSCROLL,SB_PAGEUP,0);
break;
case VK_RIGHT:
SendMessage(hwnd,WM_HSCROLL,SB_PAGERIGHT,0);
break;
}
return 0;
case WM_PAINT://绘制窗口
hdc=BeginPaint(hwnd,&ps);
si.cbSize=sizeof(si);
si.fMask=SIF_POS;
GetScrollInfo(hwnd,SB_VERT,&si);
iVertPos=si.nPos;
GetScrollInfo(hwnd,SB_HORZ,&si);
iHorzPos=si.nPos;
iPaintBeg = max (0, iVertPos + ps.rcPaint.top / cyChar) ;//max(0,当前位置+需要绘图的矩形区的最高点/字符的高度)
iPaintEnd = min (NUMLINES - 1,
iVertPos + ps.rcPaint.bottom / cyChar) ;//绘图结束的地方 = 当前位置+绘制去取的高度
for (i = iPaintBeg ; i <= iPaintEnd ; i++)
{
x = cxChar * (1 - iHorzPos) ;
y = cyChar * (i - iVertPos) ;
TextOut (hdc, x, y,
sysmetrics[i].szLabel,
lstrlen (sysmetrics[i].szLabel)) ;
TextOut (hdc, x + 22 * cxCaps, y,
sysmetrics[i].szDesc,
lstrlen (sysmetrics[i].szDesc)) ;
SetTextAlign (hdc, TA_RIGHT | TA_TOP) ;
TextOut (hdc, x + 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);
}