滾動條

頭文件:windows

#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 draggable width"),
     SM_CYMAXTRACK,           TEXT ("SM_CYMAXTRACK"),            
                              TEXT ("Maximum draggable 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")

} ;

 

代碼:app

#define WINVER 0x0500
#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 ("SysMets3") ;
     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 ("Program requires Windows NT!"), 
                      szAppName, MB_ICONERROR) ;
          return 0 ;
     }
     hwnd = CreateWindow (szAppName, TEXT ("Get System Metrics No. 3"),
                          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, cxCaps, cyChar, 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) ;
          cxChar = tm.tmAveCharWidth ;
          cxCaps = (tm.tmPitchAndFamily & 1 ? 3 : 2) * cxChar / 2 ;
          cyChar = tm.tmHeight + tm.tmExternalLeading ;
          ReleaseDC (hwnd, hdc) ;
               // Save the width of the three columns   
          iMaxWidth = 40 * cxChar + 22 * cxCaps ;
          return 0 ;
      case WM_SIZE:
          cxClient = LOWORD (lParam) ;
          cyClient = HIWORD (lParam) ;
               // Set vertical scroll bar range and page size
          si.cbSize = sizeof (si) ;
          si.fMask  = SIF_RANGE | SIF_PAGE ;
          si.nMin   = 0 ;
          si.nMax   = NUMLINES - 1 ;
          si.nPage  = cyClient / cyChar ;
          SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
               // Set horizontal scroll bar range and page size
          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:
               // Get all the vertial scroll bar information
          si.cbSize = sizeof (si) ;
          si.fMask  = SIF_ALL ;
          GetScrollInfo (hwnd, SB_VERT, &si) ;
               // Save the position for comparison later on
          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 ;
               break ;
          case SB_THUMBTRACK:
               si.nPos = si.nTrackPos ;
               break ;    
          default:
               break ;         
          }
               // Set the position and then retrieve it.  Due to adjustments
               //   by Windows it may not be the same as the value set.
          si.fMask = SIF_POS ;
          SetScrollInfo (hwnd, SB_VERT, &si, TRUE) ;
          GetScrollInfo (hwnd, SB_VERT, &si) ;
               // If the position has changed, scroll the window and update it
          if (si.nPos != iVertPos)
          {                    
               ScrollWindow (hwnd, 0, cyChar * (iVertPos - si.nPos), NULL, NULL) ;
               UpdateWindow (hwnd) ;
          }
          return 0 ;
     case WM_HSCROLL:
               // Get all the vertial scroll bar information
          si.cbSize = sizeof (si) ;
          si.fMask  = SIF_ALL ;
            // Save the position for comparison later on
          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_THUMBTRACK:
               si.nPos = si.nTrackPos ;
               break ;             
          default :
               break ;
          }
               // Set the position and then retrieve it.  Due to adjustments
               //   by Windows it may not be the same as the value set.
          si.fMask = SIF_POS ;
          SetScrollInfo (hwnd, SB_HORZ, &si, TRUE) ;
          GetScrollInfo (hwnd, SB_HORZ, &si) ;          
               // If the position has changed, scroll the window 
          if (si.nPos != iHorzPos)
          {
               ScrollWindow (hwnd, cxChar * (iHorzPos - si.nPos), 0, NULL, NULL) ;
UpdateWindow (hwnd) ; }
return 0 ; case WM_PAINT : hdc = BeginPaint (hwnd, &ps) ; // Get vertical scroll bar position si.cbSize = sizeof (si) ; si.fMask = SIF_POS ; GetScrollInfo (hwnd, SB_VERT, &si) ; iVertPos = si.nPos ; // Get horizontal scroll bar position GetScrollInfo (hwnd, SB_HORZ, &si) ; iHorzPos = si.nPos ; // Find painting limits iPaintBeg = max (0, iVertPos + ps.rcPaint.top / cyChar) ; 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) ; }

 

在應用程序中加入滾動條至關容易,只需在 CreateWindow() 函數的第三個參數中包括窗口風格標識符 函數

WS_VSCROLL(垂直滾動條) 或 WS_HSCROLL(水平滾動條), 或者同時包括二者。ui

在 CreateWindow() 函數中指定的滾動條老是出如今窗口的右邊和底部,並且老是伸展到整個客戶區的寬度和高度。 spa

