ADN Open CIS
Сообщество программистов Autodesk в СНГ

07/10/2014

Настройка CAdUiListCtrl

Если мы пользуемся классом CAdUiListCtrl и хотим его настроить получше, мы можем использовать пользовательское рисование. Это делается точно так же, как и с любым другим элементом управления MFC. Хорошую статью о том, как это делать (на английском)  для элемента управления CListCtrl  вы найдете здесь.

Дальше пример класса наследника CAdUiListCtrl  с использованием пользовательского рисования для отрисовки цветов в диалоговом окне.

Код - C++: [Выделить]
  1. // MyListCtrl.h
  2.  #pragma  once
  3.  
  4.  class  MyListCtrl : public  CAdUiListCtrl
  5.  {
  6.         DECLARE_DYNAMIC(MyListCtrl)
  7.  private :
  8.         // Метод - помощник
  9.         CString ColorNameFromIndex(int  colorIndex);
  10.  
  11.  public :
  12.         MyListCtrl();
  13.         virtual  ~MyListCtrl();
  14.  
  15.  protected :
  16.         DECLARE_MESSAGE_MAP()
  17.  
  18.         // Пользовательское рисование
  19.         afx_msg void  OnCustomDraw
  20.                ( NMHDR* pNMHDR, LRESULT* pResult );
  21.  };
  22.  
  23.  // MyListCtrl.cpp : implementation file
  24.  
  25.  #include  "stdafx.h"
  26.  #include  "MyListCtrl.h"
  27.  
  28.  IMPLEMENT_DYNAMIC(MyListCtrl, CAdUiListCtrl)
  29.  
  30.  MyListCtrl::MyListCtrl(){}
  31.  
  32.  MyListCtrl::~MyListCtrl(){}
  33.  
  34.  BEGIN_MESSAGE_MAP(MyListCtrl, CAdUiListCtrl)
  35.         ON_NOTIFY_REFLECT ( NM_CUSTOMDRAW, OnCustomDraw)
  36.  END_MESSAGE_MAP()
  37.  
  38.  // Для пользовательского рисования
  39.  afx_msg void  MyListCtrl::
  40.         OnCustomDraw ( NMHDR* pNMHDR, LRESULT* pResult)
  41.  {
  42.         NMLVCUSTOMDRAW* pLVCD
  43.                = reinterpret_cast <NMLVCUSTOMDRAW*>(pNMHDR);
  44.  
  45.      // Для начала установим стандартную обработку
  46.      // если понадобится изменим ниже
  47.      *pResult = CDRF_DODEFAULT;
  48.  
  49.      // Первым делом проверяем стадию рисования.
  50.      // Если это стадия «перед отрисовкой»
  51.      // тогда скажем Windows что нам нужны сообщения
  52.      // для каждого элемента.
  53.      if  ( CDDS_PREPAINT
  54.                == pLVCD->nmcd.dwDrawStage )
  55.         {
  56.          *pResult = CDRF_NOTIFYITEMDRAW;
  57.      }
  58.      else  if  ( CDDS_ITEMPREPAINT
  59.                == pLVCD->nmcd.dwDrawStage )
  60.         {
  61.                *pResult = CDRF_NOTIFYPOSTPAINT;
  62.         }
  63.         else  if  ( CDDS_ITEMPOSTPAINT
  64.                == pLVCD->nmcd.dwDrawStage )
  65.         {
  66.                LVITEM rItem;
  67.                int     nItem =
  68.                        static_cast <int >( pLVCD->nmcd.dwItemSpec);
  69.                CDC*  pDC = CDC::FromHandle ( pLVCD->nmcd.hdc);
  70.                CRect rcIcon;
  71.  
  72.                // Для каждого индекса цвета получаем RGB элемента
  73.                long  acirgb, r,g,b;
  74.          acirgb = acedGetRGB ( nItem );
  75.          r = ( acirgb & 0xffL );
  76.          g = ( acirgb & 0xff00L ) >> 8;
  77.          b = acirgb >> 16;
  78.                CBrush brush(RGB(r,g,b));
  79.  
  80.                CRect rcItem;
  81.                GetSubItemRect(nItem, 1, rcItem);
  82.  
  83.                int  w = rcItem.Width();
  84.                int  h = rcItem.Height();
  85.  
  86.                CRect clrBox((int )rcItem.left + 0.1 * h,
  87.                                        (int )rcItem.top + 0.1 * h,
  88.                                        (int )rcItem.left + 0.9 * h,
  89.                                        (int )rcItem.top + 0.9 * h);
  90.               
  91.                CBrush* pOldBrush = pDC->SelectObject(&brush);
  92.  
  93.                // создаем и выбираем тонкий черный карандаш
  94.                CPen penBlack;
  95.                penBlack.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
  96.                CPen* pOldPen = pDC->SelectObject(&penBlack);
  97.  
  98.                pDC->Rectangle(clrBox);
  99.                pDC->TextOutW(clrBox.right + 0.1*h,
  100.                                       (int )rcItem.top + 0.1 * h,
  101.                                       ColorNameFromIndex(nItem));
  102.  
  103.                // восстанавливаем старый объект
  104.                pDC->SelectObject(pOldBrush);
  105.                pDC->SelectObject(pOldPen);
  106.  
  107.                *pResult = CDRF_DODEFAULT;
  108.         }
  109.  }
  110.  
  111.  // Метод - помощник
  112.  CString MyListCtrl::ColorNameFromIndex
  113.                                                      (int  colorIndex)
  114.  {
  115.         switch (colorIndex)
  116.         {
  117.                case  0:
  118.                        return  _T("Black" );
  119.                case  1:
  120.                        return  _T("Red" );
  121.                case  2:
  122.                        return  _T("Yellow" );
  123.                case  3:
  124.                        return  _T("Green" );
  125.                case  4:
  126.                        return  _T("Cyan" );
  127.                default  :
  128.                {
  129.                        CString str;
  130.                        str.Format(_T("%d" ), colorIndex);
  131.                        return  str;
  132.                }
  133.         }
  134.  }

 

