http://users.atw.hu/delphicikk/listaz.php?id=2471&oldal=52

Problem/Question/Abstract:

What are the new virtual styles in the TListbox for, and whay are they important?

Answer:

One of the new features in Delphi 6 is the addition of styles lbVirtual and lbVirtualOwnerDraw to the standard TListBox. In all the Delphi 6 “What’s new” articles I’ve read this addition has received no more than a passing mention.

Why are Virtual List boxes important?

Have you ever been frustrated by the limitations of the TStrings' objects property or have had a need to create a custom display string in the list. Sure, you can assign any pointer you want to the object field of a string list but what if you already have a list container (like a Tlist) full of data. Why should you be forced to duplicate this data over to the TStrings associated with the TListBox. You should be able to just use it. Well, with a virtual list box you can.

During the past week I ran into a situation where I had a TInterfaceList and wanted to use the value returned from one of the Interface's functions as the text of the list item. Under Delphi 5 this required that I step down through the TInterfaceList calling the required interface method at each step to add the strings to the TListBox. Then I would need to synchronize any movement and selection in the list box with the TInterfaceList. Under Delphi 6, using a virtual list box, I was able merge my TInterfaceList and the TListbox into one highly usable pseudo object. That is, I was able to make the TListBox “aware” of the TInterfaceList directly.

(BTW, my original thought was to not use the TInterfaceList at all and just place the references to the Interface into the object field of the TStrings member of the list box.. As you all probably know, this was a bad idea since it totally screws the reference counting on the interface.)

Anyway I will not go into great detail about setting up a virtual list box since the Delphi help is pretty good on this. Basically you need to set the style to one of the 2 virtual styles, set the list box’s count to the number of items in the list and then fill in at few as one and as many as 3 events.

Here is a trivial sample that may help to fill in some blanks left by the lack of sample code in the help file.

I only wish that Borland could have also added this feature the other list controls like the comboboxes and the treeview.

unit Unit1;

interface

uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, ovcbase, ovcviewr, Vcl.StdCtrls; type
TForm3 = class( TForm )
ListBox1 : TListBox;
Button1 : TButton;
lblNumber : TLabel;
lblColor : TLabel;
Edit1 : TEdit;
procedure FormCreate( Sender : TObject );
procedure FormDestroy( Sender : TObject );
procedure ListBox1Data( Control : TWinControl; Index : Integer;
var Data : string );
procedure ListBox1DataObject( Control : TWinControl; Index : Integer;
var DataObject : TObject );
function ListBox1DataFind( Control : TWinControl; FindString : string )
: Integer;
procedure Button1Click( Sender : TObject );
procedure ListBox1Click( Sender : TObject );
private
{ Private declarations }
public
{ Public declarations }
ObjList : TList;
end; TMyObj = class
fColor : string;
fNumber : Integer;
constructor create( const color : string; const Number : Integer );
end; var
Form3 : TForm3; implementation {$R *.dfm}
{ TMyObj } constructor TMyObj.create( const color : string; const Number : Integer );
begin
fColor := color;
fNumber := Number;
end; procedure TForm3.Button1Click( Sender : TObject );
begin
ListBox1.ItemIndex := ListBox1.Items.IndexOf( Edit1.Text );
// I don't think this next should be necessary but..
//ListBox1Click( Self );
end; procedure TForm3.FormCreate( Sender : TObject );
begin
// create a TList and add some data to it.
ObjList := TList.create;
ObjList.Add( TMyObj.create( 'Red', ) );
ObjList.Add( TMyObj.create( 'Yellow', ) );
ObjList.Add( TMyObj.create( 'Blue', ) );
ObjList.Add( TMyObj.create( 'Green', ) );
ObjList.Add( TMyObj.create( 'Brown', ) );
ObjList.Add( TMyObj.create( 'Black', ) );
ObjList.Add( TMyObj.create( 'White', ) );
ObjList.Add( TMyObj.create( 'Orange', ) );
// ABSOLUTELY REQUIRED Set the count of the virtual listbox
ListBox1.Count := ObjList.Count;
end; procedure TForm3.FormDestroy( Sender : TObject );
var
I : Integer;
begin
for I := to ObjList.Count - do
TMyObj( ObjList.Items[ I ] ).free;
ObjList.free;
end; procedure TForm3.ListBox1Click( Sender : TObject );
begin
lblColor.Caption :=
TMyObj( ListBox1.Items.objects[ ListBox1.ItemIndex ] ).fColor;
lblNumber.Caption :=
IntToStr( TMyObj( ListBox1.Items.objects[ ListBox1.ItemIndex ] ).fNumber ); end; procedure TForm3.ListBox1Data( Control : TWinControl; Index : Integer;
var Data : string );
begin
Data := TMyObj( ObjList.Items[ index ] ).fColor;
end; function TForm3.ListBox1DataFind( Control : TWinControl; FindString : string )
: Integer;
var
I : Integer;
begin
// the simplest but most brain dead approach
result := -;
for I := to TListBox( Control ).Count - do
if TListBox( Control ).Items[ I ] = FindString then
result := I;
end; procedure TForm3.ListBox1DataObject( Control : TWinControl; Index : Integer;
var DataObject : TObject );
begin
DataObject := ObjList.Items[ index ];
end; end.
object Form3: TForm3
Left =
Top =
Caption = 'Form3'
ClientHeight =
ClientWidth =
Color = clBtnFace
Font.Charset = GB2312_CHARSET
Font.Color = clWindowText
Font.Height = -
Font.Name = 'Fixedsys'
Font.Style = []
OldCreateOrder = False
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch =
TextHeight =
object lblNumber: TLabel
Left =
Top =
Width =
Height =
Caption = 'lblNumber'
end
object lblColor: TLabel
Left =
Top =
Width =
Height =
Caption = 'Label1'
end
object ListBox1: TListBox
Left =
Top =
Width =
Height =
Style = lbVirtual
TabOrder =
OnClick = ListBox1Click
OnData = ListBox1Data
OnDataFind = ListBox1DataFind
OnDataObject = ListBox1DataObject
end
object Button1: TButton
Left =
Top =
Width =
Height =
Caption = 'Button1'
TabOrder =
OnClick = Button1Click
end
object Edit1: TEdit
Left =
Top =
Width = Height =
TabOrder =
Text = 'Orange'
end
end