客戶區並不包含滾動條所佔用的空間。  指針

Windows負責處理滾動條中全部鼠標消息。可是,滾動條並無自動對應的鍵盤接口。code

若是想將方向鍵對應到滾動條上,則必須顯示的提供相應的對應關係。orm

每一個滾動條都有相應的"範圍"和"位置"。滾動條的範圍是一對整數,分別表明滾動條的最小值和最大值。blog

位置是指滑塊在範圍中所處的值。當滑塊在滾動條的頂端時,滑塊的位置是範圍的最小值。相應的,接口

當滑塊在滾動條的底部(或最右)時,位置是範圍最大值。

在默認狀況下,滾動條的範圍是 1~100,不過經過下面的函數調用,能夠很方便的把範圍改爲對程序更有意義的值:

 

SetScrollRange(hwnd, iBar, iMin, iMax, bRedraw);  

這裏的 iBar 參數要麼是 SB_VERT(垂直滾動條範圍), 要麼是 SB_HORZ(水平滾動條範圍), 用來指定滾動條將被設置。

而 iMin 和 iMax 分別對應範圍的最小值和最大值。

須要 Windows 根據新的範圍來重繪滾動條時,請將 bRedraw 參數設爲 TRUE, (若是在調用 SetScrollRange() 函數

以後還調用其餘函數來調整滾動條的顯示時,最好將bRedraw 設爲 FALSE 以免過多的重繪)。

 

經過 SetScrollPos() 函數調用便可指定滑塊在滾動條範圍中的位置:

SetScrollPos(hwnd, iBar, iPos, bRedraw);

這裏的參數 iPos 是滑塊的新位置,他必須在 iMin 和 iMax 之間。

Windows 提供了兩個相似的函數 GetScrollRange() 和 GetScrollPos() 用於獲取滾動條的當前範圍和位置。

另外,在程序中使用滾動條時,程序須要和 Windows 共同負責維護滾動條以及滑塊在滾動條中的位置。

請記住如下幾點:

Windows 負責以下任務: 

  • 處理滾動條中全部鼠標消息
  • 當用戶單擊滾動條時,提供一種反向顯示的閃爍
  • 當用戶拖動滑塊時,在滾動條內移動滑塊
  • 向擁有滾動條的窗口的窗口過程(WndProc() )發送滾動條消息
程序須要負責以下任務:
  • 初始化滾動條的範圍和位置
  • 處理傳送給窗口過程的滾動條消息
  • 更新滑塊的位置
  • 根據滾動條的變化更新客戶區的內容

 

而對於 WM_SIZE 消息,只要當窗口的大小發生變化時,Windows 會向窗口過程發送一條 WM_SIZE 消息。

相應的 lParam 變量的低位是客戶區的寬度,而高位天然就是高度。

能夠這樣處理 WM_SIZE 消息:

case WM_SIZE:

     cxClient = LOWORD(lParam);

     cyClient = HIWORD(lParam);

     return 0;

 

滾動條消息:

 

當用戶單擊滾動條或拖到滾動條時,Windows 向窗口過程發送 WM_VSCROLL 消息(垂直滾動)或 WM_HSCROLL(水平滾動)。 

在滾動條的上的任何鼠標動做會產生至少兩條消息,一條在鼠標按下時,另外一條在鼠標鍵鬆開時。

就像全部消息同樣,WM_VSCROLL 和 WM_HSCROLL 消息都伴隨着 wParam 和 lParam 消息參數。

當滾動條是窗口一部分時,能夠忽略 lParam 參數:它只用於滾動條是子窗口時,一般是在對話框中。

一樣 wParam 參數也被分爲低位字和高位字。低位字表明瞭鼠標在滾動條上的動做。這個值被稱爲"通知碼"。

由一個以 SB 開頭的標識符定義(SB 表明滾動條)。

下面是在 WINUSER.H 中定義的通知碼:

#define SB_LINEUP 0

#define SB_LINELEFT 0

#define SB_LINEDOWN 1

#define SB_LINERIGHT 1

#define SB_PAGEUP 2

#define SB_PAGELEFT 2

#define SB_PAGEDOWN 3

#define SB_PAGERIGHT 3

#define SB_THUMBPOSITION 4

