CMFCShellList和自定義ShellList結合使用,達到「直接瀏覽縮略圖,雙擊打開圖片」

在GOPaint的設計研究過程當中,我一直但願可以實現這樣的結果(A B C 3個步驟)
在我以前的博客裏面,曾經有過縮略圖顯示的現就( http://www.cnblogs.com/jsxyhelu/p/5493329.html   ),也應用到了實際的項目中。可是如今過了一段時間後回頭再看,當時的實現放吧是粗糙的。基於MFC已經提供的基礎庫,經過c++本身的重載機制,應該可以獲得精巧的實現,可是確定須要去重寫一些東西。
爲了解決問題,達到效果,進行了一些研究。 
1、CMFCShellList和CMFCShellTree基本結合;
這兩個控件是新出現的,使用起來比較簡單。
 
DIalog的方便之處就在於「所見及所得」,這裏綁定控件變量。
在initdialog中添加兩句,就能獲得效果
    m_ctrlShellList.ModifyStyle(LVS_TYPEMASK, LVS_ICON);
    m_ctrlShellTree.SetRelatedList( &m_ctrlShellList);
Tree的結果和List的結果是級聯的。可是顯示不了縮略圖,只可以顯示圖標。
2、對CMFCShellList和CMFCShellTree的繼承和研究;
若是要更好地使用這兩個類,必須首先繼承以後使用,在這個過程當中,我纔可以重寫函數和事件:
在原始的mfcshelllistctrl控件中,若是雙擊其中的文件(圖片)的話,是採用默認的打開程序打開文件(圖片),那麼我要把這個修改爲使用我本身的程序來打開圖片,因此首先就須要進行CMFCShellListCtrl的重載
# pragma once
# include  "afxshelllistctrl.h"
class CGOShellListCtrl  :
     public CMFCShellListCtrl
{
public :
    CGOShellListCtrl( void);
     ~CGOShellListCtrl( void);
    DECLARE_MESSAGE_MAP()
    afx_msg  void OnNMDblclk(NMHDR  *pNMHDR, LRESULT  *pResult);
};
 
修改 OnNMDblclk事件
void CGOShellListCtrl : :OnNMDblclk(NMHDR  *pNMHDR, LRESULT  *pResult)
{
    LPNMITEMACTIVATE pNMItemActivate  =  reinterpret_cast <LPNMITEMACTIVATE >(pNMHDR);
    CString Filename;  
     for( int i = 0; i <GetItemCount(); i ++)    
    {    
         if( GetItemState(i, LVIS_SELECTED)  == LVIS_SELECTED )    
        {    
            GetItemPath(Filename,i);  
            AfxMessageBox(Filename);    
        }    
    }    
     *pResult  =  0;
}
獲得可以顯示雙擊文件絕對地址的目的:
那麼下一步,須要將這個地址傳入主程序,這個方法不少。
一樣,也能夠對CMFCShellTreeCtrl進行重載,獲得當前的目錄地址。
3、可是仍是須要顯示縮略圖;
可是,核心問題仍是沒有解決,如今仍是顯示不了縮略圖。
一開始我想經過重寫List的CUSTOMDRAW事件來達到效果,可是研究一些資料以後,能夠修改ListCtrl的樣式,卻沒法修改主要內容。雖然CUSTOMDRAW中也提供了控價重構的機制,可是隱藏在許多宏中,不方便使用;
最後我開始反思以前個人ThumbNail是如何實現的,最後決定仍是採用imagelist綁定的方法來解決問題。
這時,能夠確定基本是不用CMFCShellListCtrl了,而是要繼承原始的CListCtrl,基本思路就是從CMFCTreeListCtrl中得到路徑名稱,然後在自定義的List控件中顯示出來。而且還要截獲List的點擊事件,那麼得到選擇圖片的絕對地址。
其實在這個過程當中,過濾後綴名等操做也是能夠完成的。
4、DLG下的實驗
爲了進行試驗,我首先在DLG下面進行了實驗。效果良好:
雙擊打開圖片,感受速度上面仍是有些問題。
這個DLG的例子能夠參考附錄裏面的 thumbnail 例子,基本就是根據其修改的。
5、融合到GOPaint中去:
GOPaint是我目前正在作的OpenCV圖像處理框架庫,力圖可以提供大中型圖像處理軟件所需的基礎環境。那麼縮略圖也是必須的一個環節。
採用的是浮動窗口,比較美觀。畢竟要把主要區域用出來,顯示圖片。
在這裏融合的時候,我就有意識地將代碼進行合併。
對於ListCtrl和CMFCShellTreeCtrl分別進行了重載。這裏仍是選擇了ListCtrl進行重載,由於CMFCShellListCtrl中的優秀特性這裏用不起來。
SplitePane繼承於CDockablePane,是一個懸浮框類。那麼在這個懸浮框中我將
 CGOShellTreeCtrl m_wndTree;
 CGOListCtrl m_ListThumbnail;
 CPaneSplitter m_wndSplitter;
 CImageList m_ImageListThumb;
都放在其中,還包括一些存儲用的變量。這樣的結果就是若是之後在其餘地方須要使用,只須要將這幾個文件拷貝過去複用就能夠了。
 
# pragma once
# include  "afxshelltreectrl.h"
# include  "afxshelllistctrl.h"
# include  "panesplitter.h"
# include  "GOShellTreeCtrl.h"
# include  "GOListCtrl.h"
# include  "afxwin.h"
# include  <vector >
// CSplitePane
class CSplitePane  :  public CDockablePane
{
    DECLARE_DYNAMIC(CSplitePane)
public :
    CSplitePane();
     virtual  ~CSplitePane();
protected :
    DECLARE_MESSAGE_MAP()
public :
    afx_msg  int OnCreate(LPCREATESTRUCT lpCreateStruct);
    afx_msg  void OnSize(UINT nType,  int cx,  int cy);
    afx_msg  void OnDestroy();
public :
    CGOShellTreeCtrl m_wndTree;
    CGOListCtrl m_ListThumbnail;
    CPaneSplitter m_wndSplitter;
    CPaneToolBar m_wndToolbar;
    CImageList m_ImageListThumb;
     int m_nSelectedItem;
     void DrawThumbnails( void);
    std : :vector <CString > m_VectorImageNames;
    BOOL GetImageFileNames( void);
     void GetThumbnailsAndShow( void);
};
 
 
具體的實現代碼已經不重要了,由於原理已經講明白了。這裏的代碼編寫須要對繼承、控件等都有一些瞭解。若是有不清楚的地方能夠跟帖討論。
5、小結:
這樣一個效果,先後作了有2天,6-8個小時。我想還須要增強如下幾個方面的聯繫:
一、對VS環境中提供的幾個新控件的認識。不只是可以瞭解使用,最好是可以找到實現的代碼去跟一根。這樣之後須要實現本身想要的效果的時候有所依據。
MFC自己是系統的、連貫的。它本身的代碼不少時候就是最好的參考;
二、對繼承、複用等面向對象基本原理要增強理解。
三、 解決問題的方法比結果更重要。這個縮略圖的問題能夠說我一直就在思考和想解決,最後仍是下定決心,達到了預計目的,各中過程也比較漫長。如今反思過來看,仍是要牢牢抓住須要解決問題的核心,不要過分耽擱於細節。解決問題的方法必定是有的,相關的資料及時少,也是確定有幫助的;
四、不斷積累。這裏探索的過程和探索的結果,未來都會成爲很好的基礎。
6、參考資料
找到一了一些的例子:
可以直接顯示縮略圖,可是版本比較老了,不少地方須要修改。
二、 http://bbs.csdn.net/topics/390709031  也是提供customeview修改的.
三、codeprojects Thumbnails viewer and image processing using GDI+ and MFC 這篇我跟了一下,效果很好,可是太複雜。
三、最後仍是在本身的之前看過的代碼裏面找到了最合適的例子 thumbnail。原始連接多是codeprojects上的,這裏直接放出代碼。
四、若是想學習DockPane,那麼codeprojects Understanding CDockablePane  這篇是最好的
感謝閱讀至此,但願有所幫助。
相關文章
相關標籤/搜索