TListBoxStyle specifies the way a listbox control gets its data and how it is drawn.

TListBoxStyle = (
lbStandard,
lbOwnerDrawFixed,
lbOwnerDrawVariable,
lbVirtual,
lbVirtualOwnerDraw
);

The following table lists the values for the TListBoxStyle type:

Value 
Meaning 
lbStandard  
All items are strings, with each item the same height.  
lbOwnerDrawFixed  
The list box is owner-drawn, but each item in the list box is the height specified by the ItemHeight property. Each time an item is displayed in an lbOwnerDrawFixed list box, the OnDrawItem event occurs. The event handler for OnDrawItem draws the specified item. The ItemHeight property determines the height of each of the items.  
lbOwnerDrawVariable  
The list box is owner-drawn, and items in the list box can be of varying heights. Each time an item is displayed in an lbOwnerDrawVariable list box, two events occur. The first is the OnMeasureItem event. The code for the OnMeasureItem handler can set the height of each item. Then the OnDrawItem event occurs. The code for the OnDrawItem handler draws each item in the list box using the size specified by the OnMeasureItem handler.  
lbVirtual  
The list box is virtual, but all items are strings with the same height. You must indicate the number of items in the list box by setting the Count property. You must supply the items in the list box using an OnData event handler. If the items have associated objects, you must supply them using an OnDataObject event handler. In addition, you must supply an OnDataFind event handler to provide the mapping from the strings in the list box to their indexes.  
lbVirtualOwnerDraw  
The list box is virtual and owner-drawn. All items are the same height. As with lbOwnerDrawFixed, the item height is specified by the ItemHeight property, and you must draw items using an OnDrawItem event handler. As with lbVirtual, you must set the Count property and supply OnData and OnDataFind event handlers to provide the mapping between items and indexes. If items are associated with objects, you must also supply an OnDataObject event handler.  