Чтобы использовать этот элемент управления в диалоге, вставьте элемент управления MFC List control и добавьте переменную-член для него. Замените CListCtrl на класс пользовательского элемента управления. Вот образец кода:

Код - C++: [Выделить]
  1. // SampleDlg.h
  2.  // Переменная для элемента управления
  3.  MyListCtrl mMyList;
  4.  
  5.  // SampleDlg.cpp
  6.  BOOL SampleDlg::OnInitDialog()
  7.  {
  8.         CDialog::OnInitDialog();
  9.  
  10.         // Вставим две колонки
  11.         mMyList.InsertColumn(
  12.                0,
  13.                _T("Layer Name" ),
  14.                LVCFMT_LEFT, 90);
  15.  
  16.         mMyList.InsertColumn(
  17.                1,
  18.                _T("Color" )
  19.                , LVCFMT_LEFT, 90);
  20.  
  21.         // Содержимое колонки 1 будем настраивать
  22.         // во время работы, так что
  23.         // пока оставим ее пустой
  24.         int  nIndex =
  25.                mMyList.InsertItem(0, _T("Layer 0" ));
  26.         mMyList.SetItemText(nIndex, 1, _T(" " ));
  27.  
  28.         nIndex
  29.                = mMyList.InsertItem(1, _T("Layer 1" ));
  30.         mMyList.SetItemText(nIndex, 1, _T(" " ));
  31.  
  32.         nIndex
  33.                = mMyList.InsertItem(2, _T("Layer 2" ));
  34.         mMyList.SetItemText(nIndex, 1, _T(" " ));
  35.  
  36.         nIndex
  37.                = mMyList.InsertItem(3, _T("Layer 3" ));
  38.         mMyList.SetItemText(nIndex, 1, _T(" " ));
  39.  
  40.         nIndex
  41.                = mMyList.InsertItem(4, _T("Layer 4" ));
  42.         mMyList.SetItemText(nIndex, 1, _T(" " ));
  43.  
  44.         return  TRUE; 
  45.  }

 

А вот как это будет выглядеть:

 

 

Источник: http://adndevblog.typepad.com/autocad/2014/09/customizing-caduilistctrl.html

Обсуждение: http://adn-cis.org/forum/index.php?topic=1000

Опубликовано 07.10.2014
Отредактировано 07.10.2014 в 01:48:18