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  这篇是最好的
感谢阅读至此,但愿有所帮助。
相关文章
相关标签/搜索