The New Virtual List Box in Delphi 6 - lbVirtual lbVirtualOwnerDraw的更多相关文章

  1. [转载]virtual box如何生成新的UUID

    原文地址:virtual box如何生成新的UUID作者:阿昭 问题描述:在为Virtual Box加载多台虚拟机器(显然这些虚拟机器都来自一个模板)的时候,出现如下错误: "Cannot ...

  2. [SQL in Azure] Provisioning a SQL Server Virtual Machine on Azure

    http://azure.microsoft.com/en-us/documentation/articles/virtual-machines-provision-sql-server/ Provi ...

  3. Massive Collection Of Design Patterns, Frameworks, Components, And Language Features For Delphi

    Developer beNative over on GitHub has a project called Concepts which is a massive collection of Del ...

  4. Delphi一共封装(超类化)了8种Windows基础控件和17种复杂控件

    超类化源码: procedure TWinControl.CreateSubClass(var Params: TCreateParams; ControlClassName: PChar); con ...

  5. NHibernate one-to-one

    NHibernate里面one-to-one有两种方式:主键关联和唯一外健关联 主键关联: 两个表拥有相同的主键字段,值相同的关联在一起.典型的应用是一个对象的属性太多,将常用的属性跟不常用的附加属性 ...

  6. Headfirst设计模式的C++实现——抽象工厂(Abstract Factory)

    Dough.h #ifndef _DOUGH_H #define _DOUGH_H class Dough { }; #endif ThinCrustDough.h #ifndef _THIN_CRU ...

  7. Headfirst设计模式的C++实现——简单工厂模式(Simple Factory)之二

    为了引出后续的工厂方法,把在简单工厂模式的基础上增加了新功能——加盟店 简而言之就是把原来的单一简单工厂(能生产cheese和greek两种pizza)细分成了纽约地区的和芝加哥地区的(每种地区都能生 ...

  8. Headfirst设计模式的C++实现——简单工厂模式(Simple Factory)

    Pizza.h #ifndef _PIZZA_H #define _PIZZA_H #include <iostream> #include <string> class Pi ...

  9. Head First 设计模式 (Eric Freeman / Elisabeth Freeman / Kathy Sierra / Bert Bates 著)

    1. 欢迎来到设计模式世界:设计模式入门 (已看) 策略模式 定义了算法族,分别分装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 设计原则 找出应用中可能需要变化之处,把它们 ...

随机推荐

  1. 关于ORA-04091异常的出现原因,以及解决方案

    问题分析 在Oracle中执行DML语句的时候是需要显示进行提交操作的.当我们进行插入的时候,会触发触发器执行对触发器作用表和扩展表的种种操作,但是这个时 候触发器和插入语句是在同一个事务管理中的,因 ...

  2. Guava cache功能简介(转)

    原文链接:http://ifeve.com/google-guava-cachesexplained/ 范例 LoadingCache<Key, Graph> graphs = Cache ...

  3. java版云笔记(九)之动态sql

    SQL 首先,所谓SQL的动态和静态,是指SQL语句在何时被编译和执行,二者都是用在SQL嵌入式编程中的,这里所说的嵌入式是指将SQL语句嵌入在高级语言中,而不是针对于单片机的那种嵌入式编程. 静态S ...

  4. csu 1555(线段树经典插队模型-根据逆序数还原序列)

    1555: Inversion Sequence Time Limit: 2 Sec  Memory Limit: 256 MBSubmit: 469  Solved: 167[Submit][Sta ...

  5. 在Windows中安装Boot2Docker 遇到 Unable to load R3 module 的解决方案

    引言 这个几乎是所有64位win7用户在virtual box上安装64位的linux都会遇到的问题(如果你用的是买机器的时候自带的win7 64位而且你没有重装过系统的除外). 解决办法 可参考以下 ...

  6. 2019.2.25 模拟赛T1【集训队作业2018】小Z的礼物

    T1: [集训队作业2018]小Z的礼物 我们发现我们要求的是覆盖所有集合里的元素的期望时间. 设\(t_{i,j}\)表示第一次覆盖第i行第j列的格子的时间,我们要求的是\(max\{ALL\}\) ...

  7. vscode vue配置和一些其它辅助【工具篇】

    后续有补充就经常更新

  8. vue配置二级目录&vue-axios跨域办法&谷歌浏览器设置跨域

    一.根据官方建议,dist打包的项目文件放在服务器根目录下,但是很多时候,我们并不能这样做,当涉及到二级目录设置多层深埋的时候,就需要在webpack配置文件里去设置一下了. 在webpack.con ...

  9. “裕同集团&易普优APS项目启动大会”顺利召开

    “裕同集团&易普优APS项目启动大会”顺利召开 ——易普优APS助力裕同集团实现精益生产 2017年7月05日,“裕同集团&易普优APS项目启动大会”顺利召开,裕同集团高级王副总裁.I ...

  10. 易普优APS 5.0高级计划排程系统助力工业4.0智能工厂建设

    (一)智能工厂建设核心 <中国制造2025>明确提出要推进制造过程智能化,智能工厂是实现智能制造的重要载体.作为智能工厂,在生产过程应实现自动化.透明化.可视化.精益化的同时,产品检测.质 ...