一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

windows程序設(shè)計(jì)(5)使用滾動(dòng)條

 fisher60 2013-06-22

本文的程序來(lái)自《windows程序設(shè)計(jì)(第五版)》

設(shè)計(jì)滾動(dòng)條的初衷,是因?yàn)榭蛻?hù)區(qū)需要顯示的東西太多了,在這個(gè)頭文件中,我們包含了一大堆的系統(tǒng)的信息:

  1. //總行數(shù)  
  2. #define NUMLINES  ((int) (sizeof sysmetrics / sizeof sysmetrics [0]))  
  3.   
  4. struct  
  5. {  
  6.     int Index ;  
  7.     TCHAR* szLabel;  
  8.     TCHAR* szDesc ;  
  9.   
  10. }  
  11. //結(jié)構(gòu)體數(shù)組  
  12. sysmetrics [] =  
  13.           
  14. {  
  15.           
  16.     SM_CXSCREEN,            TEXT ("SM_CXSCREEN"),           TEXT ("Screen width in pixels"),          
  17.     SM_CYSCREEN,            TEXT ("SM_CYSCREEN"),           TEXT ("Screen height in pixels"),         
  18.     SM_CXVSCROLL,           TEXT ("SM_CXVSCROLL"),          TEXT ("Vertical scroll width"),          
  19.     SM_CYHSCROLL,           TEXT ("SM_CYHSCROLL"),          TEXT ("Horizontal scroll height"),          
  20.     SM_CYCAPTION,           TEXT ("SM_CYCAPTION"),          TEXT ("Caption bar height"),          
  21.     SM_CXBORDER,            TEXT ("SM_CXBORDER"),           TEXT ("Window border width"),          
  22.     SM_CYBORDER,            TEXT ("SM_CYBORDER"),           TEXT ("Window border height"),          
  23.     SM_CXFIXEDFRAME,        TEXT ("SM_CXFIXEDFRAME"),       TEXT ("Dialog window frame width"),          
  24.     SM_CYFIXEDFRAME,        TEXT ("SM_CYFIXEDFRAME"),       TEXT ("Dialog window frame height"),          
  25.     SM_CYVTHUMB,            TEXT ("SM_CYVTHUMB"),           TEXT ("Vertical scroll thumb height"),          
  26.     SM_CXHTHUMB,            TEXT ("SM_CXHTHUMB"),           TEXT ("Horizontal scroll thumb width"),          
  27.     SM_CXICON,              TEXT ("SM_CXICON"),             TEXT ("Icon width"),          
  28.     SM_CYICON,              TEXT ("SM_CYICON"),             TEXT ("Icon height"),          
  29.     SM_CXCURSOR,            TEXT ("SM_CXCURSOR"),           TEXT ("Cursor width"),          
  30.     SM_CYCURSOR,            TEXT ("SM_CYCURSOR"),           TEXT ("Cursor height"),          
  31.     SM_CYMENU,              TEXT ("SM_CYMENU"),             TEXT ("Menu bar height"),          
  32.     SM_CXFULLSCREEN,        TEXT ("SM_CXFULLSCREEN"),       TEXT ("Full screen client area width"),          
  33.     SM_CYFULLSCREEN,        TEXT ("SM_CYFULLSCREEN"),       TEXT ("Full screen client area height"),          
  34.     SM_CYKANJIWINDOW,       TEXT ("SM_CYKANJIWINDOW"),      TEXT ("Kanji window height"),          
  35.     SM_MOUSEPRESENT,        TEXT ("SM_MOUSEPRESENT"),       TEXT ("Mouse present flag"),          
  36.     SM_CYVSCROLL,           TEXT ("SM_CYVSCROLL"),          TEXT ("Vertical scroll arrow height"),          
  37.     SM_CXHSCROLL,           TEXT ("SM_CXHSCROLL"),          TEXT ("Horizontal scroll arrow width"),          
  38.     SM_DEBUG,               TEXT ("SM_DEBUG"),              TEXT ("Debug version flag"),          
  39.     SM_SWAPBUTTON,          TEXT ("SM_SWAPBUTTON"),         TEXT ("Mouse buttons swapped flag"),          
  40.     SM_CXMIN,               TEXT ("SM_CXMIN"),              TEXT ("Minimum window width"),          
  41.     SM_CYMIN,               TEXT ("SM_CYMIN"),              TEXT ("Minimum window height"),          
  42.     SM_CXSIZE,              TEXT ("SM_CXSIZE"),             TEXT ("Min/Max/Close button width"),          
  43.     SM_CYSIZE,              TEXT ("SM_CYSIZE"),             TEXT ("Min/Max/Close button height"),          
  44.     SM_CXSIZEFRAME,         TEXT ("SM_CXSIZEFRAME"),        TEXT ("Window sizing frame width"),          
  45.     SM_CYSIZEFRAME,         TEXT ("SM_CYSIZEFRAME"),        TEXT ("Window sizing frame height"),          
  46.     SM_CXMINTRACK,          TEXT ("SM_CXMINTRACK"),         TEXT ("Minimum window tracking width"),          
  47.     SM_CYMINTRACK,          TEXT ("SM_CYMINTRACK"),         TEXT ("Minimum window tracking height"),          
  48.     SM_CXDOUBLECLK,         TEXT ("SM_CXDOUBLECLK"),        TEXT ("Double click x tolerance"),          
  49.     SM_CYDOUBLECLK,         TEXT ("SM_CYDOUBLECLK"),        TEXT ("Double click y tolerance"),          
  50.     SM_CXICONSPACING,       TEXT ("SM_CXICONSPACING"),      TEXT ("Horizontal icon spacing"),          
  51.     SM_CYICONSPACING,       TEXT ("SM_CYICONSPACING"),      TEXT ("Vertical icon spacing"),          
  52.     SM_MENUDROPALIGNMENT,   TEXT ("SM_MENUDROPALIGNMENT"),  TEXT ("Left or right menu drop"),          
  53.     SM_PENWINDOWS,          TEXT ("SM_PENWINDOWS"),         TEXT ("Pen extensions installed"),          
  54.     SM_DBCSENABLED,         TEXT ("SM_DBCSENABLED"),        TEXT ("Double-Byte Char Set enabled"),          
  55.     SM_CMOUSEBUTTONS,       TEXT ("SM_CMOUSEBUTTONS"),      TEXT ("Number of mouse buttons"),         
  56.     SM_SECURE,              TEXT ("SM_SECURE"),             TEXT ("Security present flag"),          
  57.     SM_CXEDGE,              TEXT ("SM_CXEDGE"),             TEXT ("3-D border width"),          
  58.     SM_CYEDGE,              TEXT ("SM_CYEDGE"),             TEXT ("3-D border height"),          
  59.     SM_CXMINSPACING,        TEXT ("SM_CXMINSPACING"),       TEXT ("Minimized window spacing width"),          
  60.     SM_CYMINSPACING,        TEXT ("SM_CYMINSPACING"),       TEXT ("Minimized window spacing height"),          
  61.     SM_CXSMICON,            TEXT ("SM_CXSMICON"),           TEXT ("Small icon width"),         
  62.     SM_CYSMICON,            TEXT ("SM_CYSMICON"),           TEXT ("Small icon height"),          
  63.     SM_CYSMCAPTION,         TEXT ("SM_CYSMCAPTION"),        TEXT ("Small caption height"),          
  64.     SM_CXSMSIZE,            TEXT ("SM_CXSMSIZE"),           TEXT ("Small caption button width"),          
  65.     SM_CYSMSIZE,            TEXT ("SM_CYSMSIZE"),           TEXT ("Small caption button height"),          
  66.     SM_CXMENUSIZE,          TEXT ("SM_CXMENUSIZE"),         TEXT ("Menu bar button width"),          
  67.     SM_CYMENUSIZE,          TEXT ("SM_CYMENUSIZE"),         TEXT ("Menu bar button height"),          
  68.     SM_ARRANGE,             TEXT ("SM_ARRANGE"),            TEXT ("How minimized windows arranged"),          
  69.     SM_CXMINIMIZED,         TEXT ("SM_CXMINIMIZED"),        TEXT ("Minimized window width"),          
  70.     SM_CYMINIMIZED,         TEXT ("SM_CYMINIMIZED"),        TEXT ("Minimized window height"),          
  71.     SM_CXMAXTRACK,          TEXT ("SM_CXMAXTRACK"),         TEXT ("Maximum draggable width"),          
  72.     SM_CYMAXTRACK,          TEXT ("SM_CYMAXTRACK"),         TEXT ("Maximum draggable height"),          
  73.     SM_CXMAXIMIZED,         TEXT ("SM_CXMAXIMIZED"),        TEXT ("Width of maximized window"),          
  74.     SM_CYMAXIMIZED,         TEXT ("SM_CYMAXIMIZED"),        TEXT ("Height of maximized window"),          
  75.     SM_NETWORK,             TEXT ("SM_NETWORK"),            TEXT ("Network present flag"),          
  76.     SM_CLEANBOOT,           TEXT ("SM_CLEANBOOT"),          TEXT ("How system was booted"),          
  77.     SM_CXDRAG,              TEXT ("SM_CXDRAG"),             TEXT ("Avoid drag x tolerance"),          
  78.     SM_CYDRAG,              TEXT ("SM_CYDRAG"),             TEXT ("Avoid drag y tolerance"),          
  79.     SM_SHOWSOUNDS,          TEXT ("SM_SHOWSOUNDS"),         TEXT ("Present sounds visually"),          
  80.     SM_CXMENUCHECK,         TEXT ("SM_CXMENUCHECK"),        TEXT ("Menu check-mark width"),          
  81.     SM_CYMENUCHECK,         TEXT ("SM_CYMENUCHECK"),        TEXT ("Menu check-mark height"),          
  82.     SM_SLOWMACHINE,         TEXT ("SM_SLOWMACHINE"),        TEXT ("Slow processor flag"),          
  83.     SM_MIDEASTENABLED,      TEXT ("SM_MIDEASTENABLED"),     TEXT ("Hebrew and Arabic enabled flag"),          
  84.     SM_MOUSEWHEELPRESENT,   TEXT ("SM_MOUSEWHEELPRESENT"),  TEXT ("Mouse wheel present flag"),          
  85.     SM_XVIRTUALSCREEN,      TEXT ("SM_XVIRTUALSCREEN"),     TEXT ("Virtual screen x origin"),          
  86.     SM_YVIRTUALSCREEN,      TEXT ("SM_YVIRTUALSCREEN"),     TEXT ("Virtual screen y origin"),          
  87.     SM_CXVIRTUALSCREEN,     TEXT ("SM_CXVIRTUALSCREEN"),    TEXT ("Virtual screen width"),          
  88.     SM_CYVIRTUALSCREEN,     TEXT ("SM_CYVIRTUALSCREEN"),    TEXT ("Virtual screen height"),          
  89.     SM_CMONITORS,           TEXT ("SM_CMONITORS"),          TEXT ("Number of monitors"),          
  90.     SM_SAMEDISPLAYFORMAT,   TEXT ("SM_SAMEDISPLAYFORMAT"),  TEXT ("Same color format flag")  
  91.           
  92. } ;  


