Chinaunix首页 | 论坛 | 博客
  • 博客访问: 522355
  • 博文数量: 252
  • 博客积分: 6057
  • 博客等级: 准将
  • 技术积分: 1635
  • 用 户 组: 普通用户
  • 注册时间: 2009-12-21 10:17
文章分类

全部博文(252)

文章存档

2013年(1)

2012年(1)

2011年(32)

2010年(212)

2009年(6)

分类: C/C++

2010-07-01 13:44:07

原作者:ccrun  
更新日期:2006-07-19  
浏览次数:1357  
 关键字:ListView,ListItem,DrawItem,自画,ownerDraw,ccrun  
关于VCL控件自画的代码先前ccrun发过很多,比如TListBox,   TCheckListbox,   TComboBox,   TMenuItem等,下面的代码是自绘TListItem,也就是ListView在ViewStyle为vsReport时Item的自画。效果图如 下:


首先定义几个我们需要用到的颜色,这里用的是Office   2003菜单的高亮条颜色:

#define   MYCOLOR_BACK   TColor(0x00CFB9B1)
#define   MYCOLOR_BORDER   clHighlight
#define   MYCOLOR_ROW   TColor(RGB(240,   240,   240))

一般来讲,VCL中提供了自画功能的控件都有类似OnDrawXX或OnCustomDrawXX的事件,ListView有四个类似的事件,这个例子中 我们使用OnDrawItem事件。

在窗体的头文件中,声明一下自画函数,可以放在Form类的__published段内,需要注意的是,由IDE自动产生的 ListViewOnDrawItem自画函数的参数和我们声明的这个略有不同,所以在设计界面上,ListView的OnDrawItem中是看不到这 个函数的。

private:         //   User   declarations
        void   __fastcall   CrnDrawListViewItem(TCustomListView   *Sender,
                        TListItem   *Item,   TRect   &Rect,   TOwnerDrawState   State);

下面是自画函数的具体实现代码:
//---------------------------------------------------------------------------
//   自画ListView的Item
//   by   ccrun(老妖)   info#ccrun.com
//   欢迎光临   C++Builder研究   -  
//   做人要厚道,转载要留名
//---------------------------------------------------------------------------
void   __fastcall   TForm1::CrnDrawListViewItem(TCustomListView   *Sender,
            TListItem   *Item,   TRect   &Rect,   TOwnerDrawState   State)
{
        TListView   *lv   =   (TListView   *)Sender;
        //   Rect
        TRect   rct(Rect.Left   +   1,   Rect.Top,   Rect.Width()   -   1,   Rect.Bottom);
        //   Fill   background
        if(State.Contains(odFocused)   ||   State.Contains(odSelected))
        {
                //   With   focus
                lv-> Canvas-> Brush-> Color   =   MYCOLOR_BACK;
                lv-> Canvas-> FillRect(rct);
                lv-> Canvas-> Pen-> Color   =   MYCOLOR_BORDER;
                lv-> Canvas-> Rectangle(rct);
        }
        else
        {
                lv-> Canvas-> Brush-> Color   =   lv-> Color;
                lv-> Canvas-> FillRect(Rect);
        }
        int   nLeftOffset(0);      
        //   With   CheckBox?
//   本文转自   C++Builder   研究   -   /article.asp?i=656&d=qdc7kg
        //   63   63   72   75   6E   2E   63   6F   6D
        if(lv-> Checkboxes)
        {
                lv-> Canvas-> Pen-> Color   =   clBlack;
                lv-> Canvas-> Pen-> Width   =   2;
                //   Draw   CheckBox   Rect
                lv-> Canvas-> Rectangle(Rect.Left   +   4,   Rect.Top   +   3,   Rect.Left   +   16,   Rect.Bottom   -   2);
                nLeftOffset   =   16;
                if(Item-> Checked)
                {
                        //   画CheckBox的勾
                        lv-> Canvas-> MoveTo(Rect.Left   +   6,   Rect.Top   +   6);
                        lv-> Canvas-> LineTo(Rect.Left   +   8,   Rect.Top   +   11);
                        lv-> Canvas-> LineTo(Rect.Left   +   13,   Rect.Top   +   5);
                }
                lv-> Canvas-> Pen-> Width   =   1;
        }
        //   Draw   small   Icon
        if(lv-> SmallImages   &&   Item-> ImageIndex   !=   -1)
        {
                lv-> SmallImages-> Draw(lv-> Canvas,   nLeftOffset   +   Rect.Left   +   2,
                        Rect.Top   +   (Rect.Height()   -   lv-> SmallImages-> Height)   /   2   +   1,
                        Item-> ImageIndex,   true);
                nLeftOffset   +=   lv-> SmallImages-> Width;  
/*

*/
        }
        //   Draw   Text
        lv-> Canvas-> Font-> Color   =   clBlack;
        lv-> Canvas-> TextOutA(Rect.Left   +   4   +   nLeftOffset,
                        Rect.Top   +   (Rect.Height()   -   lv-> Canvas-> TextHeight( "A "))   /   2,
                        Item-> Caption);
        //   Draw   SubItem   Text
        int   nColOffset(0);
        for(int   i=0;   iSubItems-> Count;   i++)
        {
                nColOffset   +=   lv-> Column[i]-> Width;
                lv-> Canvas-> TextOutA(nColOffset   +   Rect.Left   +   4,
                        Rect.Top   +   (Rect.Height()   -   lv-> Canvas-> TextHeight( "A "))   /   2,
                        Item-> SubItems-> Strings[0]);
        }
}
//   自画代码结束

