zoukankan      html  css  js  c++  java
  • CMyListCtrl

    1. MyListCtrl.h

    #pragma once
    #include <vector>
    #include "resource.h"
    // CMyListCtrl
    #ifdef DLL_IMPLEMENT
    #define DLL_API __declspec(dllexport)
    #else
    #define DLL_API  __declspec(dllimport)
    #endif
    
    typedef unsigned int    UINT;
    #define ID_LIST_SET_FONT 1001
    #define ID_LIST_SAVE_ALL 1002
    
    class DLL_API CMyListCtrl : public CListCtrl
    {
        struct SColumn
        {
            UINT index, order, width;
            TCHAR name[128];
        };
        std::vector<SColumn> m_vecColumn;
        COLORREF m_clrFore, m_clrBack;
        CFont m_font;
        CString m_strCfgFileName;
        int m_nSortCol;//排序列的索引,-1表示无排序列
        bool m_bAscent;//true:升序  false:降序
        CImageList m_imgList;//列表头的排序图标
    
        DECLARE_DYNAMIC(CMyListCtrl)
    
    public:
        CMyListCtrl();
        virtual ~CMyListCtrl();
    
    protected:
        DECLARE_MESSAGE_MAP()
    public:
        // 用配置文件填充列
        void FillColumn(LPCTSTR szConfigFileName);
    private:
    
        // 保存颜色信息到ini文件
        void WriteColorInfoINI(const CString& strCfgFileName)
        {
            ::WritePrivateProfileStruct(_T("COLOR"), _T("color_fore"), &m_clrFore, sizeof(m_clrFore), strCfgFileName);
        }
    
        // 从ini配置文件获取颜色信息
        void GetColorInfoINI(const CString& strCfgFileName)
        {
            ::GetPrivateProfileStruct(_T("COLOR"), _T("color_fore"), &m_clrFore, sizeof(m_clrFore), strCfgFileName);
        }
    
        // 保存字体信息到ini配置文件
        void WriteFontInfoINI(const CString& strCfgFileName)
        {
            LOGFONT lf;
            GetFont()->GetLogFont(&lf);
            ::WritePrivateProfileStruct(_T("FONT"), _T("lf"), &lf, sizeof(lf), strCfgFileName);
        }
    
        // 从ini配置文件中获取字体信息
        void GetFontInfoINI(const CString& strCfgFileName)
        {
            LOGFONT lf;
            if (::GetPrivateProfileStruct(_T("FONT"), _T("lf"), &lf, sizeof(lf), strCfgFileName))
            {
                m_font.DeleteObject();
                m_font.CreateFontIndirect(&lf);
            }
            else
            {
                m_font.DeleteObject();
                m_font.CreateFont(20, 0, 0, 0, 400, 0, 0, 0, GB2312_CHARSET,
                    OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_ROMAN, _T("微软雅黑"));
            }
        }
    
        // 保存列信息到ini文件
        void WriteColumnInfoINI(const CString& strCfgFileName)
        {
            CHeaderCtrl* pHeader = GetHeaderCtrl();
            if (NULL == pHeader)
                return;
            int nCount = pHeader->GetItemCount();
            if (0 == nCount)
                return;
            int* pOrder = new int[nCount];
            GetColumnOrderArray(pOrder, nCount);
            CString strSection, strOrder, strColumnWidth;
            for (int i = 0; i < nCount; ++i)
            {
                strSection.Format(_T("%d"), i);
                strOrder.Format(_T("%d"), pOrder[i]);
                strColumnWidth.Format(_T("%d"), GetColumnWidth(i));
                ::WritePrivateProfileString(strSection, _T("Order"), strOrder, strCfgFileName);
                ::WritePrivateProfileString(strSection, _T("Width"), strColumnWidth, strCfgFileName);
            }
            delete[] pOrder;
    
        }
    
        static int CALLBACK pfnSort(LPARAM lp1, LPARAM lp2, LPARAM lpSort);
    
        virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
    public:
        afx_msg void OnSetFont();
        afx_msg void OnSaveAll();
        afx_msg void OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult);
        // 初始化一些变量,像m_imgList
        void InitListCtrl();
    };
    View Code

    2. MyListCtrl.cpp

    // MyListCtrl.cpp : 实现文件
    //
    
    #include "stdafx.h"
    #define DLL_IMPLEMENT
    #include "MyListCtrl.h"
    
    
    // CMyListCtrl
    
    IMPLEMENT_DYNAMIC(CMyListCtrl, CListCtrl)
    
    CMyListCtrl::CMyListCtrl()
    {
        //m_nSortCol = -1;
        //m_bAscent = true;
    }
    
    CMyListCtrl::~CMyListCtrl()
    {
    }
    
    
    BEGIN_MESSAGE_MAP(CMyListCtrl, CListCtrl)
        ON_COMMAND(ID_LIST_SET_FONT, OnSetFont)
        ON_COMMAND(ID_LIST_SAVE_ALL, OnSaveAll)
        ON_NOTIFY_REFLECT(LVN_COLUMNCLICK, &CMyListCtrl::OnLvnColumnclick)
    END_MESSAGE_MAP()
    
    
    
    // CMyListCtrl 消息处理程序
    
    
    
    
    // 用配置文件填充列
    void CMyListCtrl::FillColumn(LPCTSTR szConfigFileName)
    {
        m_strCfgFileName = szConfigFileName;
        CString strSection; 
        TCHAR szName[512] = { 0 };
        for (UINT i = 0; true; ++i)
        {
            SColumn sC;
            strSection.Format(_T("%d"), i);
            sC.order = ::GetPrivateProfileInt(strSection, _T("Order"), -1, m_strCfgFileName);
            if (-1 == sC.order)
                break;
            sC.width = ::GetPrivateProfileInt(strSection, _T("Width"), -1, m_strCfgFileName);
            ::GetPrivateProfileString(strSection, _T("ColumnName"), _T("-1"), sC.name, sizeof(sC.name)/sizeof(sC.name[0]), m_strCfgFileName);
            m_vecColumn.push_back(sC);
        }
        //插入列
        for (UINT i = 0; i < m_vecColumn.size(); ++i)
        {
            auto& c = m_vecColumn.at(i);
            InsertColumn(i, c.name, 0, c.width);
        }
        //按order排序
        UINT nCount = m_vecColumn.size();
        if (0 == nCount) return;
        int* arrOrder = new int[nCount];
        for (UINT i = 0; i < nCount; ++i)
        {
            arrOrder[i] = m_vecColumn[i].order;
        }
        SetColumnOrderArray(nCount, arrOrder);
        delete[] arrOrder;
    
        //获取字体,设置字体
        GetFontInfoINI(m_strCfgFileName);
        SetFont(&m_font);
    }
    
    
    BOOL CMyListCtrl::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
    {
        // TODO:  在此添加专用代码和/或调用基类
        if (0 == wParam && ((NMHDR*)lParam)->code == NM_RCLICK)
        {
            POINT pt;
            GetCursorPos(&pt);
            CMenu menu;
            menu.CreatePopupMenu();
            menu.AppendMenu(MF_STRING, ID_LIST_SET_FONT, _T("字体..."));
            menu.AppendMenu(MF_STRING, ID_LIST_SAVE_ALL, _T("保存所有设置"));
            menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, this);
        }
    
        return CListCtrl::OnNotify(wParam, lParam, pResult);
    }
    
    
    void CMyListCtrl::OnSetFont()
    {
        LOGFONT lf;
        GetFont()->GetLogFont(&lf);
        CFontDialog dlg(&lf, CF_SCREENFONTS, NULL, this);
        if (IDOK == dlg.DoModal())
        {
            m_font.DeleteObject();
            m_font.CreateFontIndirect(&dlg.m_lf);
            SetFont(&m_font);
        }
    }
    void CMyListCtrl::OnSaveAll()
    {
        WriteFontInfoINI(m_strCfgFileName);
        WriteColumnInfoINI(m_strCfgFileName);
    }
    
    
    void CMyListCtrl::OnLvnColumnclick(NMHDR *pNMHDR, LRESULT *pResult)
    {
        //LPNMLISTVIEW pNMLV = reinterpret_cast<LPNMLISTVIEW>(pNMHDR);
        //// TODO:  在此添加控件通知处理程序代码
        //*pResult = 0;
    
        //当点击不同的列表头时显示对应的排序图标
        NM_LISTVIEW* p = (NM_LISTVIEW*)pNMHDR;
        int nSub = p->iSubItem;//点击的列的索引
        CHeaderCtrl* pHeader = GetHeaderCtrl();
    
    /* 方法1:用自己的图标或位图
        //pHeader->SetImageList(&m_imgList);
        HDITEM hdi = { HDI_IMAGE | HDI_FORMAT };
        if (nSub != m_nSortCol)
        {//点击不同列时,删除旧的列图标
            if (m_nSortCol > -1)
            {
                HDITEM hdi = { HDI_FORMAT };
                pHeader->GetItem(m_nSortCol, &hdi);
                hdi.fmt &= ~HDF_IMAGE ;//移除排序图标,win7下有问题,去不掉,加上 HDITEM hdi = { HDI_FORMAT };解决,看来开关mask很重要
                pHeader->SetItem(m_nSortCol, &hdi);
            }
            m_nSortCol = nSub;
        }
        else
        {//点击相同列时,显示相反排序图标
            m_bAscent = !m_bAscent;
        }
        pHeader->GetItem(nSub, &hdi);
        hdi.fmt |= HDF_IMAGE | HDF_BITMAP_ON_RIGHT;
        hdi.iImage = m_bAscent;
        pHeader->SetItem(nSub, &hdi);
    */
        //方法2:用系统提供的排序图标
        HDITEM hdi = { HDI_FORMAT };
        if (nSub != m_nSortCol)
        {//点击不同列时,删除旧的列图标
            if (m_nSortCol > -1)
            {
                pHeader->GetItem(m_nSortCol, &hdi);
                hdi.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN);
                pHeader->SetItem(m_nSortCol, &hdi);
            }
            m_nSortCol = nSub;
        }
        else
        {//点击相同列时,显示相反排序图标
            m_bAscent = !m_bAscent;
        }
        pHeader->GetItem(nSub, &hdi);
        hdi.fmt &= ~(HDF_SORTUP | HDF_SORTDOWN);
        hdi.fmt |= (m_bAscent ? HDF_SORTUP : HDF_SORTDOWN);
        pHeader->SetItem(nSub, &hdi);
    
    
    
        //排序前,要将所有列表项的索引保存到关联数据中
        int i = GetItemCount();
        while(i--)
        {
            SetItemData(i, i);
        }
        SortItems(pfnSort, (DWORD)this); // 排序第二个参数是比较函数的第三个参数
    
    
        *pResult = 0;
    }
    
    int CALLBACK CMyListCtrl::pfnSort(LPARAM lp1, LPARAM lp2, LPARAM lpSort)
    {
        CMyListCtrl* p = (CMyListCtrl*)lpSort;
        CString s1 = p->GetItemText(lp1, p->m_nSortCol);
        CString s2 = p->GetItemText(lp2, p->m_nSortCol);
        if (p->m_bAscent)
            return s2 < s1;
        else
            return s1 < s2;
    }
    
    // 初始化一些变量,像m_imgList
    void CMyListCtrl::InitListCtrl()
    {
        m_imgList.Create(16, 16, ILC_COLOR32 | ILC_MASK, 2, 4);
        CBitmap b1, b2;
        b1.LoadBitmap(IDB_ASCENT);
        b2.LoadBitmap(IDB_DESCENT);
        m_imgList.Add(&b2, RGB(255, 255, 255));
        m_imgList.Add(&b1, RGB(255, 255, 255));
    
        CHeaderCtrl* pHeader = GetHeaderCtrl();
        pHeader->SetImageList(&m_imgList);
    
        m_nSortCol = -1;
        m_bAscent = false;
    }
    View Code

     列配置文件 SetListing.ini

    [0]
    order=0
    width=193
    columnName=column1
    [1]
    order=1
    width=193
    columnName=column2
    [2]
    order=2
    width=235
    columnName=column3
    ...

    在OnInitDialog中,添加

    //成员变量 CMyListCtrl m_list;
        CRect rect;
        GetClientRect(rect);
        rect.bottom -= 70;
        m_list.Create(WS_VISIBLE | WS_CHILD | LVS_REPORT, rect, this, 10001);
        m_list.SetExtendedStyle(m_list.GetExStyle() | LVS_EX_FULLROWSELECT //| LVS_EX_GRIDLINES 
            | LVS_EX_HEADERDRAGDROP);
        m_list.InitListCtrl();
        CString strCfgPath = myFunctions::GetExeDir() + _T("\SetListing.ini");
        m_list.FillColumn(strCfgPath.GetString());
        //m_list.InsertColumn(0, _T("jjj"), 0, 100);
        //m_list.InsertColumn(1, _T("jjj1"), 0, 100);
        //m_list.InsertColumn(2, _T("jjj2"), 0, 100);
        m_list.InsertItem(0, _T("123"));
        m_list.SetItemText(0, 1, _T("ss1"));
        m_list.SetItemText(0, 2, _T("dd1"));
        m_list.InsertItem(1, _T("222"));
        m_list.SetItemText(1, 1, _T("ss2"));
        m_list.SetItemText(1, 2, _T("dd2"));

    系统默认的排序图标:

    自己画的图标或位图:

    常记溪亭日暮,沉醉不知归路。兴尽晚回舟,误入藕花深处。争渡,争渡,惊起一滩鸥鹭。

    昨夜雨疏风骤,浓睡不消残酒。试问卷帘人,却道海棠依旧。知否?知否?应是绿肥红瘦。
  • 相关阅读:
    BT协议分析(1)—1.0协议
    Qt线程(2) QThread中使用WorkObject
    新浪微博的开放平台官方文档太粗略,记:仿大平台来实现
    58同城 骗子太多
    代码实现业务经验(程序员的核心能力)
    gitbash 本地文件提交为一个新的项目 到 gitlab
    Spring 核心容器 IOC
    spring AOP 理解
    java不返回某些字段,包括 null
    CentOS7安装 Redis5 单实例
  • 原文地址:https://www.cnblogs.com/htj10/p/12001775.html
Copyright © 2011-2022 走看看