第一行定義的,是數(shù)組有多少個(gè)元素。之后我們定義了結(jié)構(gòu)體數(shù)組。元素個(gè)數(shù)很多,一行顯示不下,那么如何添加滾動(dòng)條呢?

我們先看程序:

 
  1. #include <windows.h>  
  2. #include "sysmets.h"  
  3.   
  4. LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);  
  5.   
  6. int WINAPI WinMain(HINSTANCE hInstance,     //當(dāng)前實(shí)例句柄  
  7.                    HINSTANCE hPrevInstance, //先前實(shí)例句柄  
  8.                    LPSTR lpCmdLine,         //命令行  
  9.                    int iCmdShow)            //顯示狀態(tài)  
  10. {  
  11.     static TCHAR szAppName[] = TEXT("顯示系統(tǒng)內(nèi)容");  
  12.     //窗口句柄  
  13.     HWND hwnd;  
  14.     //消息  
  15.     MSG msg;  
  16.     //窗口類(lèi)  
  17.     WNDCLASS wndclass;  
  18.     //窗口風(fēng)格:當(dāng)移動(dòng)窗口或者改變大小時(shí)重繪窗口  
  19.     wndclass.style         =  CS_HREDRAW | CS_VREDRAW;  
  20.     //指明回調(diào)函數(shù)  
  21.     wndclass.lpfnWndProc   = WndProc;  
  22.     //額外的比特用來(lái)確認(rèn)下一個(gè)窗口類(lèi)的位置,暫時(shí)不用  
  23.     wndclass.cbClsExtra    = 0;  
  24.     //額外的比特用來(lái)確認(rèn)下一個(gè)窗口實(shí)例的位置,暫時(shí)不用  
  25.     wndclass.cbWndExtra    = 0;  
  26.     //實(shí)例句柄  
  27.     wndclass.hInstance     = hInstance;  
  28.     //裝載圖標(biāo)  
  29.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);  
  30.     //裝載光標(biāo)  
  31.     wndclass.hCursor       = LoadCursor(NULL,IDC_ARROW);  
  32.     //背景為白色  
  33.     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);  
  34.     //菜單:暫時(shí)沒(méi)有  
  35.     wndclass.lpszMenuName  = NULL;  
  36.     //窗口類(lèi)名  
  37.     wndclass.lpszClassName = szAppName;  
  38.   
  39.     //注冊(cè)窗口  
  40.     if(!RegisterClass(&wndclass))  
  41.     {  
  42.         return -1;  
  43.     }  
  44.   
  45.     //創(chuàng)建窗口  
  46.     hwnd = CreateWindow(szAppName,              //窗口類(lèi)的名稱(chēng),必須是已經(jīng)注冊(cè)的  
  47.                         TEXT("系統(tǒng)內(nèi)容"),       //窗口標(biāo)題  
  48.                         WS_OVERLAPPEDWINDOW | WS_VSCROLL,   //窗口風(fēng)格,加入垂直滾動(dòng)條  
  49.                         CW_USEDEFAULT,          //X坐標(biāo)  
  50.                         CW_USEDEFAULT,          //Y坐標(biāo)  
  51.                         CW_USEDEFAULT,          //寬度  
  52.                         CW_USEDEFAULT,          //高度  
  53.                         NULL,                   //父窗口句柄  
  54.                         NULL,                   //菜單窗口句柄  
  55.                         hInstance,              //高級(jí)版本的windos忽略  
  56.                         NULL);                    
  57.   
  58.     //顯示窗口  
  59.     //ShowWindow(hwnd,SW_SHOWNA);  
  60.     ShowWindow (hwnd, iCmdShow);  
  61.   
  62.     //更新窗口  
  63.     UpdateWindow(hwnd);  
  64.   
  65.     //消息循環(huán)  
  66.     while(GetMessage(&msg,NULL,0,0))  
  67.     {  
  68.           
  69.         TranslateMessage(&msg);  
  70.         //將消息給窗口  
  71.         DispatchMessage(&msg);  
  72.   
  73.     }  
  74.   
  75.     return msg.wParam;  
  76.   
  77. }  
  78.   
  79. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  80. {  
  81.     //字符的寬度,大寫(xiě)字母寬度,字符高度  
  82.     static int    cxChar, cxCaps, cyChar ;  
  83.     //窗口大小  
  84.     static int cxClient, cyClient ;  
  85.     //滾動(dòng)條位置  
  86.     static int iVscrollPos;   
  87.     HDC hdc;  
  88.     //該變量用于索引sysmets.h中定義的結(jié)構(gòu)體數(shù)組sysmetrics[]的每個(gè)元素  
  89.     int i;  
  90.     //輸出文本的垂直位置  
  91.     int y;  
  92.     //繪圖結(jié)構(gòu)  
  93.     PAINTSTRUCT ps;  
  94.     //字符串  
  95.     TCHAR szBuffer [10];  
  96.     //字體信息結(jié)構(gòu)  
  97.     TEXTMETRIC  tm;  
  98.     switch(message)  
  99.     {  
  100.     case WM_CREATE:  
  101.         hdc = GetDC(hwnd);  
  102.         //取得內(nèi)定系統(tǒng)字體的文字大小,存在放在tm里  
  103.         GetTextMetrics (hdc, &tm);  
  104.         //平均字符寬  
  105.         cxChar = tm.tmAveCharWidth ;  
  106.         //大寫(xiě)字母的平平均寬度  
  107.         cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;  
  108.         //字符總高度:高度+行間距  
  109.         cyChar = tm.tmHeight + tm.tmExternalLeading ;  
  110.   
  111.         ReleaseDC(hwnd,hdc);  
  112.   
  113.         //設(shè)置滾動(dòng)條范圍:參數(shù)為:窗口句柄,滾動(dòng)條類(lèi)型,最小位置,最大位置,是否重繪  
  114.         SetScrollRange (hwnd, SB_VERT, 0, NUMLINES - 1, FALSE);  
  115.         //滾動(dòng)條的方塊的位置,參數(shù)為:窗口句柄,滾動(dòng)條類(lèi)型,新的位置  
  116.         SetScrollPos   (hwnd, SB_VERT, iVscrollPos, TRUE);   
  117.           
  118.         return 0;  
  119.     case WM_SIZE:         
  120.         cxClient = LOWORD (lParam) ;          
  121.         cyClient = HIWORD (lParam) ;         
  122.         return 0;   
  123.     case WM_PAINT:  
  124.         hdc = BeginPaint (hwnd, &ps) ;  
  125.         for(i = 0;i < NUMLINES;i++ )  
  126.         {  
  127.               
  128.             //行寬度*變動(dòng)的行數(shù)  
  129.             y =  cyChar * (i - iVscrollPos) ;  
  130.             //輸出字符串到指定的區(qū)域(使用當(dāng)前的字體,背景顏色,顏色)  
  131.             //參數(shù)為:設(shè)備內(nèi)容句柄,x坐標(biāo),y坐標(biāo),帶輸出的字符串(與是否/0結(jié)尾無(wú)關(guān)),字符的個(gè)數(shù)  
  132.             //lstrlen計(jì)算字符串長(zhǎng)度              
  133.             TextOut(hdc,0,          y,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));  
  134.             //從22個(gè)大寫(xiě)字母以后的位置輸出,因?yàn)榈谝涣凶疃嘀挥?0個(gè)大寫(xiě)字母  
  135.             TextOut(hdc,22*cxCaps,  y,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));  
  136.             //最后一列是右對(duì)齊的  
  137.             SetTextAlign(hdc,TA_RIGHT | TA_TOP);  
  138.             //40*cxChar是第二列及第三列的列寬  
  139.             //wsprintf用來(lái)給指定的buffer中格式化并存儲(chǔ)字符串(0結(jié)尾),返回值為字符串的數(shù)目  
  140.             //GetSystemMetrics用來(lái)獲取系統(tǒng)參數(shù),返回值為系統(tǒng)參數(shù)  
  141.             TextOut(hdc,22*cxCaps+40*cxChar,y,szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics (sysmetrics[i].Index)));  
  142.             //再把對(duì)齊方式改回去,否則下一次循環(huán)時(shí)也是右對(duì)齊  
  143.             SetTextAlign(hdc,TA_LEFT | TA_TOP);  
  144.         }  
  145.         EndPaint (hwnd, &ps) ;  
  146.         return 0;  
  147.           
  148.     //滾動(dòng)條消息  
  149.     case WM_VSCROLL:  
  150.               
  151.         //通過(guò)滾動(dòng)條消息的wParam表明滾動(dòng)條的操作  
  152.         switch(LOWORD (wParam))  
  153.         {  
  154.         //點(diǎn)一下上箭頭:向下翻一行  
  155.         case SB_LINEUP:  
  156.             iVscrollPos -=1;  
  157.             break;  
  158.         //點(diǎn)一下下箭頭:向上翻一行  
  159.         case SB_LINEDOWN:  
  160.             iVscrollPos +=1;  
  161.             break;  
  162.         //點(diǎn)一下方塊上面:向上翻一頁(yè),每一頁(yè)是:(客戶(hù)區(qū)/一行高度)這么多行  
  163.         case SB_PAGEUP:  
  164.             iVscrollPos -= cyClient / cyChar ;  
  165.             break;  
  166.         //點(diǎn)一下方塊下面:向下翻一頁(yè)  
  167.         case SB_PAGEDOWN:  
  168.             iVscrollPos += cyClient / cyChar ;  
  169.             break;  
  170.         //拖動(dòng)滾動(dòng)條:wParam的高字節(jié)表明了滾動(dòng)條的位置  
  171.         case SB_THUMBPOSITION:  
  172.             iVscrollPos = HIWORD (wParam) ;  
  173.             break;  
  174.         default:  
  175.             break;  
  176.         }  
  177.           
  178.         //這一句是為了  
  179.         iVscrollPos = max (0, min (iVscrollPos, NUMLINES - 1)) ;  
  180.   
  181.          //如果滾動(dòng)條位置改變  
  182.          if (iVscrollPos != GetScrollPos (hwnd, SB_VERT))  
  183.          {  
  184.             //設(shè)置滾動(dòng)條小方塊的位置  
  185.             SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;  
  186.             //設(shè)為無(wú)效區(qū),激勵(lì)WM_PAINT消息  
  187.             InvalidateRect (hwnd, NULL, TRUE) ;  
  188.          }  
  189.   
  190.         return 0;  
  191.           
  192.   
  193.     case  WM_DESTROY:  
  194.         PostQuitMessage(0);  
  195.         return 0;  
  196.     }  
  197.     return DefWindowProc (hwnd, message, wParam, lParam) ;  
  198.   
  199. }  

