新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 运用C++ Buider制作自绘画列表框 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 4481 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 运用C++ Buider制作自绘画列表框 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 运用C++ Buider制作自绘画列表框


    C++ Builder中的列表框和组合框控件都已经提供了自绘画接口。使用这些接口可以实现把列表框和组合框中的项目显示为图像。如果把这种功能封装成组件就更妙了,下面以列表框为例,示范这一过程。

      一 实现原理

      列表框有的Style属性定义了三种风格,lbStandard风格只能显示文本,bOwner-DrawFixed与lbOwnerDrawVariable风格可以实现自绘画功能,所不同的是,具有前者风格的列表框中每一项的高度都是相同的,后者允许应用程序为每一项定义不同高度。

      具有自绘画风格的列表框,在列表框的外观改变的时候,如增加,删除,滚动项目,总要触发两个事件句柄:

      TMeasureItemEvent OnMeasureItem;
      TDrawItemEvent OnDrawItem;
      typedef void __fastcall (_closure *TDrawItemEvent)(TWinControl* Control,int Index,Trect& Rect; TOwnerDrawState State);
      typedef void __fastcall(_closure* TMeasureItemEvent)(TWinControl* Control, int Index,int& Height);

    OnMeasureItem事件传递一个参数Height,应用程序需要填写一项来决定这一项的高度,如果没有改变,则使用列表框的ItemHeight的值。lbOwnerDrawFixed风格的列表框不触发这一事件,故它使用自身的ItemHeight。OnDrawItem传递的Rect表示可在上作画的矩形区,程序可以使用列表框Canvas属性来画图。
     二 示例

      1 在IDE环境中,选择“File-New”,在对话框中双击“Component”,出现"New Component"对话框,在Ancestor Type中选择“TCustomListBox",在Class Name中输入"TImageListBox",点Create Uints,就生成一个类框架。

      2 在头文件(ImageListBox.h)中的相应域中,增加下列成员:

      private:
       Graphics::Tgraphic* tmpGraphic;
      protected:
       void __fastcall MyDrawItem(TWinControl *Control,int Index, const Trect &Rect,TOwnerDrawState State);
       void __fastcall MyMeasureItem(TWinControl *Control,int Index, int &Height);
      public:
       __fastcall TImageListBox(Tcomponent* Owner);
       __fastcall ~TImageListBox();
       void __fastcall AddImage(System::AnsiString Filename,System::AndiString* String);

       …

      3.在实现文件(ImageListBox.cpp)定义以下函数:
       void __fastcall TImageListBox::MyMeasureItem(TWinControl *Control,int Index, int &Height)
       {
        if(tmpGraphic)
         Height=tmpGraphic->Height+2;
         //因为C++ Builder中的列表框封装了LBS_HASSTRINGS特性,所以在这个事
         //件中不能采用诸如Items->Objects[Index]形式来取得图像数据。
       }

      void __fastcall TImageListBox::MyDrawItem(TWinControl *Control,int Index, const Trect &Rect,TOwnerDrawState State)
       {
       int Offset = 2; // 定义文本与图像的距离
       Tcanvas *pCanvas = ((TListBox *)Control)->Canvas;
       pCanvas->FillRect(Rect); //填充方框
       //取得图像对象
       Tgraphic* tmpImage=(Tgraphic*)(Items->Objects[Index]);
       pCanvas->Draw(Rect.Left+Offset,Rect.Top,tmpImage); //画图
       if(tmpImage)Offset+=tmpImage->Width+4;  //显示文本
       pCanvas->TextOut(Rect.Left + Offset, Rect.Top, ((TListBox *)Control)->Items->Strings[Index]);
       }
      //--------------------------------------------------------------------------
      void __fastcall TImageListBox::AddImage(System::AnsiString Filename,System::AnsiString* String)
      {
       //装载图像,并追加至Objects对象。
      if(Filename.Pos(".ico"))
       {
          tmpGraphic=new Graphics::Ticon();
       tmpGraphic->LoadFromFile(Filename);
        Items->AddObject(String,(Tobject*)tmpGraphic);
       }
      else if(Filename.Pos(".bmp"))
       {
          tmpGraphic=new Graphics::Tbitmap();
       tmpGraphic->LoadFromFile(Filename);
       Items->AddObject(String,(Tobject*)tmpGraphic);
       }
      tmpGraphic=NULL;
      }
      __fastcall TImageListBox::TImageListBox(Tcomponent* Owner):TCustomListBox(Owner)
       {
        Style=lbOwnerDrawVariable;
        OnDrawItem=MyDrawItem;
        OnMeasureItem=MyMeasureItem;
       }
       __fastcall TImageListBox::~TImageListBox()
       { //释放图像资源
        for(int i=0;iCount;i++)
        {
            &nb

        


    sp;if((tmpGraphic=(Tgraphic*)Items->Objects[i])!=NULL)
          delete tmpGraphic;
        }
       }


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/8/20 16:33:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    三 测试组件

      新建一个工程,先在工程中添加刚才建立的ImageListBox.cpp,并在主窗体的头文件(.h)及实现文件(.cpp)中增加#include "Imagelistbox.h". 然后在private域中增加一个成员:
    TImageListBox* Til;
      在窗体的构造函数中增加如下代码:
      Til=new TImageListBox(this);
      Til->Parent=this;
      Til->Width=80;
      Til->Height=90;
      Til->AddImage("1.ico","First");
      Til->AddImage("2.bmp,"Second");
      …

      在窗体的析构函数中增加一句:“delete Til;”,运行程序。

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2007/8/20 16:33:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/26 13:56:10

    本主题贴数2,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    917.969ms