回顧:chrome
剛剛寫完,由於是分期寫的,因此最初想好好作一下的文章格式半途而廢了~說的也許會有點囉嗦,可是全部的基礎用到的技術細節應該都用到了。app
若是還有什麼疑問,請回復留言,我會盡力解答。ide
若是有錯誤,請指正。函數
這裏全部使用到的內容在VS2010中均能正常運行。網站
可運行程序的截圖:this
CListCtrl控件的建立spa
若是一個CListCtrl控件對象和dialog上的控件已經綁定,那麼能夠跳過這個這一步,由於綁定了的對象已經完成了建立。翻譯
可是若是要在dialog上憑空建立出來一個列表控件,那麼就須要瞭解CListCtrl類的成員函數:Create指針
先看這個函數的原型:code
BOOL Create( DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID );
第一個參數是用來聲明這個列表的風格,具體風格以下 :
一下翻譯這麼多,有點累,看來個人英語仍是太差,否則怎麼會以爲累~
第二個參數:rect
這個參數就是你所建立的CListCtrl的位置,以及大小。再也不作過多介紹了
第三個參數:pParentWnd
這個參數用來指定父窗口,通常是一個CDialog對象指針,須要注意的是,千萬不能是NULL。
第四個參數:nID
控件ID,這個不用多說了,每一個看控件都有的。
CListCtrl風格修改
可是若是你已經建立好了一個ListCtrl控件,那麼你爲其聲明瞭一個CListCtrl控件,那麼上面的Create函數你就能夠跳過去了~
可是,風格老是要設置的,因此在這裏,有一個函數能夠調用,專門用來設置風格~
LONG SetWindowLong( HWND hWnd, // handle to window int nIndex, // offset of value to set LONG dwNewLong // new value );
CListCtrl的窗口句柄是public的,能直接獲取。
第二個參數添加:GWL_STYLE,目的就是爲了設置新的風格。
第三個參數就是風格的組合了
這個函數的具體內容請看MSDN,我這就再也不多說了~
CListView的擴展風格
CListCtrl能夠設置的風格:
LVS_EX_GRIDLINES //繪製表格
LVS_EX_SUBITEMIMAGES
LVS_EX_CHECKBOXES //帶複選框
LVS_EX_TRACKSELECT //自動換行
LVS_EX_HEADERDRAGDROP
LVS_EX_FULLROWSELECT //選擇整行
LVS_EX_ONECLICKACTIVATE//單擊激活
LVS_EX_TWOCLICKACTIVATE//雙擊激活
LVS_EX_FLATSB//扁平滾動條
LVS_EX_REGIONAL
LVS_EX_INFOTIP
LVS_EX_UNDERLINEHOT
LVS_EX_UNDERLINECOLD
LVS_EX_MULTIWORKAREAS//多工做區
以上風格設置可使用下面的CListCtrl成員函數來設置:
DWORD SetExtendedStyle( DWORD dwNewStyle );
如今有代碼以下:
1 void CMyRisingDlg::ListCtrlInitial() 2 { 3 CRect lc_rect; 4 DWORD dwStyle = ::GetWindowLong(m_LCTable.m_hWnd, GWL_STYLE); 5 dwStyle &= ~(LVS_TYPEMASK); 6 dwStyle &= ~(LVS_EDITLABELS); 7 SetWindowLong(m_LCTable.m_hWnd, GWL_STYLE,dwStyle |LVS_REPORT | LVS_NOLABELWRAP | LVS_SHOWSELALWAYS); 8 m_LCTable.SetExtendedStyle(LVS_EX_ONECLICKACTIVATE|LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES); 9 m_LCTable.GetWindowRect(&lc_rect); 10 DWORD dwListLength = lc_rect.Width() / 3; 11 m_imagelist.Create(16, 16, ILC_COLORDDB|ILC_MASK, 0, 1); 12 13 m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON1)); 14 m_imagelist.Add(AfxGetApp()->LoadIcon(IDI_ICON2)); 15 m_LCTable.SetImageList(&m_imagelist, LVSIL_SMALL); 16 m_LCTable.InsertColumn(0, _T("Name"), LVCFMT_LEFT | LVCFMT_IMAGE, dwListLength); 17 m_LCTable.InsertColumn(1, _T("PathName"), LVCFMT_LEFT, dwListLength); 18 m_LCTable.InsertColumn(2, _T("Create Time"), LVCFMT_LEFT, dwListLength + 3); 19 20 m_LCTable.InsertItem(0, LPSTR_TEXTCALLBACK);21 22 }
很顯然,這個函數的功能是初始化一個ListCtrl。從代碼裏面可以看出來,在初始化上,其實主要的就是風格設置。而後最一行的函數調用是爲了作虛擬列表,CListCtrl的虛擬列表內容我會在新的隨筆中介紹。
上面的幾個比較主要的成員函數調用,SetExtendedStyle函數就再也不多說了,能夠參考樣式以及上面的各類風格,或者直接去看MSDN。
而後下面的SetImageList是爲了給列表上主要的首子項添加上文件圖標,正在作,還未完成。不過上面的程序界面截圖中能看到首列有圖標,那個只是目前應付一下的~
接下來要比較重點的介紹InsertClumn函數:
這個函數是用來完成列的插入的。或者說,創建了一個索引,或者鏈表頭。由此函數調以後才能調用InsertItem函數,不然是無效的,函數剛一調用,估計就直接返回個0了。
這個函數看下MSDN的介紹:
int InsertColumn( int nCol, const LVCOLUMN* pColumn );
int InsertColumn( int nCol, LPCTSTR lpszColumnHeading, int nFormat = LVCFMT_LEFT, int nWidth = -1, int nSubItem = -1 );
Return Value
The index of the new column if successful or -1 otherwise.
這個函數有兩種形式,可是我只介紹第二種,緣由爲啥你應該很清楚~。這裏第一個參數就是列號了,很少說。第二個參數是列名,也不用太羅嗦,第三個是格式,須要簡單說一下。
nFormat參數有一下的幾種形式:LVCFMT_LEFT, LVCFMT_RIGHT, or LVCFMT_CENTER.另外還有LVCFMT_IMAGE,默認狀況下是從左往右的,也就是咱們的書寫順序。另外須要注意的是,其實這個參數通常來說的話都是直接使用LEFT參數的,緣由就是若是你使用了center或者right參數,會直接致使一個後果:就是這列的所有內容,也都是對應的居中或者置右。另外若是使用了LVCFMT_IMAGE參數,那麼就會在最左端添加圖片的基礎上,默認爲LEFT風格,這點仍是須要注意的。
目前除了InsertItem函數以外,其他的基礎操做設置就差很少了,至於其餘的一些操做我等會也還須要再看~
而後接下來說下如何添加首項的圖片。
我以爲添加這個圖片的目的主要仍是爲了提供更好的用戶體驗。由於若是有圖片的話,對大多數用戶來講會提供一個很便利的途徑來知道這個文件的類型屬性。畢竟大多數的用戶是不會去根據文件後綴來判斷這個文件究竟是幹什麼的~
廢話很少說,先看一個類:CImageList.
接着貼MSDN:
An 「image list」 is a collection of same-sized images, each of which can be referred to by its zero-based index. Image lists are used to efficiently manage large sets of icons or bitmaps. All images in an image list are contained in a single, wide bitmap in screen device format. An image list may also include a monochrome bitmap that contains masks used to draw images transparently (icon style). The Microsoft Win32 application programming interface (API) provides image list functions that enable you to draw images, create and destroy image lists, add and remove images, replace images, merge images, and drag images.
大意以下:
一個圖像列表是一樣大小圖像的集合,每一個成員都可以經過以0爲起始的目錄來訪問(其實就是順序表訪問)。圖像列表控件可以用來有效的管理大數量的圖標或位圖。在圖像列表中的全部圖片都在屏幕設備格式中包含一個單獨的,寬(這裏不知道怎麼翻譯)的位圖。一個圖像列表控件也可能包含一個包含繪製透明圖像任務的單色位圖(這裏不是很肯定)。
後面的就不翻譯了,沒什麼用。
上面我貼的那個函數裏CImageList的使用也比較明瞭,簡單介紹下:
對象建立完以後並不須要當即初始化,還不錯。而後首先要調用其中的Create函數,就是建立一個初始化一個列表並付給對象,MSDN基本就這個意思。這裏再貼一下函數原型:
BOOL Create( int cx, int cy, UINT nFlags, int nInitial, int nGrow );
BOOL Create( UINT nBitmapID, int cx, int nGrow, COLORREF crMask );
BOOL Create( LPCTSTR lpszBitmapID, int cx, int nGrow, COLORREF crMask );
BOOL Create( CImageList& imagelist1, int nImage1, CImageList& imagelist2, int nImage2, int dx, int dy );
BOOL Create( CImageList* pImageList );
Return Value
Nonzero if successful; otherwise 0.
很顯然,在個人程序裏面調用的函數是其中的第一個,因此我這就只介紹第一個了~前兩個參數很明顯,就是這個圖片的尺寸。我在這裏的建議仍是,提供16*16的圖片比較合適。我曾經想過作8*8的,結果,過小了……實在不合適。這個尺寸是我作列表比較推薦的。第三個參數很顯然就是個標誌位,用來設置風格的。
具體風格以下:
ILC_COLOR | Use the default behavior if none of the other ILC_COLOR* flags is specified. Typically, the default is ILC_COLOR4; but for older display drivers, the default is ILC_COLORDDB. |
ILC_COLOR4 | Use a 4-bit (16 color) device-independent bitmap (DIB) section as the bitmap for the image list. |
ILC_COLOR8 | Use an 8-bit DIB section. The colors used for the color table are the same colors as the halftone palette. |
ILC_COLOR16 | Use a 16-bit (32/64k color) DIB section. |
ILC_COLOR24 | Use a 24-bit DIB section. |
ILC_COLOR32 | Use a 32-bit DIB section. |
ILC_COLORDDB | Use a device-dependent bitmap. |
ILC_MASK | Uses a mask. The image list contains two bitmaps, one of which is a monochrome bitmap used as a mask. If this value is not included, the image list contains only one bitmap. |
我上面的函數在這裏使用的是後兩個參數的組合。DDB的意思是設備相關位圖,與之相反的就是大名鼎鼎的DIB了,不過這裏沒有。個人MSDN版本比較老,是給VC6.0作的,有興趣的能夠去MSDN網站上看看,新版的CImageList有沒有提供DIB的。
不過我以爲,彷佛個人那個代碼裏,ILC-MASK參數貌似沒什麼用處,回頭刪掉。
而後nInitial參數,就是Imagelist對象中初始化後就包含的圖像數目,MSDN:Number of images that the image list initially contains.
最後一個參數:nGrow 原文:Number of images by which the image list can grow when the system needs to resize the list to make room for new images. This parameter represents the number of new images the resized image list can contain.
其實這個參數倒不是很重要,可是,能牽扯到效率問題。若是每次新添加一個圖片就要申請一塊新的內存,是否是有點效率過低了?因此不如一次申請多個,這樣效率更高一下些。可是若是你的列表通常只須要10個,可是你每次resize以後會變成100個,就形成了浪費。因此仍是須要注意一下的,可是小列表設置爲5之內的數應該就好了。
這個函數介紹完了,就要接着講添加的問題。不過這個仍是比較簡單的。能夠直接調用add成員函數。
int Add( CBitmap* pbmImage, CBitmap* pbmMask );
int Add( CBitmap* pbmImage, COLORREF crMask );
int Add( HICON hIcon );
Return Value
Zero-based index of the first new image if successful; otherwise – 1.
這裏提供了三個函數,前兩個都是和Bitmap相關的,暫且不談,只談第三個。
第三個函數,很簡單,只要一個圖標資源的句柄就能夠了。獲取這個句柄資源,在MFC中有一種很簡單的方法:直接調用App類的LoadIcon函數。
AfxGetApp()->LoadIcon(IDI_ICON1)
裏面直接添加上工程中創建好的圖標資源ID就行了。
不過這個成員函數只限CWinApp類的對象使用。另一種方法是調用SDK的函數,其中hInstance就是句柄,這裏應該直接添加app的m_hwnd,應該是的,我還沒試過。第二參數要使用MAKEINTRESOURCE宏轉一下就能夠了。
接下來就是如何將圖片綁定到列表頭部了。
在兩個對象都建立完成後,只要調用CListCtrl函數的一個成員函數就能夠了:
CImageList* SetImageList( CImageList* pImageList, int nImageList );
Return Value
A pointer to the previous image list.
Parameters
pImageList
Pointer to the image list to assign.
nImageList
Type of image list. It can be one of these values:
不用說太多,我這裏第二個參數直接使用的LVSIL_SMALL選項,畢竟16*16的圖片絕對不大。
而後這樣就實現了綁定,可是此時你須要知道,雖然兩個對象綁定了,可是ImageList對象依舊可以獨立於ListCtrl進行修改操做。
那麼綁定了以後呢?仍是要看InsertItem函數。
InsertItem函數形式有好幾個,這裏須要使用這種形式:
int InsertItem( int nItem, LPCTSTR lpszItem, int nImage );
這個形式的函數專門添加了nImage這個參數,目的就是爲了實現列表的添加。
nImage的選擇是對應ImageList中的圖像尋址功能,若是在ImageList中添加好了圖片,那麼InsertItem函數就會根據這個參數的值取尋找對應的圖片,而後直接將其添加到列表中。
虛擬列表我會在新的隨筆中介紹,並會介紹一下個人思考過程。