博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ListCtrl插入大量数据时,发现缓慢有问题,QT里有数据和显示分开,MFC也有比较戳的虚拟表,古老的技术
阅读量:4179 次
发布时间:2019-05-26

本文共 6422 字,大约阅读时间需要 21 分钟。

最初代码来源

csdn代码下载

 

知识点:

subclasswindow是更改窗口过程,就是类向导关联自定义的列表控件会调用PreSubclassWindow

CreateWindowEx会调用PreCreateWindow,这个是动态创建的,笔者重载了这个函数,发现一直没有调用,花了很长的时间去调试

 

#pragma once#include 
class CSampleData{public: CString moduleName; // 模块名称 CString filePath; // 图片路径 int result; // 分析结果 int image; // 列表图片 bool checked; // 复选框};// 虚拟列表,记得RC编辑界面改对话框属性Owner Data为trueclass CVirtualListCtrl : public CListCtrl{ DECLARE_DYNAMIC(CVirtualListCtrl)public: CVirtualListCtrl(); virtual ~CVirtualListCtrl();public: void AddItem(const CSampleData& data); void Clear(); DWORD GetItemCount() { return m_database.size(); }protected: DECLARE_MESSAGE_MAP() virtual void PreSubclassWindow()override; afx_msg void OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnLvnOdfinditem(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnLvnOdcachehint(NMHDR *pNMHDR, LRESULT *pResult);private: BOOL IsCheckBoxesVisible(); void ToggleCheckBox(int item);private: std::vector
m_database;public: afx_msg void OnNMClick(NMHDR *pNMHDR, LRESULT *pResult); afx_msg void OnLvnKeydown(NMHDR *pNMHDR, LRESULT *pResult);};
// VirtualListCtrl.cpp : 实现文件//#include "stdafx.h"#include "VListTest.h"#include "VirtualListCtrl.h"// CVirtualListCtrlIMPLEMENT_DYNAMIC(CVirtualListCtrl, CListCtrl)CVirtualListCtrl::CVirtualListCtrl(){}CVirtualListCtrl::~CVirtualListCtrl(){}void CVirtualListCtrl::AddItem(const CSampleData & data){    m_database.push_back(data);    SetItemCount(m_database.size());}void CVirtualListCtrl::Clear(){    m_database.clear();    SetItemCount(0);}BEGIN_MESSAGE_MAP(CVirtualListCtrl, CListCtrl)    ON_NOTIFY_REFLECT(LVN_GETDISPINFO, &CVirtualListCtrl::OnLvnGetdispinfo)    ON_NOTIFY_REFLECT(LVN_ODFINDITEM, &CVirtualListCtrl::OnLvnOdfinditem)    ON_NOTIFY_REFLECT(LVN_ODCACHEHINT, &CVirtualListCtrl::OnLvnOdcachehint)    ON_NOTIFY_REFLECT(NM_CLICK, &CVirtualListCtrl::OnNMClick)    ON_NOTIFY_REFLECT(LVN_KEYDOWN, &CVirtualListCtrl::OnLvnKeydown)    ON_WM_CREATE()END_MESSAGE_MAP()// CVirtualListCtrl 消息处理程序void CVirtualListCtrl::PreSubclassWindow(){    // TODO: 在此添加专用代码和/或调用基类    ModifyStyle(LVS_TYPEMASK, LVS_REPORT);    SetExtendedStyle(LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES | LVS_EX_GRIDLINES);    CListCtrl::PreSubclassWindow();}// 虚拟列表显示前,发送消息请求显示的内容void CVirtualListCtrl::OnLvnGetdispinfo(NMHDR *pNMHDR, LRESULT *pResult){    LV_DISPINFO* pDispInfo = (LV_DISPINFO*)pNMHDR;    LV_ITEM* pItem = &(pDispInfo)->item;    int itemid = pItem->iItem;    if (pItem->mask & LVIF_TEXT)    {        CString text;        if (pItem->iSubItem == 0){            text = m_database[itemid].moduleName;        }        else if (pItem->iSubItem == 1){            text = m_database[itemid].filePath;        }        lstrcpyn(pItem->pszText, text, pItem->cchTextMax);    }    if (pItem->mask & LVIF_IMAGE)    {        // pItem->iImage = m_database[itemid].m_image;        if (IsCheckBoxesVisible())        {            pItem->mask |= LVIF_STATE;            pItem->stateMask = LVIS_STATEIMAGEMASK;            if (m_database[itemid].checked) {                pItem->state = INDEXTOSTATEIMAGEMASK(2);  // Turn check box on..            }            else {                pItem->state = INDEXTOSTATEIMAGEMASK(1);  // Turn check box off            }        }    }    *pResult = 0;}// 快捷键查找项void CVirtualListCtrl::OnLvnOdfinditem(NMHDR *pNMHDR, LRESULT *pResult){    // pNMHDR has information about the item we should find    // In pResult we should save which item that should be selected    NMLVFINDITEM* pFindInfo = (NMLVFINDITEM*)pNMHDR;    /* pFindInfo->iStart is from which item we should search.    We search to bottom, and then restart at top and will stop    at pFindInfo->iStart, unless we find an item that match    */    // Set the default return value to -1    // That means we didn't find any match.    *pResult = -1;    //Is search NOT based on string?    if ((pFindInfo->lvfi.flags & LVFI_STRING) == 0)    {        //This will probably never happend...        return;    }    /*    Let's look on a sample list;    Name    Anders    * Anna    Annika    Bob    Emma    Emmanuel    Anna is selected.    If "A" is written, Annika should be selected.    If "AND" is written, Anders should be selected.    If "ANNK" is written, the selection should stay on Anna.    If "E" is written, Emma should be selected.    */    //This is the string we search for    CString searchstr = pFindInfo->lvfi.psz;    //	TRACE(_T("Find: %s\n"), searchstr);    int startPos = pFindInfo->iStart;    //Is startPos outside the list (happens if last item is selected)    if (startPos >= GetItemCount())        startPos = 0;    int currentPos = startPos;    //Let's search...    do    {        //Do this word begins with all characters in searchstr?        if (_tcsnicmp(m_database[currentPos].moduleName, searchstr, searchstr.GetLength()) == 0)        {            //Select this item and stop search.            *pResult = currentPos;            break;        }        //Go to next item        currentPos++;        //Need to restart at top?        if (currentPos >= GetItemCount())            currentPos = 0;        //Stop if back to start    } while (currentPos != startPos);}// 数据库在网络上另一台电脑需要使用void CVirtualListCtrl::OnLvnOdcachehint(NMHDR *pNMHDR, LRESULT *pResult){    LPNMLVCACHEHINT pCacheHint = reinterpret_cast
(pNMHDR); // TODO: 在此添加控件通知处理程序代码 *pResult = 0;}BOOL CVirtualListCtrl::IsCheckBoxesVisible(){ DWORD style = GetStyle(); if (((style & LVS_TYPEMASK) == LVS_LIST) || ((style & LVS_TYPEMASK) == LVS_REPORT)) return TRUE; return FALSE;}void CVirtualListCtrl::ToggleCheckBox(int item){ m_database[item].checked = !m_database[item].checked; RedrawItems(item, item);}void CVirtualListCtrl::OnNMClick(NMHDR *pNMHDR, LRESULT *pResult){ NMLISTVIEW* pNMListView = (NM_LISTVIEW*)pNMHDR; LVHITTESTINFO hitinfo; hitinfo.pt = pNMListView->ptAction; int item = HitTest(&hitinfo); if (item != -1) { if ((hitinfo.flags & LVHT_ONITEMSTATEICON) != 0) { ToggleCheckBox(item); } } *pResult = 0;}void CVirtualListCtrl::OnLvnKeydown(NMHDR *pNMHDR, LRESULT *pResult){ LV_KEYDOWN* pLVKeyDown = (LV_KEYDOWN*)pNMHDR; if (pLVKeyDown->wVKey == VK_SPACE) { if (IsCheckBoxesVisible()) { if (GetSelectionMark() != -1) ToggleCheckBox(GetSelectionMark()); } } *pResult = 0;}

 

转载地址:http://twmai.baihongyu.com/

你可能感兴趣的文章
linux安装mysql 5.7.23二进制 安装jdk tomcat
查看>>
mysql总结 windows 版本
查看>>
POI 导出工具类
查看>>
HTTP请求工具类
查看>>
Ngnix+tomcat 集群以及session共享
查看>>
Nginx配置多个项目放在不同的tomcat中,共享同一个端口
查看>>
mysql的JDBC连接工具类
查看>>
ORACLE的JDBC连接工具类
查看>>
利用多线程(用到原子类AtomicInteger)往数据库批量插入大量数据
查看>>
多个线程操作数组
查看>>
定长线程池的应用
查看>>
生产者和消费者模式
查看>>
ArrayBlockingQueue的简单使用
查看>>
Git 常用命令总结(一)
查看>>
Git 常用命令总结(二)
查看>>
JAVA 并发——synchronized的分析
查看>>
Echarts——使用 dataset 管理数据
查看>>
DES 加解密工具类
查看>>
JAVA乱码问题——URL中的+,空格,/,?,%,#,&,= 及转义处理
查看>>
Base64编解码工具类
查看>>