#define SB_THUMBTRACK 5

#define SB_TOP 6

#define SB_LEFT 6

#define SB_BOTTOM 7

#define SB_RIGHT 7

#define SB_ENDSCROLL 8

 

凡是含有 LEFT, RIGHT 的標識符用於水平滾動條中,而含有 UP, DOWN, TOP, BOTTOM 的標識符用於垂直滾動條中。

當鬆開鼠標鍵時,程序會收到 SB_ENDSCROLL 消息。 

將鼠標放在滑塊上而後按下鼠標鍵時,能夠移動滑塊。這將會產生帶 SB_THUMBPOSITION 和 SB_THUMBTRACK 

通知碼的滾動消息。當 wParam 的低位字是 SB_THUMBTRACK 時,它的高位字即是用戶拖動滑塊的當前位置。

若是低位字是 SB_THUMBPOSITION 時,它的高位字即是用戶鬆開鼠標鍵時滑塊的最終位置。

能夠看下圖加深理解:

 

SCROLLINFO 這個結構體:

typedef struct tagSCROLLINFO

{

UINT cbSize ; // set to sizeof (SCROLLINFO) 

UINT fMask ; // values to set or get

int nMin; // minimum range value

int nMax; // maximum range value

UINT nPage ; // page size 

int nPos ; // current position 

int nTrackPos ; // current tracking position 

}SCROLLINFO,*LPSCROLLINFO;

 

爲何要引進這個結構體呢? 

相對於 SetScrollRange(), SetScrollPos(), GetScrollRange(), GetScrollPos() 函數,

SetScrollInfo(), GetScrollInfo() 這兩個函數更先進,由於它含有上述四個函數的全部功能,還加了兩個新功能。

第一個功能是關於滑塊的大小。滑塊的大小應該和窗口文檔的多少成比例。爲了美觀能夠看以下的公式:

             滑塊大小 / 滾動條長度  =  頁面大小 / 範圍  =  文檔顯示的數量 / 文檔的總大小 

這兩個函數的語法以下:

             SetScrollRange(hwnd, iBar, &si, bRedraw);

             GetScrollRange(hwnd,iBar,&si);

能夠看到有個 &si 這個東西。其實它就是 ScrollInfo結構體的變量。程序一般將該結構體變量這樣命名。

一樣的 iBar 也只能是 SB_VERT, SB_HORZ, SB_CTL 中的一個。SB_CTL 表示一個滾動條控件。

在調用這兩個函數以前,必須將 cbSize 字段設爲該結構體的大小:

                si.cbSize = sizeof(si);

          或者  si.cbSize = sizeof(SCROLLINFO);

可能不少老哥們都想到既然是個定值,那爲啥要給第一個字段呢?

由於這樣,之後的 Windows 版本能夠擴展結構而同時保持與之前的應用程序兼容。

參數:

fMask: 指定結構中的哪些成員是有效,該值共有以下5種選擇,能夠選擇多種用「OR」組合起來,該值在設置和查詢參數時都必須填寫。
SIF_ALL         整個結構都有效
SIF_DISABLENOSCROLL           該值僅在設定參數時使用,視控件參數設定的須要來對本結構的成員進行取捨。
SIF_PAGE           nPage成員有效
SIF_POS        nPos成員有效
SIF_RANGE     nMin和nMax成員有效
nMin                   滾動範圍最小值
nMax                  滾動範圍最大值
nPage                 頁面尺寸,用來肯定比例滾動框的大小
nPos                   滾動框的位置
nTrackPos           拖動時滾動框的位置,該參數只能查詢,不能設置。

 

在 SetScrollInfo() 中指定了 SIF_RANGE 時,必須在 nMin 和 nMax 中指定滾動條的範圍。

                                        SIF_POS  時,必須在 nPos 字段指定滾動條的位置。

                                        SIF_PAGE 時,必須在 nPage 字段指定頁面的大小。

                                        SIF_DISABLENOSCROLL, 做用原來讓滾動條不顯示的設置這時將禁用滾動條。( 該函數獨有 )

在 GetScrollInfo() 中,指定了標誌的,就返回相應的值。

                                       SIF_TRACKPOS 標誌(該函數獨有),並且只在處理通知碼是 SB_THUMBTRACK 或

                                       SB_THUMBPOSITION 的 WM_VSCROLL 或 WM_HSCROLL 消息時。

                                       在函數返回時,SCROLLINFO結構的 nTrackPos 字段將返回當前滑塊的位置(32位整數)。

 