程序的思路是這樣的:在創(chuàng)建窗口時(shí),就要告訴系統(tǒng)你要加一個(gè)滾動(dòng)條(垂直的),在WM_CREATE消息中,就要對(duì)滾動(dòng)條進(jìn)行一些基本的設(shè)置。WM_VSCROLL對(duì)滾動(dòng)條做出相應(yīng),可以分為3部分:第一部分接收滾動(dòng)條的消息;第二部分是讓滾動(dòng)條的那個(gè)小方塊滾動(dòng)到特定的位置,第三部分是頁(yè)面的文字出現(xiàn)“滾動(dòng)”的效果。

先看第一部分:滾動(dòng)條的作用是什么:當(dāng)點(diǎn)擊一下向上或者向下的按鈕時(shí),會(huì)滾動(dòng)一行文字;當(dāng)點(diǎn)擊滾動(dòng)的小方塊的上面或者下面時(shí),會(huì)滾動(dòng)一頁(yè)文字;而拖著滾動(dòng)條走,能滾動(dòng)到指定的地方。到底是這幾種操作的哪一種,是通過(guò)WM_VSCROLL消息的wParam的低字節(jié)傳過(guò)來(lái)的。在程序中,使用iVscrollPos這個(gè)全局變量來(lái)記錄滾動(dòng)的位置,每一次對(duì)滾動(dòng)條都會(huì)改變位置。