由于这个自画函数与IDE自动产生的不一样,所以需要动态指定ListView的OnDrawItem,同时,ListView还需要一些设置,当然,你 可以在设计时直接在属性中更改。
//---------------------------------------------------------------------------
__fastcall   TForm1::TForm1(TComponent*   Owner)
                :   TForm(Owner)
{
        ListView1-> OwnerDraw   =   true;
        ListView1-> RowSelect   =   true;
        ListView1-> ReadOnly   =   true;
        ListView1-> OnDrawItem   =(TLVDrawItemEvent)&CrnDrawListViewItem;
}

这样就基本OK了,有兴趣的朋友可以测试一下。

.dfm文件内容(View   as   Text)
=============================================================================
object   Form1:   TForm1
    Left   =   196
    Top   =   131
    BorderStyle   =   bsDialog
    Caption   =   'ListItem自画演示 '
    ClientHeight   =   168
    ClientWidth   =   231
    Color   =   clBtnFace
    Font.Charset   =   GB2312_CHARSET
    Font.Color   =   clWindowText
    Font.Height   =   -12
    Font.Name   =   '宋体 '
    Font.Style   =   []
    OldCreateOrder   =   False
    Position   =   poScreenCenter
    Visible   =   True
    PixelsPerInch   =   96
    TextHeight   =   12
    object   Label1:   TLabel
        Left   =   40
        Top   =   8
        Width   =   144
        Height   =   12
        Caption   =   'by   ccrun(老妖)   QQ:165332 '
    end
    object   Label2:   TLabel
        Left   =   24
        Top   =   144
        Width   =   186
        Height   =   12
        Caption   =   'Welcome   to   '
    end
    object   ListView1:   TListView
        Left   =   10
        Top   =   27
        Width   =   209
        Height   =   105
        Columns   =   <
            item
            end
            item
                Width   =   56
            end
            item
                Width   =   80
            end>
        Items.Data   =   {
            EF0000000700000000000000FFFFFFFFFFFFFFFF020000000000000001610261
            610361616100000000FFFFFFFFFFFFFFFF020000000000000001620262620362
            626200000000FFFFFFFFFFFFFFFF020000000000000001630263630363636300
            000000FFFFFFFFFFFFFFFF020000000000000001640264640364646400000000
            FFFFFFFFFFFFFFFF020000000000000001650265650365656500000000FFFFFF
            FFFFFFFFFF020000000000000001660266660366666600000000FFFFFFFFFFFF
            FFFF0200000000000000016702676703676767FFFFFFFFFFFFFFFFFFFFFFFFFF
            FFFFFFFFFFFFFFFFFFFFFFFFFFFFFF}
        TabOrder   =   0
        ViewStyle   =   vsReport
    end
end
阅读(1037) | 评论(2) | 转发(0) |
给主人留下些什么吧!~~

chulia200020012010-07-01 13:46:47

http://www.plm.hk/phpgm/thread-2340-1-1.html 如何将ListView的表格头部的颜色改变?楼主lbg(lbg) lbg, ListView, 表格, 楼主, 头部 如何将ListView的表格头部的颜色改变?楼主lbg(lbg)2002-08-31 15:35:42 在 C++ Builder / 基础类 提问 我看到ListView有个OwerDraw的属性,在OnDrawItem事件中有一个Rect的参数,我试了试,这个Rect是指向数据区的,我想将它的Columns的颜色改变,该怎么办? 问题点数:60、回复次数:17 Top 1 楼xuby5228(潇湘大少)回复于 2002-08-31 18:35:52 得分 0 你看一下下面的代码: void __fastcall TFrmMain:rawXPStyleMainMenu( TObject *Sender,

chulia200020012010-07-01 13:45:47

http://topic.csdn.net/t/20060905/09/4998803.html #9楼 得分:100回复于:2006-09-05 11:45:35 Delphi的FAQ里面有,楼主参考一下方法: 如何改变LISTVIEW头部(header)的颜色!我想要cl3dlight的颜色 --------------------------------------------------------------- 1,用SPY++等工具查看,发现HEADER本身是一个子窗口,类名为SYSHEADER32; 2,用WINDOWS API得到该窗口的DC; 3,就可以自己画了,代码如下,你需要先自己增加COLUMS,然后设置为REPORT样式; procedure TForm1.Button2Click(Sender: TObject); var dd:thandle; f:Tcanvas; begin f: