CImageList

图像列表控制(CImageList)是相同大小图像的一个集合,每个集合中均以0为图像的索引序号基数,图像列表通常由大图标或位图构成,其中包含透明位图模式。可以利用Windows32位应用程序接口函数API来绘制、建立和删除图像,并能实现增加、删除、替换和拖动图像等操作。图像列表控制提供了控制图像列表的基本方法,这些方法在WINDOWS95及以后版本才能实现。

(一)图像控制的对象结构
 1、图像控制的数据成员
  m_hImageList 连接图像对象的控制句柄

 2、图像控制的建立方法
  CimageList &imageList建立图像控制对象结构
  Create 初始化图像列表并绑定对象

 图像控制的建立方法如下:
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 );
  其中各项参数的含义为:cx定义图像的宽度,单位为象素;cy定义图象的高度,单位为象素;nFlags确定建立图像列表的类型,可以是以下值的组合:ILC_COLOR、ILC_COLOR4、ILC_COLOR8、ILC_COLOR16、ILC_COLOR24、ILC_COLOR32、ILC_COLORDDB和ILC_MASK;nInitial用来确定图像列表包含的图像数量;nGrow用来确定图像列表可控制的图像数量。
  nBitmapID 用来确定图像列表联系的位图标志值;crMask表示颜色屏蔽位;
  LpszBitmapID 用来确定包含位图资源的标识串;
  imagelist1 指向图像列表控制对象的一个指针;nImage1图像列表1中包含的图像数量;imagelist2指向图像列表控制对象的一个指针;nImage2图像列表2中包含的图像数量;dx表示以象素为单位的图像宽度;dy表示以象素为单位的图像高度。
  同样,图像控制的建立也包括两个步骤,首先建立图像列表结构,然后建立图像列表控制。

 3、图像控制的属性类
  图像控制的属性类包括返回m_hImageList.控制句柄GetSafeHandle、取得图像列表中的图像数量GetImageCount、设置图像列表的背景颜色SetBkColor、取得图像列表的背景颜色SetBkColor和取得图像的有关信息SetBkColor。

 4、图像控制的操作方法
  图像控制的操作方法包括将一个图像列表绑定到一个对象上Attach、将对象上的图像列表解除绑定并返回句柄Detach、删除一个图像列表DeleteImageList、将一个图像增加到图像列表中Add和将一个图像从图像列表中删除Remove等。

(二)图像控制的应用技巧
  对于图像控制,同样不能单独使用,必须与列表控制、树控制和标签控制相互结合应用,下面分别介绍其具体应用技巧。
 1、图像控制在列表控制中的应用技巧
  ①设置图像控制CListCtrl::SetImageList的调用格式如下:
CImageList* SetImageList( CImageList* pImageList, int nImageList );
  其返回值是指向前一个图像列表控制的一个指针,如果不存在前一个图像列表则为NULL;其中参数pImageList是指向图像列表的标识,nImageList是图像列表的类型,可以是如下值:
  LVSIL_NORMAL 用大图标方式进行图像列表;
  LVSIL_SMALL 用小图标方式进行图像列表;
  LVSIL_STATE 以图像状态进行图像列表;

  ②取得图像控制CListCtrl::GetImageList的调用格式如下:
CImageList* GetImageList( int nImageList ) const;
  其返回值为指向图像列表控制的指针,其中nImageList用来确定取得返回值的图像列表的 值,其取值与设置图像列表函数相同。

  ③图像控制在列表控制中的应用示例
  CImageList Cil1,Cil2; //定义大小图标像列表
  CVCLISTApp *pApp=(CVCLISTApp *)AfxGetApp();//取得列表控制程序
  Cil1.Create(32,32,TRUE,2,2); //建立32位图像控制
  Cil1.Add(pApp->LoadIcon(IDI_GJ));//增加选中状态图像
  Cil1.Add(pApp->LoadIcon(IDI_XS));//增加非选中状态图像
  Cil2.Create(16,16,TRUE,2,2); //建立16位图像控制
  Cil2.Add(pApp->LoadIcon(IDI_GJ));//增加选中状态图像
  Cil2.Add(pApp->LoadIcon(IDI_XS));//增加非选中状态图像
  m_ListCtrl.SetImageList(&Cil1,LVSIL_NORMAL);//设置大图标控制
  m_ListCtrl.SetImageList(&Cil2,LVSIL_SMALL);//设置小图标控制

 2、图像控制在树控制中的应用技巧
  ①设置图像控制CTreeCtrl::SetImageList的调用格式如下:
CImageList* SetImageList( CImageList * pImageList, int nImageListType );
  其返回值为指向前前一个图像列表的指针,否则为NULL;参数pImageList为指向图像列表的标识,如果pImageList为NULL则所有的图像都将从树控制中被清除;nImageListType为图像列表设置的类型,可以是如下值之一:
  TVSIL_NORMAL 设置正常图像列表,其中包括选中和非选中两种图标;
  TVSIL_STATE 设置图像列表状态,指用户自定义状态;

  ②取得图像控制CTreeCtrl::GetImageList的调用格式如下:
CImageList* GetImageList( UINT nImage );
  如果调用成功则返回图像列表控制指针,否则为NULL;nImage为取得返回值的图像列表类型,其取值和取得图像列表控制完全相同。

  ③图像控制在树控制中的应用示例
CImageList Cil1,Cil2;//定义大小图标像列表
CVCTREEApp *pApp=(CVCTREEApp *)AfxGetApp();//获取应用程序指针
Cil1.Create(16,16,ILC_COLOR,2,2);//建立图像控制
Cil1.Add(pApp->LoadIcon(IDI_PM));//增加选中状态图像
Cil1.Add(pApp->LoadIcon(IDI_CJ));//增加非选中状态图像
m_TreeCtrl.SetImageList(&Cil1,TVSIL_NORMAL);//设置图像控制列表
 然后在树控制的结构定义中进行如下设置:
TCItem.item.iImage=0; //设置未选中图像索引号
TCItem.item.iSelectedImage=1;//设置选中时图像引号

 3、图像控制在标签控制中的应用技巧
  ①设置图像控制CTabCtrl::SetImageList的调用格式
CImageList * SetImageList( CImageList * pImageList );
  其返回值为指向前一个图像列表的指针,如果不存在前一个图像列表则为NULL;pImageList为标识TAB控制的图像列表指针。

  ②取得图像控制CTabCtrl::GetImageList的调用格式
HIMAGELIST GetImageList() const;
  其返回值为指向TAB控制的图像列表指针,如果调用不成功则为NULL。

 
<think>我们正在讨论MFC中的CImageList类,这是一个用于管理图像列表的类,通常与树形控件(CTreeCtrl)、列表控件(CListCtrl)等一起使用,以显示图标。 根据引用内容,我们可以总结出CImageList的基本使用步骤: 1. 创建图像列表:使用Create函数指定图像的大小、颜色格式和初始数量等。 2. 添加图像:使用Add函数添加图标或位图。 3. 将图像列表关联到控件:如CTreeCtrl的SetImageList方法。 4. 使用图像:在插入控件项时指定图像索引。 下面将详细说明每一步,并提供代码示例。 ### 1. **创建CImageList对象** 首先,我们需要在对话框类(或其他窗口类)中声明一个CImageList成员变量: ```cpp class CMyDialog : public CDialogEx { // ... 其他代码 private: CImageList m_imageList; // 图像列表对象 }; ``` ### 2. **初始化图像列表** 通常在对话框的OnInitDialog函数中初始化图像列表。使用Create函数创建图像列表,然后添加图像资源(图标或位图)。 创建图像列表的函数原型: ```cpp BOOL Create( int cx, // 图像的宽度(像素) int cy, // 图像的高度(像素) UINT nFlags, // 图像列表的类型,如ILC_COLOR32(32位真彩色) int nInitial, // 初始图像数量 int nGrow // 当列表需要增长时,每次增长的数量 ); ``` 示例代码(在OnInitDialog中): ```cpp // 创建图像列表,每个图标30x30像素,使用32位色 m_imageList.Create(30, 30, ILC_COLOR32 | ILC_MASK, 1, 1); // 加载图标资源(假设资源ID为IDI_ICON1) HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON1); // 将图标添加到图像列表 m_imageList.Add(hIcon); // 可以继续添加更多图标 HICON hIcon2 = AfxGetApp()->LoadIcon(IDI_ICON2); m_imageList.Add(hIcon2); ``` 注意:如果使用ILC_MASK,则图像列表支持掩码(透明效果)。添加图标时,如果图标背景透明,则会自动使用掩码。 ### 3. **关联图像列表到控件** 将创建好的图像列表设置到控件(如树形控件)中: ```cpp // 假设m_treeCtrl是已经绑定好的树形控件 m_treeCtrl.SetImageList(&m_imageList, TVSIL_NORMAL); ``` 这里的第二个参数TVSIL_NORMAL表示设置的是普通图像列表(包含选中和未选中状态下的图标)。树形控件还可以设置状态图像列表(TVSIL_STATE),用于复选框等状态图标。 ### 4. **在控件中使用图像** 当向控件插入项时,可以指定使用的图像索引。例如,在树形控件中插入节点: ```cpp // 插入根节点,使用图像列表中的第一个图标(索引0)作为未选中图标,第二个图标(索引1)作为选中图标 HTREEITEM hRoot = m_treeCtrl.InsertItem(_T("根节点"), 0, 1, TVI_ROOT); ``` 在InsertItem函数中,参数2是未选中时的图像索引,参数3是选中时的图像索引。如果不需要区分,可以设为相同值。 ### 5. **清理** 当对话框关闭时,CImageList对象会自动销毁,我们不需要手动销毁。但是,如果我们在非对话框类中使用,或者需要提前释放资源,可以调用Detach()函数(如引用[1]中所示)将图像列表句柄与CImageList对象分离,然后销毁图像列表。但在MFC中,通常让对象自动管理即可。 ### 完整示例(在对话框初始化中) 以下是一个完整的OnInitDialog函数示例,展示如何创建图像列表并添加到树形控件: ```cpp BOOL CMyDialog::OnInitDialog() { CDialogEx::OnInitDialog(); // 创建图像列表 m_imageList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 4, 4); // 初始4个,每次增长4个 // 添加图标(假设已添加多个图标资源) HICON hIcon[4]; for (int i = 0; i < 4; i++) { // 图标资源ID分别为IDI_ICON1, IDI_ICON2, ... hIcon[i] = AfxGetApp()->LoadIcon(IDI_ICON1 + i); m_imageList.Add(hIcon[i]); // 加载后可以立即销毁图标句柄,因为图像列表已经复制了图像 DestroyIcon(hIcon[i]); } // 关联到树形控件 m_treeCtrl.SetImageList(&m_imageList, TVSIL_NORMAL); // 添加树节点 HTREEITEM hRoot = m_treeCtrl.InsertItem(_T("根节点"), 0, 0); m_treeCtrl.InsertItem(_T("子节点1"), 1, 1, hRoot); m_treeCtrl.InsertItem(_T("子节点2"), 2, 2, hRoot); m_treeCtrl.Expand(hRoot, TVE_EXPAND); return TRUE; } ``` ### 注意事项 - **图像资源管理**:在将图标添加到图像列表后,如果不再需要原图标句柄,应该调用DestroyIcon销毁,以避免资源泄漏。 - **图像索引**:图像列表中的图像索引从0开始。 - **图像列表的生命周期**:确保图像列表对象的生命周期覆盖控件的使用期。如果图像列表被销毁,控件将无法显示图像。 - **位图支持**:除了图标,还可以使用位图(CBitmap)添加到图像列表,使用Add函数的重载版本:`int Add(CBitmap* pbmImage, CBitmap* pbmMask);` 或 `int Add(CBitmap* pbmImage, COLORREF crMask);`。 ### 高级用法 - **覆盖图像**:可以使用Replace函数替换图像列表中的某个图像。 - **拖放支持**:图像列表支持拖放操作,可以使用BeginDrag、DragEnter等函数实现。 - **自绘图像**:可以使用Draw函数在指定的DC上绘制图像列表中的图像。 [^1]: 引用[1]: MFC ADO用CListCtrl CImageList显示图片。 [^2]: 引用[2]: 该控件常用接口如下。 [^3]: 引用[3]: 重写CSelectView的OnInitialUpdate函数。 §§相关问题§§ 1. 如何在MFC中使用CImageList为列表控件(CListCtrl)添加图标? 2. CImageList如何支持不同大小的图像? 3. 如何动态更换树形控件节点的图标?</think>### MFC CImageList 使用教程 CImageList 是 MFC 中管理图像集合的核心类,常用于为树形控件(CTreeCtrl)、列表控件(CListCtrl)等提供图标支持。以下是详细使用指南: #### 1. **基本使用流程** ```cpp // 在对话框类头文件中声明 class CMyDialog : public CDialog { CImageList m_imageList; // 图像列表对象 CTreeCtrl m_treeCtrl; // 树形控件 }; // 在OnInitDialog()中初始化 BOOL CMyDialog::OnInitDialog() { // 创建图像列表 (30x30像素,32位色) m_imageList.Create(30, 30, ILC_COLOR32 | ILC_MASK, 4, 1); // 加载图标资源 (IDI_ICON1为资源ID) HICON hIcon = AfxGetApp()->LoadIcon(IDI_ICON1); m_imageList.Add(hIcon); // 添加图标到图像列表 // 关联到树形控件 m_treeCtrl.SetImageList(&m_imageList, TVSIL_NORMAL); // 插入带图标的节点 (参数2:未选中图标索引,参数3:选中图标索引) m_treeCtrl.InsertItem(_T("节点文本"), 0, 0, TVI_ROOT); // 释放图标句柄 DestroyIcon(hIcon); return TRUE; } ``` 关键步骤: 1. 使用 `Create()` 初始化图像列表[^2][^3] 2. 用 `LoadIcon()` 加载图标资源[^2] 3. 通过 `Add()` 添加图标到图像列表[^1][^3] 4. 用 `SetImageList()` 关联到控件[^1][^3] 5. 插入项时指定图标索引[^3] #### 2. **核心方法详解** | 方法 | 参数说明 | 示例 | |------|----------|------| | `Create()` | `(宽度, 高度, 标志, 初始数量, 增长量)` | `Create(16,16,ILC_COLOR32,5,1)` | | `Add()` | `(HICON或CBitmap指针)` | `Add(AfxGetApp()->LoadIcon(IDI_ICON))` | | `SetImageList()` | `(CImageList指针, 列表类型)` | `m_tree.SetImageList(&m_imgList, TVSIL_NORMAL)` | | `InsertItem()` | `(文本, 图标索引, 选中图标索引, 父节点)` | `InsertItem("File",0,0,TVI_ROOT)` | #### 3. **动态管理图像** ```cpp // 添加位图资源 CBitmap bmp; bmp.LoadBitmap(IDB_BITMAP1); m_imageList.Add(&bmp, RGB(255,0,0)); // RGB指定透明色 bmp.DeleteObject(); // 替换图像 CBitmap newBmp; newBmp.LoadBitmap(IDB_NEW); m_imageList.Replace(0, &newBmp, NULL); // 替换索引0的图片 // 删除所有图像 m_imageList.RemoveAll(); ``` #### 4. **高级应用技巧** 1. **双图标状态**(正常/选中): ```cpp // 插入节点时指定两个图标索引 HTREEITEM hItem = m_tree.InsertItem(_T("文档"), 0, 1, hParent); ``` 2. **多尺寸支持**: ```cpp // 创建不同尺寸的图像列表 CImageList smallList, largeList; smallList.Create(16, 16, ILC_COLOR32, 5, 1); largeList.Create(32, 32, ILC_COLOR32, 5, 1); // 关联到列表控件 m_listCtrl.SetImageList(&smallList, LVSIL_SMALL); m_listCtrl.SetImageList(&largeList, LVSIL_NORMAL); ``` 3. **动态图标切换**: ```cpp // 根据条件切换图标 void CMyDialog::UpdateItemIcon(HTREEITEM hItem, int state) { m_treeCtrl.SetItemImage(hItem, state, state); // 设置新图标索引 } ``` #### 5. **注意事项** 1. **资源管理**: - 使用 `DestroyIcon()` 释放通过 `LoadIcon()` 加载的图标[^3] - 图像列表生命周期应长于关联控件 2. **性能优化**: ```cpp m_treeCtrl.SetRedraw(FALSE); // 开始批量操作 for(int i=0; i<1000; i++) { m_treeCtrl.InsertItem(...); } m_treeCtrl.SetRedraw(TRUE); // 结束批量操作,重绘控件 ``` 3. **常见错误**: - 错误:未调用 `Create()` 直接使用 `Add()` - 错误:图像列表被提前销毁导致控件显示异常 - 错误:图标索引越界(索引从0开始) [^1]: 引用[1]: CImageList创建与添加图像示例 [^2]: 引用[2]: 关键接口说明 [^3]: 引用[3]: 树形控件图像列表完整实现流程
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值