windows的滾動條使用


背景

在畢業快一年的工作時間中,對windows編程的某些特性並不夠熟悉,例如滾動條的使用。在一次需求中需要用到滾動條,在開發過程中走了不少彎路,因此需要做一些筆記總結一下學習到的內容。

先推薦幾個寫的特別好的博客:

Windows編程之滾動條—滾動條消息
C語言Windows程序設計-> 第八天-> 滾動條
三、Windows編程之滾動條—滾動條信息函數

基本滾動條的使用是非常簡單的,無法就那么幾個步驟

  • 判斷是否需要滾動條,並初始化滾動條,比如頁面大小等變量。

如: EnableScrollBarCtrlSetScrollInfo等API, SetScrollInfo用於設置滾動條的相關參數, 包括滾動范圍的最大值和最小值, 頁面大小, 滑塊的位置。

  typedef struct tagSCROLLINFO 
  { 
    UINT cbSize ;            //設置為sizeof (SCROLLINFO), 表示該結構的大小
    UINT fMask ;           //要設置或獲取的值
    int nMin ;               //滾動條范圍的最小值
    int nMax ;                //滾動條范圍的最大值
    UINT nPage ;          //頁面大小
    int nPos ;               //當前位置 
    int nTrackPos ;           //當前追蹤位置 
  }SCROLLINFO;

fMask中我們常用的是 SIF_ALL(是SIF_RANGE、SIF_POS、SIF_PAGE和SIF_TRACKPOS的組合),

在win32中,滾動條的長度和窗口的長度是成一定比例的。如下公式所控制:

  • 對滾動條的消息處理,例如幾個典型的消息:SB_LINEDOWNSB_LINEUPSB_THUMBPOSITIONSB_THUMBTRACK; 以及SB_PAGEDOWN等之類的消息。主要邏輯就是在滾動條移動時,要更新子窗口相對於父窗口的位置(如,調用MoveWindow函數等)。
    鼠標滑輪的消息,在MFC的CWnd窗口中,捕獲滑輪消息,轉發滾動條消息:
BOOL CxxxxWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
	if (m_bEnableVScroll)
	{
		if (zDelta > 0)
		{
			PostMessage(WM_VSCROLL, SB_LINEUP, 0);
		}
		else
		{
			PostMessage(WM_VSCROLL, SB_LINEDOWN, 0);
		}
	}

	return __super::OnMouseWheel(nFlags, zDelta, pt);
}

常用的滾動條消息如下:

開發過程中遇到的問題

  • 帶滾動條的窗口的窗口結構
    之前不太曉得帶滾動條的窗口的窗口結構,帶滾動條的窗口一定是有子窗口的。滑動的時候,改變子窗口的相對位置。參考一張圖:

  • 如何使滾動條可以拖拽?
    主要是對 SB_THUMBPOSITIONSB_THUMBTRACK消息的處理。當把鼠標的光標放在卷動方塊上並按住鼠標鍵時,您就可以移動卷動方塊。這樣就產生了帶有SB_THUMBTRACKSB_THUMBPOSITION通知碼的滾動條消息。在wParam的低字組是SB_THUMBTRACK時,wParam的高字組是使用者在拖動卷動方塊時的目前位置。該位置位於卷動列范圍的最小值和最大值之間。在wParam的低字組是SB_THUMBPOSITION時,wParam的高字組是使用者釋放鼠標鍵后卷動方塊的最終位置。

    case SB_THUMBPOSITION:
    case SB_THUMBTRACK:
    {
        bSuccess = GetScrollInfo(SB_VERT, &si);
        si.fMask = SIF_POS;
        si.nPos = si.nTrackPos;
        bSuccess = SetScrollInfo(SB_VERT, &si);
        //按照成員變量nPos的消息移動子窗口位置即可....
        Invalidate();
    }
        break;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM