现在的位置: 首页 > 综合 > 正文

CLISTBOX 的drawitem

2013年09月21日 ⁄ 综合 ⁄ 共 3367字 ⁄ 字号 评论关闭

    最近在做一个UI时,需要将一些笔画非常多的字显示在一个ListBox列表中,供别人参考,高高兴兴做完了以后,运行一看,糟糕,由于笔画太多,字太小,眼睛根本看不清楚,不过当时并不在意,不就是用SetFont就搞定的事吗!!然后在获得该ListBox的DC后,用SetFont一把,结果出乎所料,里面的字体居然没变化。后来查阅相关资料,才发现微软居然将这些控件的字体和颜色等属性都是设置为默认的,普通的属性设置函数根本没用。真是气死人呀,哪有这么不人性化的软件,所以人家说VC难学,特别是MFC,我看微软负有不可推卸的责任。好了,不扯远了,继续主题。要想在ListBox或者ListCtrl等控件中绘制你想要的图形或者设置你想要的属性,那么必须采用自绘的方式。大致步骤如下:  
    1、添加一个LISTBOX控件,将其Owner Draw属性改为“FIXED”或者“VARIABLE”,前者是指每个Item的高度一样,后者可以单独对每一个Item的高度设置,并可以为不同的 Item设置不同的属性。此外,还需要将Has Strings的属性设置为TRUE。      2、建立一个断承CListBox的类COwnerListBox,重载(Override)它的几个函数。主要是DrawItem和 MeasureItem两个函数。其他的函数可以参见MSDN。  
    3、MeasureItem中主要是设置这个ListBox的属性。而DrawItem主要是自己画每一个Item.   
    4、如果LISTBOX控件选择了“FIXED”属性后不做任何修改,那么用AddString等函数添加的子项将不会被系统自动显示,原因是用户选择了自绘属性。这个属性由COwnerListBox里的DrawItem和MesureItem函数完成。DrawItem用来绘制子项目,MesureItem用来修改项目的一些属性(一般不用更改)。  

  完成上述步骤后,即可看见更改后的LISTBOX,另外按钮等其他控件步骤与思想是大同小异的。下面是我做的一个类,用来自绘ListBox的每一项。其中主要功能就是将每一项的字体显示的大写,并用红色显示出。界面可以参见附图。
代码:
OwnerListBox.h:

#pragma once
// COwnerListBox
class COwnerListBox : public CListBox { DECLARE_DYNAMIC(COwnerListBox)
public: COwnerListBox();
        virtual ~COwnerListBox();
        struct DataItem{
             CString m_string;
        };
        void Add(CString m_str);
protected:
         DECLARE_MESSAGE_MAP()
public:
         virtual void  DrawItem(LPDRAWITEMSTRUCT/*lpDrawItemStruct*/);
         virtual void
MeasureItem(LPMEASUREITEMSTRUCT /*lpMeasureItemStruct*/); protected:
        virtual void PreSubclassWindow();
 };

// 这段代码希望大家拷到自己电脑用其他文字编辑程序打开看,这里显示有点问题。

OwnerListBox.cpp: //// OwnerListBox.cpp : 实现文件 // #include "stdafx.h" #include "CompStroke.h" #include "OwnerListBox.h" #include "./ownerlistbox.h" #include // COwnerListBox IMPLEMENT_DYNAMIC(COwnerListBox, CListBox) COwnerListBox::COwnerListBox() { } COwnerListBox::~COwnerListBox() { } BEGIN_MESSAGE_MAP(COwnerListBox, CListBox) END_MESSAGE_MAP() // COwnerListBox 消息处理程序 void COwnerListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) { // TODO: 添加您的代码以绘制指定项 COLORREF clrItemText; LPDRAWITEMSTRUCT lpDIS = lpDrawItemStruct; switch ( lpDIS->itemAction ) //lpDIS为一个LPMEASUREITEMSTRUCT(记录控件信息) { case ODA_SELECT: case ODA_DRAWENTIRE: // Is the item selected? if ( lpDIS->itemState & ODS_SELECTED ) { clrItemText = GetSysColor( COLOR_HIGHLIGHTTEXT ); // Clear the rectangle FillRect( lpDIS->hDC, &lpDIS->rcItem, (HBRUSH)(COLOR_ACTIVECAPTION+1) ); } else { clrItemText = GetSysColor( COLOR_WINDOWTEXT ); // Clear the rectangle FillRect( lpDIS->hDC, &lpDIS->rcItem, (HBRUSH)(COLOR_WINDOW+1) ); } } CDC dc; dc.Attach(lpDIS->hDC); CRect rectFull = lpDIS->rcItem; CRect rect2 = rectFull; rect2.right = rectFull.Width() - 1; UINT nIndex = lpDIS->itemID; if (nIndex != (UINT) -1) { LOGFONT lf; dc.GetCurrentFont()->GetLogFont(&lf); CFont font, *pOldFont; lf.lfCharSet = SHIFTJIS_CHARSET; lstrcpy(lf.lfFaceName,_T("MS Mincho")); lf.lfHeight=50; // lf.lfWidth=0; font.CreateFontIndirect(&lf); pOldFont=dc.SelectObject(&font); CString sss; this->GetText(nIndex,sss); dc.SetBkMode(TRANSPARENT); dc.SetTextColor(RGB(255,0,0)); dc.DrawText(sss,CRect(rect2.left+3,rect2.top+3, rect2.right-3,rect2.bottom+3), DT_LEFT | DT_SINGLELINE); dc.SelectObject(pOldFont); } dc.Detach(); } void COwnerListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct) { // TODO: 添加您的代码以确定指定项的大小 lpMeasureItemStruct->itemHeight = 60; lpMeasureItemStruct->itemWidth = 100; } void COwnerListBox::PreSubclassWindow() { // TODO: 在此添加专用代码和/或调用基类 CListBox::PreSubclassWindow(); } void COwnerListBox::Add(CString m_str) { DataItem *prtData = new DataItem; prtData->m_string = m_str; int index = AddString(m_str); SetItemDataPtr(index, prtData); delete prtData; }

抱歉!评论已关闭.