在上一篇中,我們使用老式的做法添加滾動條,他雖然運行良好,但是,效率不高.我們在win32之後有了新式的做法:
和已經可以完成前面的所有功能,並且新添加了兩個特性:
1.SetScrollInfo:第一個功能涉及卷動方塊的大小。卷動方塊大小在上一個博客中的程序中是固定的。然而,在您可能使用到的一些Windows應用程序中,卷動方塊大小與在窗口中顯示的文件大小成比例。顯示的大小稱作「頁面大小」。算法為:
==.
可以使用SetScrollInfo來設置頁面大小(從而設置了卷動方塊的大小),
2.GetScrollInfo:增加了第二個重要的功能,或者說它改進了目前API的不足。假設您要使用65,536或更大單位的范圍,這在16位Windows中是不可能的。當然在Win32中,函數被定義為可接受32位參數,因此是沒有問題的。(記住如果使用這樣大的范圍,卷動方塊的實際物理位置數仍然由卷動列的圖素大小限制)。然而,當使用SB_THUMBTRACK或SB_THUMBPOSITION通知碼得到WM_VSCROLL或WM_HSCROLL消息時,只提供了16位數據來指出卷動方塊的目前位置。通過GetScrollInfo函數可以取得真實的32位值。
語法為:
SetScrollInfo (hwnd, iBar, && nMin ; nMax ; nPos ; nTrackPos ; *= (si) ;
fMask是一個flag的作用:
1.SetScrollInfo函數使用SIF_RANGE旗標時,必須把nMin和nMax字段設定為所需的滾動條范圍。GetScrollInfo函數使用SIF_RANGE旗標時,應把nMin和nMax字段設定為從函數傳回的目前范圍。
2.SIF_POS旗標也一樣。當通過SetScrollInfo使用它時,必須把結構的nPos字段設定為所需的位置。可以通過GetScrollInfo使用SIF_POS旗標來取得目前位置。
3.使用SIF_PAGE旗標能夠取得頁面大小。用SetScrollInfo函數把nPage設定為所需的頁面大小。GetScrollInfo使用SIF_PAGE旗標可以取得目前頁面的大小。如果不想得到比例化的滾動條,就不要使用該旗標。
4.當處理帶有SB_THUMBTRACK或SB_THUMBPOSITION通知碼的WM_VSCROLL或WM_HSCROLL消息時,通過GetScrollInfo只使用SIF_TRACKPOS旗標。從函數的傳回中,SCROLLINFO結構的nTrackPos字段將指出目前的32位的卷動方塊位置。
5.在SetScrollInfo函數中僅使用SIF_DISABLENOSCROLL旗標。如果指定了此旗標,而且新的滾動條參數使滾動條消失,則該滾動條就不能使用了(下面會有更多的解釋)。
6.SIF_ALL旗標是SIF_RANGE、SIF_POS、SIF_PAGE和SIF_TRACKPOS的組合。在WM_SIZE消息處理期間設置滾動條參數時,這是很方便的(在SetScrollInfo函數中指定SIF_TRACKPOS後,它會被忽略)。這在處理滾動條消息時也是很方便的。
在上一篇文章的代碼中,我們發現設定滾動條范圍的時候,我們拉到底,會出現最後一行在一頁的最上面的情況,其實我們只需要將最後一行放在底部就行了.所以,我們應該這樣子做》
iVscrollMax = max (, NUMLINES - cyClient /, iVscrollMax, TRUE) ;
但是,在新的滾動條函數在,無需這樣子設置,他已經幫你處理好了這個問題.於是:si可以大膽的設置為NUMLINES-1;
可以向下面這樣設置SCROLLINFO這個結構體:
si.cbSize = = SIF_RANGE |= = NUMLINES - = cyClient /&
綜上所述:我們應該這樣子去用新的函數做一個滾動條:
一下全都是在窗口函數中(CALLBACK)
1.設定變量:
] ;
2.在WM_CREARTE中:
=&== (tm.tmPitchAndFamily & ? : ) * cxChar / = tm.tmHeight + = * cxChar + * ;
3.在WM_SIZE中:
= LOWORD (lParam) ; = HIWORD (lParam) ; = = SIF_RANGE |= = NUMLINES - = cyClient /& = = SIF_RANGE |= = + iMaxWidth /= cxClient /& ;
4.在WM_VSCROLL中(橫向也是如此處理,在此處不貼代碼了):
si.cbSize = =& = ==- = += -=+== =& & (si.nPos != iVertPos) , cyChar * (iVertPos -
5.在WM_PAINT中:
= BeginPaint (hwnd, & = =&si) ; = &si) ; = = max (, iVertPos + ps.rcPaint.top / cyChar) ; = min ( NUMLINES - + ps.rcPaint.bottom / cyChar) ; (i = iPaintBeg ; i <= iPaintEnd ; i++= cxChar * ( -= cyChar * (i - + *|+ * cxCaps + *|
注1:這些代碼無法粘貼之後直接運行,因為少了一部分代碼,包括一個頭文件和WIN_MAIN函數.完整代碼在github上面:
注2:此代碼在VS2012下完成.
完整代碼地址:https://github.com/shangbo/windows_api/tree/master/scroll2