InsertItem中使用SetRedraw

本文介绍如何使用SetRedraw函数来优化Windows程序中树控件和列表控件的数据更新过程,通过关闭和重新开启视图更新,有效减少因频繁更新导致的时间开销。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SetRedraw 的用法:
SetRedraw(FALSE):关闭视图更新;
SetRedraw(TRUE) :开启视图更新;

说明:
常用到insertitem这个函数的地方会用到此函数,如:树控件和list控件添加数据,
扯到insertitem这个函数的原因是,insertitem在添加数据时,每添加一项就会更新一下视图,这过会增加耗时.所以循环添加数据时就关掉,添加完后再开启更新.

代码:

//m_ctrlFileList是一个list控件变量

m_ctrlFileList.SetRedraw(FALSE);        //删除redrawflag就算改也不会重画
while(ass>0)
{
        //插入数据;
        m_ctrlFileList.InsertItem(ItemIndex,FileName);   
        m_ctrlFileList.SetItemText(ItemIndex,1,FileSize);
        m_ctrlFileList.SetItemText(ItemIndex,2,StartTime);
        m_ctrlFileList.SetItemText(ItemIndex,3,StopTime);
        m_ctrlFileList.SetItemText(ItemIndex,4,Property);       
}
m_ctrlFileList.SetRedraw(TRUE);        //设置重画表示
<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
发出的红包

打赏作者

路途遥远gg

帮到你了就好

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值