代码参考了http://download.youkuaiyun.com/detail/clever101/6790283#comment
把视图左右分割,在右边的视图内显示图片,并使其能够自动排列
先上一个效果图:
步骤:
1.建立单文档视图工程ListDemoView
2.分割视图:
用类向导再建立一个以CView类为基类的类ListDemoViewLeft类,作为左侧视图类,将原来工程内自动形成的ListDemoView类作为右侧视图类
重载OnCreateClient的函数
重载OnCmdMsg函数(由于分割视图后 可能会出现视图无法响应菜单消息 因此需要重载这个函数)
MainFrm.h中加入:
public:
BOOL OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext);//分割视图
BOOL OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo);//分割视图响应菜单消息
private:
CSplitterWnd m_splitterWnd;//用于分割窗口
再MainFrm.cpp中加入:
BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext)
{
// TODO: Add your specialized code here and/or call the base class
m_splitterWnd.CreateStatic(this,1,2);
CRect rect;
GetClientRect(&rect);
if (!m_splitterWnd.CreateView(0,0,RUNTIME_CLASS(ListDemoViewLeft),CSize(rect.Width()/4,rect.Height()),pContext)||
!m_splitterWnd.CreateView(0,1,RUNTIME_CLASS(CListDemoView),CSize(rect.Width()*3/4,rect.Height()),pContext))
{
return FALSE;
}
return TRUE;
}
//重载OnCmdMsg 使得分割视图中,每个view能够接收到菜单响应消息
//先调用缺省函数,如果命令没有被处理(缺省的OnCmdMsg返回FALSE),则获取当前所有视图指针,调用每个视图的OnCmdMsg函数,将命令消息传送给每个视图。
BOOL CMainFrame::OnCmdMsg(UINT nID, int nCode, void* pExtra, AFX_CMDHANDLERINFO* pHandlerInfo)
{
if ( CFrameWnd::OnCmdMsg(nID, nCode, pExtra, pHandlerInfo) )
return TRUE;
CListDemoDoc* pDoc = ( CListDemoDoc* ) GetActiveDocument ();
POSITION pos = NULL;
if ( pDoc != NULL )
pos = pDoc->GetFirstViewPosition ();
while ( pos != NULL )
{
CView* pNextView = pDoc->GetNextView ( pos );
if ( pNextView != GetActiveView() )
{
if ( pNextView->OnCmdMsg ( nID, nCode, pExtra, pHandlerInfo ) )
return TRUE;
}
}
return FALSE;
}
3. 在右侧视图内实现CListCtrl控件
该实现利用了GDI+,因此需要现在stdafx.h中加入:
#include <gdiplus.h> //GDI+声明,可以GDI/GDI+混合使用
#pragma comment(lib, "gdiplus.lib")
using namespace Gdiplus;
在ListDemoView.h中加入菜单项:
显示缩略图 设置ID为ID_SHOWPIC
在类向导中 在ListDemoView类中加入该菜单项的COMMAND消息响应函数OnShowpic
在ListDemoView.h中加入代码:
protected:
void InitListCtrl();
private:
CListCtrl m_listCtrl;
CImageList m_imageList;
short m_imageW;
short m_imageH;
HANDLE m_handle; //循环插入图片线程的句柄
GdiplusStartupInput m_gdiplusStartupInput; //只需要在程序运行最开始初始化一次
ULONG_PTR m_gdiplusToken; //只需要在程序运行最开始初始化一次
private:
bool insertImageItem(TCHAR* path);
public:
void UpdateImageList();
在ListDemoView.cpp中加入代码:
构造函数中加入代码
m_imageW = 0;
m_imageH = 0;
m_imageH = 0;
OnCreate函数:
int CListDemoView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
CRect rect;
GetClientRect(&rect);
//动态创建listctrl控件 LVS_AUTOARRANGE设置后图标可随窗口大小的变化自动排列
m_listCtrl.Create(LVS_SINGLESEL|LVS_ICON|WS_CHILD|WS_VISIBLE|LVS_SINGLESEL|LVS_AUTOARRANGE,CRect(rect),this,IDC_LIST_DIVISION);
InitListCtrl();
return 0;
}
加入其他函数:
void CListDemoView::InitListCtrl()//ListCtrl与imagelist的初始化
{
GdiplusStartup(&m_gdiplusToken, &m_gdiplusStartupInput, NULL ); //初始化GDI+
m_listCtrl.SetExtendedStyle(LVS_EX_FULLROWSELECT|LVS_EX_GRIDLINES);//设置当前的列表视图控件扩展的样式
m_listCtrl.SetIconSpacing(CSize(140, 130)); //设置图片间距
//设置缩略图大小,宽120 高90
m_imageW = 120;
m_imageH = 90;
m_imageList.Create(m_imageW, m_imageH, ILC_COLORDDB|ILC_COLOR32, 1, 1); //wide of picture is 120,height is 90
m_listCtrl.SetImageList(&m_imageList,LVSIL_NORMAL); //CImageList associates CListCtrl//LVSIL_NORMAL:大图标方式进行图像列表,LVSIL_SMALL为小图标,LVSIL_STATE 以图像状态进行图像列表
//UpdateImageList();
}
void CListDemoView::OnShowpic()//菜单响应函数
{
DWORD dwID;
//CreateThread在主线程的基础上创建一个新线程。否则图片无法实时显示
m_handle = CreateThread(NULL, 0, GetImageThread, this, 0, &dwID);
}
DWORD WINAPI GetImageThread( LPVOID lpParam )
{
CListDemoView *pPicListDlg = (CListDemoView*)lpParam;
pPicListDlg->UpdateImageList();
return 1;
}
void CListDemoView::UpdateImageList()
{
CString imagename;
int a = 1, i =0;
//while(a<=7)
while(i<50)
{
a = i%7+1;//用于循环输出图像,为方便输出,此处在image文件下存的图片都是1.jpg,2.jpg一直到7.jpg的名称
imagename.Format(_T("image/%d.jpg"), a);
TCHAR* imagename_t = new TCHAR[50];
imagename_t = imagename.GetBuffer(imagename.GetLength());//cstring convert to tchar*
imagename.ReleaseBuffer();
insertImageItem(imagename_t);
Sleep(300);
i++;
}
}
bool CListDemoView::insertImageItem(TCHAR* path)
{
Bitmap bmp(path); //传入图片路径
int sourceWidth = m_imageW; //获得图片宽度,这个120和创建的120保持相同。
int sourceHeight = bmp.GetHeight(); //获得图片宽度
if(sourceHeight>m_imageH) //和m_ImageList.Create(120…)有很大关系,如果小于设
{
sourceHeight= m_imageH; //定的宽度,图片将无法显示
}
Bitmap* pThumbnail = (Bitmap*)bmp.GetThumbnailImage(sourceWidth, sourceHeight, NULL, NULL); //设定缩略图的大小
HBITMAP hBmp;
pThumbnail->GetHBITMAP(Color(255,255,255),&hBmp);
CBitmap *pImage = CBitmap::FromHandle(hBmp); //转换成CBitmap格式位图
TCHAR drive[MAX_PATH] = _T("");
TCHAR dir[MAX_PATH] = _T("");
TCHAR fname[MAX_PATH] = _T("");
TCHAR ext[MAX_PATH] = _T("");
_wsplitpath(path ,drive, dir,fname, ext);
CString itemName(fname);
itemName.Append(ext);
int index = m_imageList.Add(pImage,RGB(255,255, 255));
m_listCtrl.InsertItem(index, itemName, index); // itemName,你自己设法得到图片片的名字。名字会显示在图片下
return true;
}