zoukankan      html  css  js  c++  java
  • CListCtrl自绘

    花了一个晚上学习listctrl的自绘,不是很简单,可能比CRichEditCtrl还要复杂些,遇到第一件事情是自适应改变行高,项目需要,当然也可以是固定,最终解决方案如下:

    网上修改CListCtrl项高度的方法一般是扩大字体,及用图片将项高度撑大.
    这两种方法虽然简单,但是效果却不是很理想.一种比较理想的方法是自画CListCtrl,不过方法相对来说比较复杂.
    要修改CListCtrl的列表项高度,我们需要自己添加 MeasureItem 的消息响应函数,对应的消息是 WM_MEASUREITEM+WM_REFLECT_BASE, 而不是 WM_MEASUREITEM.在CListBox里我们可以直接在 ClassWizard 里将此消息响应添加进 class 里,但是 CListCtrl 默认是没有这个消息响应的,我们需要手动添加它(注意,这里不是 WM_MEASUREITEM. CListCtrl 仅有 WM_MEASUREITEM, 对应的函数为 OnMeasureItem).
    为了响应这个消息,我们还需要给列表加上 LVS_OWNERDRAWFIXED 风格.可以在 Create 列表的时候添加,也可以在 PreCreateWindow 虚函数中添加.
    添加 MeasureItem 消息响应函数,首先我们需要在类的头文件中添加:
    afx_msg void MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct);
    来声明此消息响应函数;
    然后在cpp的消息响应宏中添加:
    ON_WM_MEASUREITEM_REFLECT()
    最后自己建立 MeasureItem 的函数定义:
    /////////////////////////////////////////////////////////////////////////////
    // CListEx message handlers
    void CListEx::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
    {
    if( m_nItemHeight > 0 )
       lpMeasureItemStruct->itemHeight = m_nItemHeight;
    }
    其中 m_nItemHeight 是我在头文件中声明的一个成员变量,用于从外部修改列表项高度.
    然后我们添加一个方法,便于从外部直接修改列表项高度:
    //设置行高
    void SetItemHeight(UINT nHeight);
    然后是该方法的定义:
    //设置行高
    void CListEx::SetItemHeight(UINT nHeight)
    {
    m_nItemHeight = nHeight;
    CRect rcWin;
    GetWindowRect(&rcWin);
    WINDOWPOS wp;
    wp.hwnd = m_hWnd;
    wp.cx = rcWin.Width();
    wp.cy = rcWin.Height();
    wp.flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOZORDER;
    SendMessage(WM_WINDOWPOSCHANGED, 0, (LPARAM)&wp);
    }
    这个方法的最后,使用了 SendMessage 发送 WM_WINDOWPOSCHANGED 消息让 CListCtrl 进入 MeasureItem 的消息响应函数,对列表高度进行修改.
    因为我们这里使用了列表的自绘风格,因此列表项需要自己绘制.
    首先在类的声明中添加 DrawItem 虚函数声明:
    virtual void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct);
    然后自画 CListCtrl:
    void CListEx::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
    {
    int    nItem = lpDrawItemStruct->itemID;
    CDC*   pDC   = CDC::FromHandle(lpDrawItemStruct->hDC);
    ......
    CRect   rcBound, rcLabel, rcIcon;
    //获得列表项图标,标签,及项的区域
    GetItemRect ( nItem, rcIcon, LVIR_ICON );
    GetItemRect ( nItem, rcLabel, LVIR_LABEL );
    GetItemRect ( nItem, rcBound, LVIR_BOUNDS );
    ......
    }
    现在这个 CListCtrl 的重载类就支持自定义列表项高度了.
  • 相关阅读:
    [置顶] flex4事件监听与自定义事件分发(三)
    不要通过终止进程的方式清理内存
    两个关于XML解析报错问题小记
    HDU H204 阿牛的EOF牛肉串
    <Win32_8>由浅入深——滚动条
    设计模式19---设计模式之状态模式(State)(行为型)
    NetworkX学习笔记-5-NetworkX中怎样对多个网络赋属性,并根据属性排序
    OpenRisc-41-or1200的cache模块分析
    Hibernate 入门的第一个程序
    NDK GDB 中打印vector , vector<vector <> >
  • 原文地址:https://www.cnblogs.com/rainbowzc/p/1556904.html
Copyright © 2011-2022 走看看