在分割的视图内实现CListCtrl控件 结合CImageList实现图片的自动排列显示

代码参考了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;
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;
}

 
 
 
 
 
 
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值