轉自:http://www.jizhuomi.com/software/191.htmlhtml
滾動條控件簡介app
滾動條你們也很熟悉了,Windows窗口中不少都有滾動條。前面講的列表框和組合框設置了相應屬性後,若是列表項顯示不下也會出現滾動條。滾動條分爲水平滾動條(Horizontal Scroll Bar)和垂直滾動條(Vertical Scroll Bar)兩種。滾動條中有一個滾動塊,用於標識滾動條當前滾動的位置。咱們能夠拖動滾動塊,也能夠用鼠標點擊滾動條某一位置使滾動塊移動。less
從滾動條的建立形式來分,有標準滾動條和滾動條控件兩種。像列表框和組合框設置了WS_HSCROLL 或WS_VSCROLL風格之後出現的滾動條,不是一個獨立的窗口,而是這些窗口的一部分,這就是標準滾動條。而滾動條控件是一個獨立的窗口,它能夠得到焦點,響應某些操做。函數
滾動條控件的建立工具
MFC也爲滾動條控件的操做提供了類,即爲CScrollBar類。this
滾動條控件的建立依然有兩種方式,一種是直接在Toolbox中將滾動條控件拖入對話框模板,而後添加控件變量使用,另外一種就是用CScrollBar類的Create成員函數動態建立。這兩種方式適用於不一樣的場合。spa
CScrollBar類的成員函數Create的函數原型以下:指針
virtual BOOL Create(
DWORD dwStyle,
const RECT& rect,
CWnd* pParentWnd,
UINT nID
);code
此函數與其餘控件類的Create函數原型基本相同。參數dwStyle指定滾動條控件的風格,rect指定滾動條控件的位置和尺寸,pParentWnd爲指向滾動條控件父窗口的指針,nID指定滾動條控件的ID。下面簡單介紹幾個主要的滾動條控件風格,更加具體的能夠查閱MSDN。htm
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, *LPSCROLLINFO; typedef SCROLLINFO CONST *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 時,滾動條將被隱藏。參數bRedraw 表示是否須要重繪滾動條,若是爲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工程,名稱設置爲「Example26」。
2. 在自動生成的對話框模板IDD_EXAMPLE26_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. 在對話框初始化時,咱們須要設置滾動條的滾動範圍和初始位置,並在編輯框中顯示初始位置,那麼須要修改CExample26Dlg::OnInitDialog()函數爲:
BOOL CExample26Dlg::OnInitDialog() { CDialogEx::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range.
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); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here // 設置水平滾動條的滾動範圍爲1到100
m_horiScrollbar.SetScrollRange(1, 100); // 設置水平滾動條的初始位置爲20
m_horiScrollbar.SetScrollPos(20); // 在編輯框中顯示20
SetDlgItemInt(IDC_HSCROLL_EDIT, 20); return TRUE; // return TRUE unless you set the focus to a control
}
5. 如今滾動條還不能正常滾動,而且編輯框中數字也不隨滾動改變。根據上面所講,咱們能夠重載CExample26Dlg類的OnHScroll函數。具體操做爲,在CExample26Dlg類的屬性頁面的工具欄上點「Messages」按鈕,找到WM_HSCROLL消息,添加響應函數就能夠了。
OnHScroll函數重寫後以下:
void CExample26Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default
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. 編譯運行程序,彈出結果對話框,能夠本身拖動滾動塊看是否能正常滾動,而且編輯框中也顯示了正確的數值。效果以下:
至於垂直滾動條,其實與水平滾動條相似,你們能夠本身寫寫垂直滾動條的例子。滾動條控件的內容就講到這裏了,比較基礎,但這些是之後應用滾動條控件的必知內容。
PS:關於OnHScroll函數重寫的幾個疑問。
一、註釋掉while循環中部分代碼,程序運行沒有影響。
void CExample26Dlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar) { // TODO: Add your message handler code here and/or call default
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); }
二、關於default的註釋應該寫錯了,改爲:
//最下面的CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);執行時會第二次進入此函數,最終肯定滾動塊位置,而且會直接到default分支,因此在此處設置編輯框中顯示數值
若是把 SetDlgItemInt(IDC_HSCROLL_EDIT, pos); 語句拿出來(剪切)放到 m_horiScrollbar.SetScrollPos(pos); 下面,其他代碼不變,則程序運行無影響。