iVscrollPos = max (0, min (iVscrollPos, NUMLINES - 1)) ;是為了不讓滾動(dòng)條的位置超出一定為范圍,大家可以把它屏蔽之后,將滾動(dòng)條向上或者向下滾,就可以理解結(jié)果了。
而通過(guò)SetScrollPos (hwnd, SB_VERT, iVscrollPos, TRUE) ;就將滾動(dòng)條的方塊放到了可定位位置。而第三部分讓頁(yè)面滾動(dòng),則是WM_PAINT的作用了:其實(shí)當(dāng)你看到第二行顯示在原來(lái)第一行為位置上時(shí),其實(shí)并不是系統(tǒng)沒(méi)有輸出第一行,而是第一行輸出的位置已經(jīng)到了客戶(hù)區(qū)的上面,所以你看不到!第二行緊跟在第一行下面,剛好就放到了開(kāi)始的位置。

這個(gè)滾動(dòng)條有一個(gè)明顯的缺點(diǎn),就是他并不是我們希望看到的那樣:滾動(dòng)條的長(zhǎng)度反應(yīng)的當(dāng)前頁(yè)面占顯示的內(nèi)容總的內(nèi)容的百分比,具體的說(shuō),就是:

頁(yè)面方塊的大小/滾動(dòng)的長(zhǎng)度=頁(yè)面大小/整個(gè)范圍=顯示文件的數(shù)量/整個(gè)文件的數(shù)量

