DELPHI实现动态信息显示功能
{ 
unit : thashmap_unit 
class : thashmap 
描述 : 哈希表实现工具
} 
interface 
uses classes, sysutils; 
type 
thashmap = class 
private 
m_list_primary : tstringlist; 
m_list_keyvalue : tstringlist; 
m_list_type : tstringlist; 
public 
c create(); 
destructor destroy; override; 
{ 
加入值 
可以加入空值,但主键不能为空 
} 
procedure add(p_str_key : string; p_str_value : string; p_object : tobject = nil); 
//删除 
procedure remove(p_str_key : string); overload; 
procedure remove(p_int_pos : integer); overload; 
//全部删除 
procedure removeall(); 
{ 
获取项目总数,利用此方法可以遍历所有项目,例如: 
for i := 1 to obj.getcount() do 
begin 
m_str := obj.getvalue(i – 1); 
…m_str… 
end; 
} 
function getcount() : integer; 
{ 
根据位置信息获取主键名称 
} 
function getkeyname(p_int_pos : integer) : string; 
{ 
根据主键名导出键值 
} 
function getvalue(p_str_key : string) : string; overload; 
{ 
根据主键名导出节点数据 
} 
function getdata(p_str_key : string) : tobject; overload; 
{ 
gettype 
返回值 : 
0 : 无data 
1 : 有data 
} 
function gettype(p_str_key : string) : string; overload; 
{ 
根据索引号导出键值 
注意此方法索引值为: 
0 to getcount() – 1 
} 
function getvalue(p_int_index : integer) : string; overload; 
function gettype(p_int_index : integer) : string; overload; 
function getdata(p_int_index : integer) : tobject; overload; 
end;
implementation
c thashmap.create(); 
begin 
self.m_list_primary := tstringlist.create; 
self.m_list_keyvalue := tstringlist.create; 
self.m_list_type := tstringlist.create; 
end; 
destructor thashmap.destroy(); 
begin 
self.m_list_primary.free; 
self.m_list_keyvalue.free; 
self.m_list_type.free; 
end; 
procedure thashmap.add(p_str_key : string; p_str_value : string; p_object : tobject = nil); 
var 
m_int_pos : integer; 
begin 
if (trim(p_str_key) = '') then 
begin 
exit; 
end; 
m_int_pos := self.m_list_primary.indexof(p_str_key); 
if m_int_pos = -1 then 
begin 
//未重复 
self.m_list_primary.add(p_str_key); 
self.m_list_keyvalue.addobject(p_str_value, p_object); 
end 
else 
begin 
//重复,则替换 
self.m_list_keyvalue.strings[m_int_pos] := p_str_key; 
self.m_list_keyvalue.objects[m_int_pos] := p_object; 
end; 
if p_object = nil then 
begin 
self.m_list_type.add('0'); 
end 
else 
begin 
self.m_list_type.add('1'); 
end; 
end; 
procedure thashmap.remove(p_str_key : string); 
var 
m_int_pos : integer; 
m_obj : tobject; 
begin 
m_int_pos := self.m_list_primary.indexof(p_str_key); 
if m_int_pos <> -1 then 
begin 
m_obj := self.m_list_keyvalue.objects[m_int_pos]; 
if m_obj <> nil then 
begin 
m_obj.free; 
end; 
self.m_list_primary.delete(m_int_pos); 
self.m_list_keyvalue.delete(m_int_pos); 
self.m_list_type.delete(m_int_pos); 
end; 
end; 
procedure thashmap.remove(p_int_pos : integer); 
var 
m_obj : tobject; 
begin 
if ((p_int_pos < 0) or (p_int_pos > self.getcount())) then 
begin 
exit; 
end; 
//删除 
m_obj := self.m_list_keyvalue.objects[p_int_pos]; 
if m_obj <> nil then 
begin 
//dispose(m_obj); 
m_obj.free; 
end; 
self.m_list_primary.delete(p_int_pos); 
self.m_list_keyvalue.delete(p_int_pos); 
self.m_list_type.delete(p_int_pos); 
end; 
procedure thashmap.removeall(); 
var 
i : integer; 
m_obj : tobject; 
begin 
for i := 1 to self.m_list_keyvalue.count do 
begin 
m_obj := self.m_list_keyvalue.objects[i – 1]; 
if m_obj <> nil then 
begin 
m_obj.free; 
end; 
end; 
self.m_list_primary.clear; 
self.m_list_keyvalue.clear; 
self.m_list_type.clear; 
end; 
function thashmap.getcount() : integer; 
begin 
result := self.m_list_primary.count; 
end; 
function thashmap.getkeyname(p_int_pos : integer) : string; 
begin 
if ((p_int_pos >= 0) and (p_int_pos < self.getcount)) then 
begin 
result := self.m_list_primary.strings[p_int_pos]; 
end 
else 
begin 
result := ''; 
end; 
end; 
function thashmap.getvalue(p_str_key : string) : string; 
var 
m_int_pos : integer; 
begin 
m_int_pos := self.m_list_primary.indexof(p_str_key); 
if m_int_pos = -1 then 
begin 
result := ''; 
end 
else 
begin 
result := self.m_list_keyvalue.strings[m_int_pos]; 
end; 
end; 
function thashmap.getdata(p_str_key : string) : tobject; 
var 
m_int_pos : integer; 
begin 
m_int_pos := self.m_list_primary.indexof(p_str_key); 
if m_int_pos = -1 then 
begin 
result := nil; 
end 
else 
begin 
result := self.m_list_keyvalue.objects[m_int_pos]; 
end; 
end; 
function thashmap.gettype(p_str_key : string) : string; 
var 
m_int_pos : integer; 
begin 
m_int_pos := self.m_list_primary.indexof(p_str_key); 
if m_int_pos = -1 then 
begin 
result := '0'; 
end 
else 
begin 
result := self.m_list_type.strings[m_int_pos]; 
end; 
end; 
function thashmap.getvalue(p_int_index : integer) : string; 
begin 
if ((p_int_index >= 0) and (p_int_index < self.getcount)) then 
begin 
result := self.m_list_keyvalue.strings[p_int_index]; 
end 
else 
begin 
result := ''; 
end; 
end; 
function thashmap.gettype(p_int_index : integer) : string; 
begin 
if ((p_int_index >= 0) and (p_int_index < self.getcount)) then 
begin 
result := self.m_list_type.strings[p_int_index]; 
end 
else 
begin 
result := ''; 
end; 
end; 
function thashmap.getdata(p_int_index : integer) : tobject; 
begin 
if ((p_int_index >= 0) and (p_int_index < self.getcount)) then 
begin 
result := self.m_list_keyvalue.objects[p_int_index]; 
end 
else 
begin 
result := nil; 
end; 
end; 
end.
{ 
unit : tinfopanel_unit 
class : tinfopanel 
描述 : 信息载体 
设计者 : sunny 
生成日期 : 20060802 
} 
interface
uses forms, thashmap_unit, classes, c stdctrls, sysutils;
type 
tinfopanel = class(tscrollbox) 
private 
m_comp : tlist; 
m_comp : tlist; 
m_hash : thashmap; 
m_int_left : integer; //左边界位置 
m_int_top : integer; //上边界位置 
m_int_labelwidth : integer; //label宽度 
m_int_valuewidth : integer; //值域宽度 
m_int_rowheight : integer; //每条记录高度 
m_int_rowtorow : integer; //每两个记录之间的隔断距离 
m_int_coltocol : integer; //每个记录label和value之间的距离 
public 
c create(aowner: tcomp override; 
destructor destroy; override; 
//talign = (aln altop, albottom, alleft, alright, alclient, alcustom); 
procedure setposandsize(p_int_left, p_int_top, p_int_width, p_int_height : integer; p_alg : talign = aln 
{ 
设置和获取哈希表对象 
} 
procedure sethashmap(p_hash : thashmap); 
function gethashmap() : thashmap; 
{ 
获取更新后的哈希表 
获取控件值 
用户根据返回值是否为空判断用户输入是否有空值 
此功能的初忠是用于将用户更改操作后的数据存储到数据库中 
} 
function restorhashmap() : thashmap; 
{ 
设置显示每条记录时的尺寸 
} 
procedure setleft(p_int_left : integer); 
procedure settop(p_int_top : integer); 
procedure setlabelwidth(p_int_width : integer); 
procedure setvaluewidth(p_int_width : integer); 
procedure setrowheight(p_int_height : integer); 
procedure setrowtorow(p_int_rowtorow : integer); 
procedure setcoltocol(p_int_coltocol : integer); 
{ 
释放已有的对象列表 
} 
procedure destroycomp 
{ 
生成显示信息 
} 
procedure updateinfomati 
end; 
implementation
c tinfopanel.create(aowner: tcomp 
begin 
inherited create(aowner); 
m_comp := tlist.create; 
m_comp := tlist.create; 
m_int_left := 2; //左边界位置 
m_int_top := 10; //上边界位置 
m_int_labelwidth := 80; //label宽度 
m_int_valuewidth := 80; //值域宽度 
m_int_rowheight := 20; //每条记录高度 
m_int_rowtorow := 50; //行间隔 
m_int_coltocol := 10; //列间隔 
end; 
destructor tinfopanel.destroy(); 
begin 
m_components_label.free; 
m_components_edit.free; 
if self.m_hash <> nil then 
begin 
self.m_hash.free; 
end; 
inherited destroy; 
end; 
procedure tinfopanel.setposandsize(p_int_left, p_int_top, p_int_width, p_int_height : integer; p_alg : talign = aln 
begin 
self.align := p_alg; 
self.left := p_int_left; 
self.top := p_int_top; 
self.width := p_int_width; 
self.height := p_int_height; 
end; 
procedure tinfopanel.sethashmap(p_hash : thashmap); 
begin 
self.m_hash := p_hash; 
end; 
function tinfopanel.gethashmap() : thashmap; 
begin 
result := self.m_hash; 
end; 
function tinfopanel.restorhashmap() : thashmap; 
var 
i : integer; 
m_hash : thashmap; 
begin 
m_hash := thashmap.create; 
for i := 1 to self.m_components_label.count do 
begin 
if trim(tobject(self.m_components_edit.items[i – 1]).classname) = 'tedit' then 
begin 
m_hash.add(tlabel(self.m_components_label.items[i – 1]).capti tedit(self.m_components_edit.items[i – 1]).text); 
end 
else 
begin 
m_hash.add(tlabel(self.m_components_label.items[i – 1]).capti tcombobox(self.m_components_edit.items[i – 1]).text); 
end; 
end; 
result := m_hash; 
end; 
procedure tinfopanel.setleft(p_int_left : integer); 
begin 
self.m_int_left := p_int_left; 
end; 
procedure tinfopanel.settop(p_int_top : integer); 
begin 
self.m_int_top := p_int_top; 
end; 
procedure tinfopanel.setlabelwidth(p_int_width : integer); 
begin 
self.m_int_labelwidth := p_int_width; 
end; 
procedure tinfopanel.setvaluewidth(p_int_width : integer); 
begin 
self.m_int_valuewidth := p_int_width; 
end; 
procedure tinfopanel.setrowheight(p_int_height : integer); 
begin 
self.m_int_rowheight := p_int_height; 
end; 
procedure tinfopanel.setrowtorow(p_int_rowtorow : integer); 
begin 
self.m_int_rowtorow := p_int_rowtorow; 
end; 
procedure tinfopanel.setcoltocol(p_int_coltocol : integer); 
begin 
self.m_int_coltocol := p_int_coltocol; 
end; 
procedure tinfopanel.destroycomp 
var 
i : integer; 
obj : pointer; 
begin 
if self.m_comp = nil then 
begin 
exit; 
end; 
for i := self.m_components_label.count downto 1 do 
begin 
obj := self.m_comp – 1]; 
dispose(obj); 
end; 
for i := self.m_components_edit.count downto 1 do 
begin 
obj := self.m_comp – 1]; 
dispose(obj); 
end; 
end; 
procedure tinfopanel.updateinfomati 
var 
i : integer; 
j : integer; 
m_str_label : string; 
m_str_value : string; 
m_str_type : string; 
m_lab : tlabel; 
m_edt : tedit; 
m_cob : tcombobox; 
m_list : tstringlist; 
begin 
if self.m_hash = nil then 
begin 
exit; 
end; 
//clear comp list 
self.destroycomp 
for i := 1 to self.m_hash.getcount() do 
begin 
m_str_label := self.m_hash.getkeyname(i – 1); 
m_str_value := self.m_hash.getvalue(i – 1); 
m_str_type := self.m_hash.gettype(i – 1); 
//create label 
m_lab := tlabel.create(nil); 
m_lab.parent := self; 
m_lab.caption := m_str_label; 
m_lab.left := self.m_int_left; 
m_lab.top := self.m_int_top + (i – 1) * self.m_int_rowheight + (i – 1) * self.m_int_rowtorow + 7; //标题向下7个像素偏移 
m_lab.width := self.m_int_labelwidth; 
m_lab.height := self.m_int_rowheight; 
m_lab.visible := true; 
//create edit or combobox 
if trim(m_str_type) = '1' then 
begin 
//create combobox 
m_cob := tcombobox.create(nil); 
m_cob.parent := self; 
m_cob.left := self.m_int_left + self.m_int_labelwidth + self.m_int_coltocol; 
m_cob.top := self.m_int_top + (i – 1) * self.m_int_rowheight + (i – 1) * self.m_int_rowtorow; 
m_cob.width := self.m_int_valuewidth; 
m_cob.height := self.m_int_rowheight; 
m_cob.visible := true; 
m_list := tstringlist(self.m_hash.getdata(i – 1)); 
for j := 1 to m_list.count do 
begin 
m_cob.items.add(m_list.strings[j – 1]); 
end; 
m_cob.text := m_str_value; 
self.m_components_edit.add(m_cob); 
end 
else 
begin 
//create edit 
m_edt := tedit.create(nil); 
m_edt.parent := self; 
m_edt.text := m_str_value; 
m_edt.left := self.m_int_left + self.m_int_labelwidth + self.m_int_coltocol; 
m_edt.top := self.m_int_top + (i – 1) * self.m_int_rowheight + (i – 1) * self.m_int_rowtorow; 
m_edt.width := self.m_int_valuewidth; 
m_edt.height := self.m_int_rowheight; 
m_edt.visible := true; 
self.m_components_edit.add(m_edt); 
end; 
self.m_components_label.add(m_lab); 
end; 
end; 
end.
实现调用:
m_hash : thashmap; 
m_list : tstringlist; 
begin 
m_list := tstringlist.create; 
m_list.add('1'); 
m_list.add('2'); 
m_list.add('3'); 
m_list.add('name4'); 
m_infopanel := tinfopanel.create(nil); 
m_hash := thashmap.create; 
m_hash.add('1sdfasdfasdfas', 'name1'); 
m_hash.add('2dffffes', 'name2'); 
m_hash.add('3', 'name3'); 
m_hash.add('4', 'name4', m_list); 
m_hash.add('5', 'name5'); 
m_hash.add('6', 'name6'); 
m_infopanel.sethashmap(m_hash); 
m_infopanel.setposandsize(100, 100, 300, 150, aln 
m_infopanel.setrowtorow(10); 
m_infopanel.setleft(30); 
m_infopanel.setrowheight(22); 
m_infopanel.color := clred; 
m_infopanel.parent := self; 
m_infopanel.updateinfomati 
end;
 
  	 