MFC編程入門之二十六(常用控件:滾動條控件ScrollBar)


  回顧上一節,講的是組合框控件Combo Box的使用。本節詳解滾動條控件Scroll Bar的相關內容。

  滾動條控件簡介

  滾動條大家也很熟悉了,Windows窗口中很多都有滾動條。前面講的列表框和組合框設置了相應屬性后,如果列表項顯示不下也會出現滾動條。滾動條分為水平滾動條(Horizontal Scroll Bar)和垂直滾動條(Vertical Scroll Bar)兩種。滾動條中有一個滾動塊,用於標識滾動條當前滾動的位置。我們可以拖動滾動條,也可以用鼠標點擊滾動條某一位置使滾動塊移動。

  從滾動條的創建形式來分,有標准滾動條和滾動條控件兩種。像列表框和組合框設置了WS_HSCROLL或WS_VSCROLL風格以后出現的滾動條,不是一個獨立的窗口,而是這些窗口的一部分,這就是標准滾動條。而滾動條空間是一個獨立的窗口,它可以獲得焦點,響應某些操作。

  滾動條控件的創建

  MFC也為滾動條控件的操作提供了類,即為CScrollBar類。

  滾動條控件的創建依然有兩種方式,一種是直接在Toolboox中將滾動條控件拖入對話框模板,然后添加控件變量使用,另一種就是用CScrollBar類的Create成員函數動態創建。這兩種方式適用於不同的場合。

  CScrollBar類的成員函數Create的函數原型如下:

  virtual BOOL Create(

    DWORD dwStyle,

    const RECT& rect,

    CWnd* pParentWnd,

    UINT nID

  );

  此函數與其他控件類的Create函數原型基本相同。參數dwStyle指定滾動條控件的風格,rect指定滾動條控件的位置和尺寸,pParentWnd為指向滾動條控件父窗口的指針,nID指定滾動條控件的ID。下面簡單介紹幾個主要的滾動條控件風格,更加具體的可以查閱MSDN。

  SBS_HORZ:指定滾動條為水平滾動條。如果沒有指定SBS_BOTTOMALIGN或SBS_TOPALIGN風格,則滾動條的高度、寬度和位置由Create函數的rect參數給出。

  SBS_VERT:指定滾動條為垂直滾動條。如果沒有指定SBS_RIGHTALIGN或SBS_LEFTALIGN風格,則滾動條的高度、寬度和位置由Create函數的rect參數給出。

  SBS_TOPALIGN:與SBS_HORZ配合使用。滾動條的上邊緣與Create函數的rect參數指定的矩形的上邊緣對齊。

  SBS_BOTTOMALIGN:與SBS_HORZ配合使用。滾動條的下邊緣與Create函數的rect參數指定矩形的下邊緣對齊。滾動條高度為系統滾動條的默認高度。

  SBS_LEFTALIGN:與SBS_VERT配合使用。滾動條的左邊緣與Create函數的rect參數指定矩形的左邊緣對齊。滾動條的寬度為系統滾動條的默認寬度。

  SBS_RIGHTALIGN:與SBS_VERT配合使用。滾動條的右邊緣與Create函數的rect參數指定矩形的右邊緣對齊。滾動條寬度為系統滾動條的默認寬度。

  dwStyle參數可以是以上風格中某幾個的組合,另外一般也會用到WS_CHILD、WS_VISIBLE風格。例如,創建一個水平滾動條控件,dwStyle參數應該為WS_CHILD|WS_VISIBLE|SBS_HORZ,創建垂直滾動條控件時dwStyle參數應該為WS_CHILD|WS_VISIBLE|SBS_VERT。

  CScrollBar類的主要成員函數

  BOOL GetScrollInfo(LPSCROLLINFO lpScrollInfo, UINT nMask = SIF_ALL);

  獲取滾動條的參數信息,該信息為SCROLLINFO結構體的形式。參數lpScrollInfo為指向SCROLLINFO結構體變量的指針。SCROLLINFO結構體的定義如下:

typedef struct tagSCROLLINFO
{
    UINT    cbSize;    // 結構的尺寸(單位為字節)
    UINT    fMask;     // 說明結構中的哪些參數是有效的,可以屏蔽值的組合,如SIF_POS|SIF_PAGE,若為SIF_ALL則整個結構體都有效
    int     nMin;         // 滾動范圍最小值,當fMask中包含SIF_RANGE時有效
    int     nMax;        // 滾動范圍最大值,當fMask中包含SIF_RANGE時有效 
    UINT    nPage;     // 頁尺寸,用來確定比例滾動框的大小,當fMask中包含SIF_PAGE時有效
    int     nPos;          // 滾動框的位置,當fMask中包含SIF_POS有效
    int     nTrackPos;   // 滾動時滾動框的位置,當fMask中包含SIF_TRACKPOS時有效,該參數只能查詢,不能設置,最好不要用該參數來查詢拖動時滾動框的位置
}   SCROLLINFO, FAR *LPSCROLLINFO;
typedef SCROLLINFO CONST FAR *LPCSCROLLINFO;

    參數nMask的含義與SCROLLINFO結構體中的fMask一樣。該函數在獲取信息成功返回TRUE,否則返回FALSE。

 

  BOOL SetScrollInfo(LPSCROLLINFO lpScrollInfo, BOOL bRedraw = TRUE);

  用於設置滾動條的各種參數信息。參數lpScrollInfo為指向SCROLLINFO結構體變量的指針,參數bRedraw表示是否需要重繪滾動條,如果為TRUE,則重繪。該函數操作成功則返回TRUE,否則返回FALSE。

 

  int GetScrollPos() const;

  獲取滾動條的當前位置。如果失敗則返回0。

 

  int SetScrollPos(int nPos, BOOL bRedraw = TRUE);

  將滾動塊移動到指定位置。參數nPos指定了滾動塊的新位置,參數bRedraw表示是否需要重繪滾動條,如果為TRUE,則重繪。函數返回滾動框原來的位置,若操作失敗則返回0.

  

   void GetScrollRange(LPINT lpMinPos, LPINT lpMaxPos) const;

  獲取滾動條的滾動范圍。參數lpMinPos指向滾動條滾動范圍的最小值,參數lpMaxPos指向滾動條滾動范圍的最大值。

  

  void SetScrollRange(int nMinPos, int nMaxPos, BOOL bRedraw = TRUE);

  用於指定滾動條的滾動范圍。參數nMinPos和nMaxPos分別指定了滾動范圍的最小值和最大值,兩者的差不得超過32767。當兩者都為0時,滾動條將被隱藏。參數bReadraw表示是否需要重繪滾動條,如果為TRUE,則重繪。

 

  OnHScroll()與OnVScroll()函數

  無論是標准滾動條,還是滾動條控件,滾動條的通知消息都是用WM_HSCROLL和WM_VSCROLL消息發送出去的。對這兩個消息的默認處理函數是CWnd::OnHSCroll和CWnd::OnVScroll,一般要在派生類中對這兩個函數進行重載,以實現滾動功能。也就是說,假設在一個對話框中放入了一個水平滾動條,我們可以在對話框類中重載OnHScroll函數,並在OnHScroll函數中實現滾動功能。

  這兩個函數的聲明如下:

  afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CSCrollBar* pScrollBar);

  afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CSCrollBar* pScrollBar);

  參數nSBCode是通知消息碼,主要通知碼及含義的介紹下面已列出。nPos是滾動框的位置,只有在nSBCode為SB_THUMBPOSITION或SB_THUMBTRACK時,該參數才有意義。如果通知消息是滾動條控件發來的,那么,pScrollBar是指向該控件的指針,如果是標准滾動條發來的,則pScrollBar為NULL。

  SB_BOTTOM/SB_RIGHT:滾動到底端(右端)

  SB_TOP/SB_LEFT:滾動到頂端(左端)

  SB_LINEDOWN/SB_LINERIGHT:向下(向右)滾動一行(列)

  SB_LINEUP/SB_LINELEFT:向上(向左)滾動一行(列)

  SB_PAGEDOWN/SB_PAGERIGHT:向下(向右)滾動一頁

  SB_PAGEUP/SB_PAGELEFT:向上(向左)滾動一頁

  SB_THUMBPOSITION:滾動到指定位置

  SB_THUMBTRACK:滾動框被拖動。可利用該消息來跟蹤對滾動框的拖動

  SB_ENDSCROLL:滾動結束

  

  CScrollBar類應用實例

  講完了基礎知識,還是給大家一個簡單的實例。就是在一個對話框中加入一個水平滾動控件和一個編輯框控件,無論滾動條控件是在滾動還是在靜止,編輯框中都顯示滾動塊的當前位置。以下是具體開發步驟:

  1、創建一個基於對話框的MFC工程,名稱設置為“MFCScrollBarDemo”。

  2、在自動生成的對話框模板IDD_MFCSCROLLBARDEMO_DIALOG中,刪除"TODO:Place dialog controls here."靜態文本控件、“OK”按鈕和“Cancel”按鈕。添加一個Horizontal Scroll Bar控件,ID設置為IDC_HORI_SCROLLBAR。再添加一個靜態文本框和一個編輯框,靜態文本控件的Caption屬性設為“滾動塊當前位置:”,編輯框的ID設為IDC_HSCROLL_EDIT,Read Only屬性設為True。此時的對話框模板如下圖:

  3、為滾動條IDC_HORI_SCROLLBAR添加CScrollBar類型的控件變量m_horiScrollbar。

  4、在對話框初始化時,我們需要設置滾動條的滾動范圍和初始位置,並在編輯框中顯示初始位置,那么需要修改CMFCScrollBarDemoDlg::OnInitDialog()函數為:

C++代碼:

BOOL CMFCScrollBarDemoDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 將“關於...”菜單項添加到系統菜單中。

	// IDM_ABOUTBOX 必須在系統命令范圍內。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 設置此對話框的圖標。  當應用程序主窗口不是對話框時,框架將自動
	//  執行此操作
	SetIcon(m_hIcon, TRUE);			// 設置大圖標
	SetIcon(m_hIcon, FALSE);		// 設置小圖標

	// TODO: 在此添加額外的初始化代碼
	// 設置水平滾動條的滾動范圍為1到100
	m_horiScrollbar.SetScrollRange(1, 100);
	// 設置水平滾動條的初始位置為20
	m_horiScrollbar.SetScrollPos(20);
	// 在編輯框中顯示20
	SetDlgItemInt(IDC_HSCROLL_EDIT, 20);

	return TRUE;  // 除非將焦點設置到控件,否則返回 TRUE
}

  5、現在滾動條還不能正常滾動,並且編輯框中數字也不隨滾動改變。根據上面所講,我們可以重載CMFCScrollBarDemoDlg類的OnHScroll函數。具體操作為,在CMFCScrollBarDemoDlg類的屬性頁面的工具欄上點擊“Message”按鈕,找到WM_HSCROLL消息,添加響應函數就可以了。OnHScroll函數重寫后如下:

C++代碼:

void CMFCScrollBarDemoDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: 在此添加消息處理程序代碼和/或調用默認值
	// 獲取水平滾動條當前位置
	int pos = m_horiScrollbar.GetScrollPos();

	switch (nSBCode)
	{
	// 如果向左滾動一列,則pos減1
	case SB_LINELEFT:
		pos -= 1;
		break;
	// 如果向右滾動一列,則pos加1
	case SB_LINERIGHT:
		pos += 1;
		break;
	// 如果向左滾動一頁,則pos減10
	case SB_PAGELEFT:
		pos -= 10;
		break;
	// 如果向右滾動一頁,則pos加10
	case SB_PAGERIGHT:
		pos += 10;
		break;
	// 如果滾動到最左端,則pos為1
	case SB_LEFT:
		pos = 1;
		break;
	// 如果滾動到最右端,則pos為100
	case SB_RIGHT:
		pos = 100;
		break;
	// 如果拖動滾動塊到指定位置,則pos賦值為nPos的值
	case SB_THUMBPOSITION:
		pos = nPos;
		break;
	// 下面的m_horiScrollbar.SetScrollPos(pos);執行時
	// 會第二次進入此函數,最終確定滾動塊位置,並且會
	// 直接到default分支,所以在此處設置編輯框中顯示數值
	default:
		SetDlgItemInt(IDC_HSCROLL_EDIT, pos);
		return;
	}

	// 設置滾動塊位置
	m_horiScrollbar.SetScrollPos(pos);

	CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}

  6、編譯運行程序,彈出結果對話框,可以自己拖動滾動塊看是否能正常滾動,並且編輯框中也能顯示正確的數值。效果如下:

  至於垂直滾動條,其實與水平滾動條類似,大家可以自己寫寫垂直滾動條的例子。

 


免責聲明!

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



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