別看這只是一點(diǎn)小小的改動(dòng),但是他的實(shí)現(xiàn)方法卻與上面的差別很大??傮w上來(lái)說(shuō),他需要使用SCROLLINFO結(jié)構(gòu)來(lái)記錄滾動(dòng)條的信息,然后使用GetScrollInfo獲取信息,通過(guò)SetScrollInfo設(shè)置信息。在對(duì)滾動(dòng)條的響應(yīng)消息中,通過(guò)ScrollWindow來(lái)實(shí)現(xiàn)內(nèi)容的滾動(dòng)(而不像前面那個(gè)程序,在WM_PAINT消息下實(shí)現(xiàn))。

我們?cè)诳纯闯绦颍?/P>

 
  1. #include <windows.h>  
  2. #include "sysmets.h"  
  3.   
  4. LRESULT CALLBACK WndProc (HWND,UINT,WPARAM,LPARAM);  
  5.   
  6. int WINAPI WinMain(HINSTANCE hInstance,     //當(dāng)前實(shí)例句柄  
  7.                    HINSTANCE hPrevInstance, //先前實(shí)例句柄  
  8.                    LPSTR lpCmdLine,         //命令行  
  9.                    int iCmdShow)            //顯示狀態(tài)  
  10. {  
  11.     static TCHAR szAppName[] = TEXT("顯示系統(tǒng)內(nèi)容");  
  12.     //窗口句柄  
  13.     HWND hwnd;  
  14.     //消息  
  15.     MSG msg;  
  16.     //窗口類(lèi)  
  17.     WNDCLASS wndclass;  
  18.     //窗口風(fēng)格:當(dāng)移動(dòng)窗口或者改變大小時(shí)重繪窗口  
  19.     wndclass.style         =  CS_HREDRAW | CS_VREDRAW;  
  20.     //指明回調(diào)函數(shù)  
  21.     wndclass.lpfnWndProc   = WndProc;  
  22.     //額外的比特用來(lái)確認(rèn)下一個(gè)窗口類(lèi)的位置,暫時(shí)不用  
  23.     wndclass.cbClsExtra    = 0;  
  24.     //額外的比特用來(lái)確認(rèn)下一個(gè)窗口實(shí)例的位置,暫時(shí)不用  
  25.     wndclass.cbWndExtra    = 0;  
  26.     //實(shí)例句柄  
  27.     wndclass.hInstance     = hInstance;  
  28.     //裝載圖標(biāo)  
  29.     wndclass.hIcon         = LoadIcon(NULL, IDI_APPLICATION);  
  30.     //裝載光標(biāo)  
  31.     wndclass.hCursor       = LoadCursor(NULL,IDC_ARROW);  
  32.     //背景為白色  
  33.     wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);  
  34.     //菜單:暫時(shí)沒(méi)有  
  35.     wndclass.lpszMenuName  = NULL;  
  36.     //窗口類(lèi)名  
  37.     wndclass.lpszClassName = szAppName;  
  38.   
  39.     //注冊(cè)窗口  
  40.     if(!RegisterClass(&wndclass))  
  41.     {  
  42.         return -1;  
  43.     }  
  44.   
  45.     //創(chuàng)建窗口  
  46.     hwnd = CreateWindow(szAppName,              //窗口類(lèi)的名稱(chēng),必須是已經(jīng)注冊(cè)的  
  47.                         TEXT("系統(tǒng)內(nèi)容"),       //窗口標(biāo)題  
  48.                         WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,  //窗口風(fēng)格,加入滾動(dòng)條  
  49.                         CW_USEDEFAULT,          //X坐標(biāo)  
  50.                         CW_USEDEFAULT,          //Y坐標(biāo)  
  51.                         CW_USEDEFAULT,          //寬度  
  52.                         CW_USEDEFAULT,          //高度  
  53.                         NULL,                   //父窗口句柄  
  54.                         NULL,                   //菜單窗口句柄  
  55.                         hInstance,              //高級(jí)版本的windos忽略  
  56.                         NULL);                    
  57.   
  58.     //顯示窗口  
  59.     //ShowWindow(hwnd,SW_SHOWNA);  
  60.     ShowWindow (hwnd, iCmdShow);  
  61.   
  62.     //更新窗口  
  63.     UpdateWindow(hwnd);  
  64.   
  65.     //消息循環(huán)  
  66.     while(GetMessage(&msg,NULL,0,0))  
  67.     {  
  68.           
  69.         TranslateMessage(&msg);  
  70.         //將消息給窗口  
  71.         DispatchMessage(&msg);  
  72.   
  73.     }  
  74.   
  75.     return msg.wParam;  
  76.   
  77. }  
  78.   
  79. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)  
  80. {  
  81.     //字符的寬度,大寫(xiě)字母寬度,字符高度  
  82.     static int    cxChar, cxCaps, cyChar ;  
  83.     //窗口大小  
  84.     static int cxClient, cyClient ;  
  85.     //最大寬度  
  86.     static int iMaxWidth;  
  87.     //滾動(dòng)條位置  
  88.     static int iVertPos,iHorzPos,iPaintBeg,iPaintEnd;  
  89.     HDC hdc;  
  90.     //該變量用于索引sysmets.h中定義的結(jié)構(gòu)體數(shù)組sysmetrics[]的每個(gè)元素  
  91.     int i;  
  92.     //輸出文本的位置  
  93.     int x,y;  
  94.     //繪圖結(jié)構(gòu)  
  95.     PAINTSTRUCT ps;  
  96.     //這個(gè)結(jié)構(gòu)包含了滾動(dòng)條的信息  
  97.     //通過(guò)SetScrollInfo函數(shù)設(shè)置信息,通過(guò) GetScrollInfo 函數(shù)獲取信息  
  98.     SCROLLINFO si;  
  99.     //字符串  
  100.     TCHAR szBuffer [10];  
  101.     //字體信息結(jié)構(gòu)  
  102.     TEXTMETRIC  tm;  
  103.     switch(message)  
  104.     {  
  105.     case WM_CREATE:  
  106.         hdc = GetDC(hwnd);  
  107.         //取得內(nèi)定系統(tǒng)字體的文字大小,存在放在tm里  
  108.         GetTextMetrics (hdc, &tm);  
  109.         //平均字符寬  
  110.         cxChar = tm.tmAveCharWidth ;  
  111.         //大寫(xiě)字母的平均寬度  
  112.         cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;  
  113.         //字符總高度:高度+行間距  
  114.         cyChar = tm.tmHeight + tm.tmExternalLeading ;  
  115.   
  116.         ReleaseDC(hwnd,hdc);  
  117.         //最大跨度 = 40個(gè)字符+22個(gè)大寫(xiě)字母  
  118.         iMaxWidth = 40*cxChar+22*cxCaps;  
  119.         return 0;  
  120.     case WM_SIZE:  
  121.         cxClient = LOWORD (lParam) ;          
  122.         cyClient = HIWORD (lParam) ;     
  123.         //設(shè)置垂直滾動(dòng)條信息  
  124.         //結(jié)構(gòu)體的大小  
  125.         si.cbSize  = sizeof(si);  
  126.         //指明將要設(shè)置和獲取的參數(shù):這里是最大最小值組成的范圍和頁(yè)面的大小  
  127.         si.fMask = SIF_RANGE | SIF_PAGE ;  
  128.         //滾動(dòng)條位置的最小值  
  129.         si.nMin = 0;  
  130.         //滾動(dòng)條位置的最大值  
  131.         si.nMax = NUMLINES - 1 ;  
  132.         //頁(yè)面大小  
  133.         si.nPage = cyClient / cyChar ;  
  134.         //設(shè)置滾動(dòng)條的參數(shù)  
  135.         SetScrollInfo(hwnd, SB_VERT,&si,TRUE);  
  136.   
  137.         //設(shè)置水平滾動(dòng)條信息  
  138.         si.cbSize  = sizeof(si);  
  139.         si.fMask = SIF_RANGE | SIF_PAGE ;  
  140.         si.nMin = 0;  
  141.         si.nMax = 2+ iMaxWidth/cxChar ;  
  142.         si.nPage = cxClient / cxChar ;  
  143.         SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;  
  144.   
  145.         return 0;   
  146.           
  147.     case WM_PAINT:  
  148.         hdc = BeginPaint (hwnd, &ps) ;  
  149.   
  150.         si.cbSize = sizeof(si);  
  151.         si.fMask = SIF_POS;  
  152.         GetScrollInfo(hwnd,SB_VERT,&si);  
  153.         iVertPos = si.nPos;  
  154.         GetScrollInfo(hwnd,SB_HORZ,&si);  
  155.         iHorzPos = si.nPos;  
  156.         //max(0,當(dāng)前位置+需要繪圖的矩形區(qū)的最高點(diǎn)/字符的高度)  
  157.         //iPaintBeg = max(0,iVertPos+ps.rcPaint.top/cyChar);  
  158.         iPaintBeg = max(0,iVertPos);  
  159.         //繪圖結(jié)束的地方 = 當(dāng)前位置+繪制去取的高度  
  160.         iPaintEnd = min(NUMLINES -1,iVertPos+ps.rcPaint.bottom/cyChar);  
  161.   
  162.         for(i = iPaintBeg; i <= iPaintEnd;i++)  
  163.         {  
  164.             //繪圖的x起始位置:1是自己設(shè)置的,設(shè)置越大離左邊越寬  
  165.             x = cxChar * (1 - iHorzPos) ;  
  166.             //繪圖的y起始位置。  
  167.             y = cyChar * (i - iVertPos) ;  
  168.             TextOut(hdc,x, y,sysmetrics[i].szLabel,lstrlen(sysmetrics[i].szLabel));    
  169.             //從22個(gè)大寫(xiě)字母以后的位置輸出,因?yàn)榈谝涣凶疃嘀挥?0個(gè)大寫(xiě)字母    
  170.             TextOut(hdc,x+22*cxCaps,y,sysmetrics[i].szDesc,lstrlen(sysmetrics[i].szDesc));    
  171.             SetTextAlign(hdc,TA_RIGHT | TA_TOP);  
  172.             TextOut(hdc,x+22*cxCaps+40*cxChar,y,szBuffer,wsprintf(szBuffer,TEXT("%5d"),GetSystemMetrics (sysmetrics[i].Index)));   
  173.             SetTextAlign(hdc,TA_LEFT | TA_TOP);    
  174.         }  
  175.         EndPaint (hwnd, &ps) ;  
  176.         return 0;  
  177.           
  178.     //垂直滾動(dòng)條消息  
  179.     case WM_VSCROLL:  
  180.         //獲取垂直滾動(dòng)條信息  
  181.   
  182.         si.cbSize = sizeof(si);  
  183.         //所有參數(shù)  
  184.         si.fMask = SIF_ALL;  
  185.         GetScrollInfo(hwnd,SB_VERT,&si);  
  186.         //垂直位置  
  187.         iVertPos = si.nPos ;  
  188.         //通過(guò)滾動(dòng)條消息的wParam表明滾動(dòng)條的操作  
  189.         switch(LOWORD (wParam))  
  190.         {  
  191.         case SB_TOP:  
  192.             si.nPos = si.nMin;  
  193.             break;  
  194.         case SB_BOTTOM:  
  195.             si.nPos = si.nMax;  
  196.             break;  
  197.         case SB_LINEUP:  
  198.             si.nPos -= 1;  
  199.             break;  
  200.         case SB_LINEDOWN:  
  201.             si.nPos +=1;  
  202.         case SB_PAGEUP:  
  203.             si.nPage -= si.nPage;  
  204.             break;  
  205.         case SB_PAGEDOWN:  
  206.             si.nPos +=si.nPage;  
  207.             break;  
  208.         case SB_THUMBTRACK:  
  209.             si.nPos = si.nTrackPos;  
  210.             break;  
  211.         default:  
  212.             break;  
  213.         }  
  214.           
  215.   
  216.         si.fMask = SIF_POS;  
  217.         SetScrollInfo(hwnd,SB_VERT,&si,TRUE);  
  218.         GetScrollInfo(hwnd,SB_VERT,&si);  
  219.         if(si.nPos != iVertPos)  
  220.         {  
  221.             //滾動(dòng)指定窗口的內(nèi)容  
  222.             ScrollWindow(hwnd,0,cyChar*(iVertPos-si.nPos),NULL,NULL);  
  223.             UpdateWindow(hwnd);  
  224.         }  
  225.         return 0;  
  226.     //水平滾動(dòng)條消息  
  227.     case WM_HSCROLL:  
  228.         si.cbSize = sizeof(si);  
  229.         si.fMask = SIF_ALL;  
  230.         GetScrollInfo(hwnd,SB_HORZ,&si);  
  231.         iHorzPos = si.nPos;  
  232.         switch(LOWORD(wParam))  
  233.         {  
  234.         case SB_LINELEFT:  
  235.             si.nPos -= 1;  
  236.             break;  
  237.         case SB_LINERIGHT:  
  238.             si.nPos +=1;  
  239.             break;  
  240.         case SB_PAGELEFT:  
  241.             si.nPos -= si.nPage;  
  242.             break;  
  243.         case SB_PAGERIGHT:  
  244.             si.nPos += si.nPage;  
  245.             break;  
  246.         case SB_THUMBPOSITION:  
  247.             si.nPos = si.nTrackPos;  
  248.             break;  
  249.         default:  
  250.             break;  
  251.               
  252.         }  
  253.         si.fMask = SIF_POS;  
  254.         SetScrollInfo(hwnd,SB_HORZ,&si,TRUE);  
  255.         GetScrollInfo(hwnd,SB_HORZ,&si);  
  256.         if(si.nPos != iHorzPos)  
  257.         {  
  258.             ScrollWindow(hwnd,cxChar*(iHorzPos-si.nPos),0,NULL,NULL);  
  259.             //UpdateWindow (hwnd) ;  
  260.   
  261.         }  
  262.         return 0;  
  263.     case  WM_DESTROY:  
  264.         PostQuitMessage(0);  
  265.         return 0;  
  266.     }  
  267.     return DefWindowProc (hwnd, message, wParam, lParam) ;  
  268.   
  269. }  


 

