在SYSMETS1程序的基礎上,爲窗口添加最重要的元素之一 ——滾動條.
代碼註釋,如下:
- //SYSMETS2.cpp
- #include<windows.h>
- #include"sysmets.h"
- LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);
- int APIENTRY WinMain(HINSTANCE hInstance,
- HINSTANCE hPrevInstance,
- PSTR szCmdLine,
- int iCmdShow)
- {
- static TCHAR szAppName[]=TEXT("SysMets2");
- HWND hWnd;
- MSG msg;
- WNDCLASS wndclass;
- //填充窗口類的10個字段
- wndclass.cbClsExtra=0;
- wndclass.cbWndExtra=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;
- wndclass.style=CS_HREDRAW|CS_VREDRAW;
- //註冊窗口類
- int retVal=RegisterClass(&wndclass); //失敗,返回0;成功,返回非0
- if(retVal == 0)
- {
- MessageBox(NULL,TEXT("This progrom 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;
- HDC hdc;
- int i;
- PAINTSTRUCT ps;
- TCHAR szBuffer[10];
- TEXTMETRIC tm;
- //消息處理
- switch(message){
- case WM_CREATE: //CreateWindows函數時,產生該消息(通過調用API產生的消息,均是非隊列消息)
- 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);
- SetScrollPos(hWnd,SB_VERT,iVscrollPos,TRUE);
- return 0;
- case WM_SIZE: //(窗口大小發生變化,產生該消息;緊接着產生WM_PAINT消息)
- cyClient=HIWORD(lParam); //lParam:低字位,表示客戶區的寬度;高字位,是高度.
- return 0;
- case WM_VSCROLL:
- switch(LOWORD(wParam)) //wParam:低字位,表示鼠標在滾動條上的動作
- {
- case SB_LINEUP:
- 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); //高字位,表示表示(翻閱之後)滑塊的位置
- break;
- default:
- break;
- }
- //如果滑塊位置改變,重設爲iVscrollPos
- iVscrollPos=max(0,min(iVscrollPos,NUMLINES-1));
- if(GetScrollPos(hWnd,SB_VERT) != iVscrollPos)
- {
- SetScrollPos(hWnd,SB_VERT,iVscrollPos,TRUE);
- InvalidateRect(hWnd,NULL,TRUE);
- }
- return 0;
- case WM_PAINT:
- hdc=BeginPaint(hWnd,&ps);
- for(i=0;i<NUMLINES;i++)
- {
- TextOut(hdc,0,cyChar*(i-iVscrollPos),sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));
- TextOut(hdc,22*cxCaps,cyChar*(i-iVscrollPos),sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));
- SetTextAlign(hdc,TA_LEFT|TA_TOP);
- TextOut(hdc,
- 22*cxCaps+40*cxChar,cyChar*(i-iVscrollPos),
- 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);
- }
函數原型:
1.
ATOM RegisterClass( const WNDCLASS* lpWndClass );
typedef WORD ATOM;
typedef unsigned short WORD;
2.
BOOL InvalidateRect( HWND hWnd, const RECT* lpRect, BOOL bErase );
const RECT* lpRect, //爲NULL,表示整個客戶區爲更新區域
BOOL bErase //如果爲TRUE,擦除背景顏色;否則,不擦除.
3.
BOOL SetScrollRange( HWND hWnd, int nBar, int nMinPos, int nMaxPos, BOOL bRedraw );
int nBar, //SB_VERT | SB_HORZ
BOOL bRedraw //一般情況下,滾動條的範圍不需要重繪
int SetScrollPos( HWND hWnd, int nBar, int nPos, BOOL bRedraw );
BOOL bRedraw //滑塊的位置,每次更新後必須重繪