Windows API学习之滚动条系列函数

    技术2026-04-18  0

    作者:朱金灿来源:http://blog.csdn.net/clever101

          Windows API中滚动条相关函数有两个:int SetScrollInfo( HWND hwnd, int fnBar, LPSCROLLINFO lpsi, BOOL fRedraw );

    BOOL GetScrollInfo( HWND hwnd, int fnBar, LPSCROLLINFO lpsi );

    见名知意,SetScrollInfo就是用来设置窗口的滚动信息,GetScrollInfo就是用来获取窗口的滚动信息。SetScrollInfo的参数含义如下:参数 意义hwnd滚动条控件的句柄或带有标准滚动栏的窗口的句柄fnBar用于指定哪一种滚动条,只能是下面的值之一:SB_CTL :滚动条控件SB_HORZ:水平滚动条SB_VERT:垂直滚动条lpsi滚动条信息结构体指针。下面作进一步详细介绍。fRedraw 值为TRUE表示要Windows重新绘制计算了新信息后的滚动条,FALSE表示不绘制。

    GetScrollInfo的参数含义如下:

    参数 意义hwnd滚动条控件的句柄或带有标准滚动栏的窗口的句柄fnBar用于指定哪一种滚动条,只能是下面的值之一:SB_CTL :滚动条控件SB_HORZ:水平滚动条SB_VERT:垂直滚动条lpsi滚动条信息结构体指针。下面作进一步详细介绍。

    值得注意的是在调用GetScrollInfo函数时要获取相关滚动信息,需要指定SCROLLINFO结构体中的fMask成员的值。fMask取下面的值的组合值:值 意义SIF_PAGE 获取SCROLLINFO中的nPage成员的值(即一页的大小)。SIF_POS 获取SCROLLINFO中的nPos成员的值。SIF_RANGE获取SCROLLINFO中的nPos成员的nMin 和 nMax的值。SIF_TRACKPOS获取SCROLLINFO中的nTrackPos成员的值。nTrackPosSIF_RANGE、SIF_POS、SIF_PAGE和SIF_TRACKPOS的组合。

    使用例程(据petzod的《windows程序设计》第四章,仅列出主要代码片段,具体请下载源码):

     

    view plain copy to clipboard print ? case WM_SIZE:      {          // save the width and height of window when changed the size of window          cxClient = LOWORD(lp); // the width          cyClient = HIWORD(lp); // the height             // set vertical scroll bar range and page size          si.cbSize = sizeof(SCROLLBARINFO);          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 and page size          si.cbSize = sizeof(SCROLLBARINFO);          si.fMask = SIF_RANGE|SIF_PAGE;          si.nMin = 0;          si.nMax = 2 + nMaxWidth/cxChar;          si.nPage = cxClient/cxChar;          SetScrollInfo(hWnd,SB_HORZ,&si,TRUE);          return 0;      }  case WM_VSCROLL:      {  // get all vertical scroll bar information  si.cbSize = sizeof(SCROLLINFO);  si.fMask = SIF_ALL;  ::GetScrollInfo(hWnd,SB_VERT,&si);     // save the position for comparison later on  nVertPos = si.nPos;      switch (LOWORD(wp))             {          case SB_LINEUP:              {                  si.nPos -=1;// the height decrease 1 unit                  break;              }          case SB_LINEDOWN:              {                  si.nPos +=1;// the height increase 1 unit                  break;              }          case SB_PAGEUP:              {                     // back to prev page, the cyClient/cyChar is the number of row in one page                  si.nPos -= cyClient/cyChar;                   break;              }          case SB_PAGEDOWN:              {                  // back to next page                  si.nPos += cyClient/cyChar;                  break;              }          case SB_THUMBPOSITION:              {                  si.nPos = HIWORD(wp);                  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 update it          if (si.nPos!=nVertPos)          {              ::ScrollWindow(hWnd,0,cyChar*(nVertPos-si.nPos),NULL,NULL);              ::UpdateWindow(hWnd);          }          return 0;      }  case WM_HSCROLL:      {          // get all the vertical scroll bar information          si.cbSize = sizeof(si);          si.fMask = SIF_ALL;          // save the position for comparison later on          ::GetScrollInfo(hWnd,SB_HORZ,&si);          nHorzPos = si.nPos;          switch (LOWORD(wp))          {          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_THUMBPOSITION:              {                  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 postion has changed ,scroll the window          if (si.nPos!=nHorzPos)          {              ::ScrollWindow(hWnd,cxChar*(nHorzPos-si.nPos),0,NULL,NULL);          }          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);          nVertPos = si.nPos;          // get horizontal scroll bar position             GetScrollInfo(hWnd,SB_HORZ,&si);             nHorzPos = si.nPos;          // find painting limits              int nPaintBeg = max(0,nVertPos+ps.rcPaint.top/cyChar); // the begin row             int nPaintEnd = min(NUMLINES-1,nVertPos+ps.rcPaint.bottom/cyChar); // the end row          for (int i =nPaintBeg;i<=nPaintEnd;i++)          {                 // calculate the y position of draw region, when y position less 0,skip              int x = cxChar*(1-nHorzPos);               int y = cyChar*(i-nVertPos);              ::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,_T("%5d"),::GetSystemMetrics(sysmetrics[i].Index)));              ::SetTextAlign(hdc,TA_LEFT|TA_TOP);          }          ::EndPaint(hWnd,&ps);          return 0;      }  

     

        相关源码下载:

    Windows API学习之滚动条系列函数演示程序

    最新回复(0)