ScrollWindow() 介紹:

            功能:該函數滾動所指定的窗口客戶區域內容。

            函數原型:BOOL ScrollWindow(HWND hWnd, int XAmount, int YAmount,

                                                               CONST RECT *IpRect, CONST RECT *lpClipRect);

            參數:

                   hWnd:客戶區域將被滾動的窗口的句柄。
                   XAmount:指定水平滾動的距離,以設備單位計。若是窗口類風格爲CS_OWNDC或CS_CLASSDC,
                                      則此參數則使用邏輯單位而非設備單位。當向左滾動窗體內容時,參數值必須爲負。
                   YAmount:指定垂直滾動的距離,以設備單位計。若是窗口類風格爲CS_OWNDC或CS_CLASSDC,
                                      則此參數則使用邏輯單位而非設備單位。當向上滾動窗體內容時,參數值必須爲負。
                   lpRect:指向RECT結構的指針,該結構指定了將要滾動的客戶區範圍。若此參數爲NULL,則整個客戶區域將被滾動。
                   lpClipRect:指向RECT結構的指針,該結構指定了要滾動的裁剪區域。
                                        只有這個矩形中的位纔會被滾動。在矩形以外的位不會被影響,即便它們是在lpRect矩形以內。
                                        假如lpClipRect爲NULL,則不會在滾動矩形上進行裁剪。
             返回值: 若是函數運行成功,返回值爲非零;若是函數運行失敗,返回值爲零。
 
 
另外提示一下,這個程序比較難以理解的部分就是 處理 WM_PAINT 消息的部分了。
iPaintBeg 之因此會用到 max(),是爲了應對用戶一直觸發 SB_LINEUP 消息。
同理,iPaintEnd 之因此用到 min(),是爲了應對用戶一直觸發 SB_LINEDOWN 消息。
而 iPaintBeg 通常狀況下都爲 iVertPos + ps.rcPaint.top / cyChar。
由於 ps.rcPaint.top 表明客戶區裏繪製矩形的頂部,默認狀況下都爲 0,在這裏能夠省略掉。
而iPaintBeg 通常狀況下都爲  iVertPos + ps.rcPaint.bottom / cyChar
一樣,ps.rcPaint.bottom 表明客戶區裏繪製矩形的底部,默認狀況下都爲 cyClient。
 
舉個例子,想像一下,在你剛運行這個程序的時候,你沒有觸發任何消息,
iPaintBeg = 0,iPaintEnd = cyClient。這一切都正常。當你用鼠標點擊某些控件時,iVertPos 的值發生了改變。
或許 iPaintBeg = ps.rcPaint.top / cychar + iVertPos,iPaintBeg = ps.rcPaint.bottom / cychar + iVertPos 這樣更好理解一些。
 
x = cxChar * (1 - iHorzPos) ;
仍然是想象一下,在你剛運行這個程序的時候,你沒有觸發任何消息。
此時,iHorzPos = 0,這是顯示的文本將和客戶區有一個字符的空格,這僅是爲了美觀。
當你觸發 si.nPos 增大的狀況時,說明你要看到內容是右邊的部分,這是你只需將文本的位置左移,固然 x 的值能夠是負數。
y = cyChar * (i - iVertPos) ;
一樣,仍然這樣想,一開始 i = 0,iVertPos 等於 0;然而 i 是在不斷加一的。
無論怎樣,每次進行繪圖操做時,i 老是等於 iVertPos + ps.rcPaint.top / cyChar。即 i = iVertPos。
每次結束繪圖操做時,循環都是執行了 ps.rcPaint.bottom / cyChar 次。即 cyClient / cyChar 次。
 
好了比較難以理解的就這個部分了,我想你們應該都能看懂。
(注意:遇到程序在弄懂以後必定要本身去敲,必定要本身去敲,必定要本身去敲)
(注意:遇到程序在弄懂以後必定要本身去敲,必定要本身去敲,必定要本身去敲)
(注意:遇到程序在弄懂以後必定要本身去敲,必定要本身去敲,必定要本身去敲)
相關文章
相關標籤/搜索