Windows學習筆記——SYSMETS2

在SYSMETS1程序的基礎上,爲窗口添加最重要的元素之一 ——滾動條.

代碼註釋,如下:

  1. //SYSMETS2.cpp  
  2. #include<windows.h>  
  3. #include"sysmets.h"  
  4.  
  5. LRESULT CALLBACK WndProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam);  
  6.  
  7.  
  8. int APIENTRY WinMain(HINSTANCE hInstance,  
  9.                      HINSTANCE hPrevInstance,  
  10.                      PSTR     szCmdLine,  
  11.                      int       iCmdShow)  
  12. {  
  13.     static TCHAR szAppName[]=TEXT("SysMets2");  
  14.     HWND hWnd;  
  15.     MSG msg;  
  16.     WNDCLASS wndclass;  
  17.  
  18.     //填充窗口類的10個字段  
  19.     wndclass.cbClsExtra=0;  
  20.     wndclass.cbWndExtra=0;  
  21.  
  22.     wndclass.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);  
  23.  
  24.     wndclass.hCursor=LoadCursor(NULL,IDC_ARROW);  
  25.     wndclass.hIcon=LoadIcon(NULL,IDI_APPLICATION);  
  26.  
  27.     wndclass.hInstance=hInstance;  
  28.  
  29.     wndclass.lpfnWndProc=WndProc;                                 //窗口過程處理函數  
  30.     wndclass.lpszClassName=szAppName;                             //窗口類名  
  31.  
  32.     wndclass.lpszMenuName=NULL;  
  33.  
  34.     wndclass.style=CS_HREDRAW|CS_VREDRAW;  
  35.  
  36.     //註冊窗口類  
  37.     int retVal=RegisterClass(&wndclass); //失敗,返回0;成功,返回非0  
  38.     if(retVal == 0)  
  39.     {  
  40.         MessageBox(NULL,TEXT("This progrom requires Windows NT !"),szAppName,MB_ICONERROR);  
  41.         return 0;  
  42.     }  
  43.  
  44.     //創建窗口  
  45.     hWnd=CreateWindow(szAppName,  
  46.                       TEXT("Get System Metrics No.2"),  
  47.                       WS_OVERLAPPEDWINDOW | WS_VSCROLL,  
  48.                       CW_USEDEFAULT,CW_USEDEFAULT,  
  49.                       CW_USEDEFAULT,CW_USEDEFAULT,  
  50.                       NULL,NULL,hInstance,NULL);  
  51.  
  52.     ShowWindow(hWnd,iCmdShow);  
  53.     UpdateWindow(hWnd);  
  54.  
  55.     //獲取消息  
  56.     while(GetMessage(&msg,NULL,0,0))  
  57.     {  
  58.         TranslateMessage(&msg);  
  59.         DispatchMessage(&msg);  
  60.     }  
  61.                          
  62.  
  63.     return msg.wParam;  
  64. }  
  65.  
  66. LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)  
  67. {  
  68.     static int cxChar,cxCaps,cyChar,cyClient,iVscrollPos;  
  69.     HDC hdc;  
  70.     int i;  
  71.     PAINTSTRUCT ps;  
  72.     TCHAR szBuffer[10];  
  73.     TEXTMETRIC tm;  
  74.  
  75.     //消息處理  
  76.     switch(message){  
  77.       
  78.     case WM_CREATE: //CreateWindows函數時,產生該消息(通過調用API產生的消息,均是非隊列消息)  
  79.         hdc=GetDC(hWnd);  
  80.  
  81.         GetTextMetrics(hdc,&tm);  
  82.         cxChar=tm.tmAveCharWidth;  
  83.         cxCaps=(tm.tmPitchAndFamily & 1? 3:2)* cxChar/2;  
  84.         cyChar=tm.tmHeight+tm.tmExternalLeading;  
  85.  
  86.         ReleaseDC(hWnd,hdc);  
  87.  
  88.         //設置滾動條的範圍和滑塊的位置  
  89.         SetScrollRange(hWnd,SB_VERT,0,NUMLINES-1,FALSE);  
  90.         SetScrollPos(hWnd,SB_VERT,iVscrollPos,TRUE);  
  91.         return 0;  
  92.  
  93.     case WM_SIZE: //(窗口大小發生變化,產生該消息;緊接着產生WM_PAINT消息)  
  94.         cyClient=HIWORD(lParam); //lParam:低字位,表示客戶區的寬度;高字位,是高度.  
  95.         return 0;  
  96.  
  97.     case WM_VSCROLL:  
  98.         switch(LOWORD(wParam)) //wParam:低字位,表示鼠標在滾動條上的動作  
  99.         {  
  100.         case SB_LINEUP:  
  101.             iVscrollPos-=1;  
  102.             break;  
  103.         case SB_LINEDOWN:  
  104.             iVscrollPos+=1;  
  105.             break;  
  106.         case SB_PAGEUP:  
  107.             iVscrollPos-=cyClient/cyChar;  
  108.             break;  
  109.         case SB_PAGEDOWN:  
  110.             iVscrollPos+=cyClient/cyChar;  
  111.             break;  
  112.  
  113.         case SB_THUMBPOSITION:  
  114.             iVscrollPos=HIWORD(wParam); //高字位,表示表示(翻閱之後)滑塊的位置  
  115.             break;  
  116.         default:  
  117.             break;  
  118.         }  
  119.  
  120.         //如果滑塊位置改變,重設爲iVscrollPos  
  121.         iVscrollPos=max(0,min(iVscrollPos,NUMLINES-1));  
  122.         if(GetScrollPos(hWnd,SB_VERT) != iVscrollPos)  
  123.         {  
  124.             SetScrollPos(hWnd,SB_VERT,iVscrollPos,TRUE);  
  125.             InvalidateRect(hWnd,NULL,TRUE);  
  126.         }  
  127.         return 0;  
  128.  
  129.  
  130.     case WM_PAINT:  
  131.         hdc=BeginPaint(hWnd,&ps);  
  132.           
  133.           
  134.         for(i=0;i<NUMLINES;i++)  
  135.         {  
  136.             TextOut(hdc,0,cyChar*(i-iVscrollPos),sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));  
  137.             TextOut(hdc,22*cxCaps,cyChar*(i-iVscrollPos),sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));  
  138.  
  139.             SetTextAlign(hdc,TA_LEFT|TA_TOP);  
  140.             TextOut(hdc,  
  141.                     22*cxCaps+40*cxChar,cyChar*(i-iVscrollPos),  
  142.                     szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics(sysmetrics[i].iIndex)));  
  143.             SetTextAlign(hdc,TA_LEFT|TA_TOP);  
  144.         }  
  145.  
  146.         EndPaint(hWnd,&ps);  
  147.         return 0;  
  148.  
  149.     case WM_DESTROY:  
  150.         PostQuitMessage(0);  
  151.         return 0;  
  152.     }  
  153.  
  154.     return DefWindowProc(hWnd,message,wParam,lParam);  
  155. }  

 

 

函數原型:

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 //滑塊的位置,每次更新後必須重繪

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章