程序中有幾點(diǎn)需要注意:

1.程序中設(shè)置了垂直滾動(dòng)條和水平滾動(dòng)條。在WM_SIZE消息中,隨著窗口的變化,滾動(dòng)條的那個(gè)小方塊的大小也在變化。

2.在每次使用GetScrollInfo或者SetScrollInfo之前,都必須有si.cbSize  = sizeof(si);這是因?yàn)榧嫒莸木壒?。而且還得指明操作的是SCROLLINFO中的哪些內(nèi)容,這通過(guò)fMask來(lái)控制。

3.程序中有幾行代碼很費(fèi)解:

iPaintBeg = max(0,iVertPos+ps.rcPaint.top/cyChar);實(shí)際上,由于ps.rcPaint.top=0,這行代碼也可以寫(xiě)為:iPaintBeg = max(0,iVertPos);

iPaintEnd = min(NUMLINES -1,iVertPos+ps.rcPaint.bottom/cyChar);畫(huà)圖的結(jié)束位置=滾動(dòng)條當(dāng)前的位置+繪制的行數(shù),而行數(shù)=客戶(hù)區(qū)寬度/每一行的寬度;

x = cxChar * (1 - iHorzPos) ;繪圖的x坐標(biāo),那個(gè)1是為了不是太“頂格”,你也可以把它設(shè)置大一點(diǎn),結(jié)果就很明顯了。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀(guān)點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多

    伊人国产精选免费观看在线视频| 国产老女人性生活视频| 久久国产亚洲精品赲碰热| 亚洲少妇一区二区三区懂色| 少妇熟女精品一区二区三区| 日韩精品一区二区三区av在线| 亚洲专区中文字幕在线| 亚洲欧美中文字幕精品| 黄色国产精品一区二区三区| 亚洲日本中文字幕视频在线观看| 欧美精品亚洲精品一区| 欧美精品专区一区二区| 精品国产av一区二区三区不卡蜜 | 不卡中文字幕在线免费看| 日本高清视频在线观看不卡| 好吊色免费在线观看视频| 亚洲中文在线中文字幕91| 中文字幕五月婷婷免费| 中文字幕禁断介一区二区| 亚洲精品国产第一区二区多人| 国产精品亚洲综合色区韩国| 国产精品一区二区视频成人| 免费黄色一区二区三区| 人妻少妇久久中文字幕久久 | 欧美日韩综合在线第一页| 中文字幕av诱惑一区二区| 国产毛片av一区二区三区小说| 久热99中文字幕视频在线| 欧美美女视频在线免费看| 91老熟妇嗷嗷叫太91| 丰满人妻熟妇乱又乱精品古代| 冬爱琴音一区二区中文字幕| av在线免费观看在线免费观看| 麻豆看片麻豆免费视频| 夜夜躁狠狠躁日日躁视频黑人| 国产又粗又长又大高潮视频| 国产一级内射麻豆91| 亚洲一区精品二人人爽久久| 免费精品一区二区三区| 国产大屁股喷水在线观看视频 | 91免费精品国自产拍偷拍|