zoukankan      html  css  js  c++  java
  • 滚动条

    头文件:

    #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")
    
    } ;

    代码:

    #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(水平滚动条), 或者同时包括两者。

    在 CreateWindow() 函数中指定的滚动条总是出现在窗口的右边和底部,而且总是伸展到整个客户区的宽度和高度。 

    客户区并不包含滚动条所占用的空间。  

    Windows负责处理滚动条中所有鼠标消息。但是,滚动条并没有自动对应的键盘接口。

    如果想将方向键对应到滚动条上,则必须显示的提供相应的对应关系。

    每个滚动条都有相应的"范围"和"位置"。滚动条的范围是一对整数,分别代表滚动条的最小值和最大值。

    位置是指滑块在范围中所处的值。当滑块在滚动条的顶端时,滑块的位置是范围的最小值。相应的,

    当滑块在滚动条的底部(或最右)时,位置是范围最大值。

    在默认情况下,滚动条的范围是 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 次。
     
    好了比较难以理解的就这个部分了,我想大家应该都能看懂。
    (注意:遇到程序在弄懂之后一定要自己去敲,一定要自己去敲,一定要自己去敲)
    (注意:遇到程序在弄懂之后一定要自己去敲,一定要自己去敲,一定要自己去敲)
    (注意:遇到程序在弄懂之后一定要自己去敲,一定要自己去敲,一定要自己去敲)
  • 相关阅读:
    SegmentFault 巨献 1024 程序猿游戏「红岸的呼唤」第二天任务攻略
    POJ 2263 Heavy Cargo(ZOJ 1952)
    EEPlat 主子表和对象引用配置实例
    tornado websocket
    android android:duplicateParentState=&quot;true&quot; &quot;false&quot;
    掌握4个有效的数据分析要点,切实解决用户痛点
    掌握4个有效的数据分析要点,切实解决用户痛点
    没有基础,如何成为数据分析师?
    没有基础,如何成为数据分析师?
    数据的无量纲化处理和标准化处理的区别是什么
  • 原文地址:https://www.cnblogs.com/M-Anonymous/p/9295278.html
Copyright © 2011-2022 走看看