listview 显示缩略图问题(200分)

  • 主题发起人 song2all
  • 开始时间
S

song2all

Unregistered / Unconfirmed
GUEST, unregistred user!
不要用listview+imagelist的。有没控件或告知该控件地址的?然后根据记录移动显示出字段中的图片,图片是以文件位置方式保存在字段中的。如有个“图片”字段,里面有图片位置信息,如“d:/aa/员工.jpg”,然后记录一移动,listview便显示相关图片.谢谢大家~!
 
没有人回答吗?200分啊,我自己顶一下
 
God.does anybody know about it?
 
200 extra scores will be offered if it get correct answer
 
这还用控件? 自己画不就行了,用不到imagelist
listview+hint就够用了
下面代码是我在实际项目中用的一段 ,你自己改改hint里的draw就行了
TDData=record {我定义了个结构放在item的data里,你把那个图片部分换成你自己的字段就行了}
ID,
Memo,
Picture, {图片}
Music:string;
end;
PDData=^TDData;
procedure OnHintTime(var msg:tmessage);message WM_TIMER;
var
_hint:THintWindow;
HintItem:TListItem;
create部分:
begin
_hint:=THintWindow.Create(self);
_hint.DoubleBuffered:=true;
end;

procedure Tfrm_reslist.LVMouseMove(Sender: TObject;
Shift: TShiftState;
X,
Y: Integer);
var
item:tlistitem;
begin
item:=tlistview(sender).GetItemAt(x,y);
if not (assigned(item) and assigned(item.Data)) then
begin
KillTimer(Handle, 1);
_hint.ReleaseHandle;
HintItem:=nil;
exit;
end;
if (item<>HintItem) then
begin
HintItem:=item;
_hint.ReleaseHandle;
KillTimer(Handle, 1);
SetTimer(Handle, 1, 300, nil);
TListView(Sender).Refresh;
end;
end;

procedure Tfrm_reslist.LVCustomDrawItem(Sender: TCustomListView;
Item: TListItem;
State: TCustomDrawState;
var DefaultDraw: Boolean);
begin
if (HintItem=item) and (not (cdsSelected in State)) then
Sender.Canvas.Brush.Color:=$00E0E0E0
else
Sender.Canvas.Brush.Color:=clWindow;
end;

procedure Tfrm_reslist.OnHintTime(var msg:tmessage);
const
PicWidth=200;
PicHeight=150;
var
pic:tpicture;
Dbmp,Sbmp:tbitmap;
th,tw,tmpi:integer;
_rect,tmprect:trect;
tmppt:tpoint;
HintData:pDData;
str,
picname:string;
begin
KillTimer(Handle, 1);
if assigned(HintItem.Data) then
begin
HintData:=HintItem.Data;
Dbmp:=tbitmap.Create;
Sbmp:=tbitmap.Create;
try
with lv.ClientRectdo
begin
tmppt:=clienttoscreen(point(Left+50,HintItem.Position.Y+50));
_rect.Left:=tmppt.X;
_rect.Top:=tmppt.Y;
_rect.Right:=_rect.Left+Right-Left-100;
end;
Dbmp.Width:=PicWidth;
Dbmp.Height:=PicHeight;
picname:=RESPath+HintData.Picture;
{这部分换成你自己纪录图片位置的字段就行了}
if fileexists(picname) then
begin
pic:=tpicture.Create;
try
pic.LoadFromFile(picname);
Sbmp.Assign(pic.Graphic);
SetStretchBltMode(dbmp.Canvas.Handle,HalfTone);
stretchBlt(Dbmp.Canvas.Handle,0,0,PicWidth,PicHeight,
Sbmp.Canvas.Handle,0,0,Sbmp.Width,Sbmp.Height,SRCCOPY);
finally
pic.Free;
end;
end
else
with dbmp.Canvasdo
{无图片}
begin
Brush.Color:=clgray;
FillRect(rect(0,0,PicWidth,PicHeight));
str:='无资源图片';
th:=TextHeight(str);
tw:=TextWidth(str);
TextOut((PicWidth-tw) div 2,(PicHeight-th) div 2,str);
end;
{下面是显示文字,不要可以直接删掉}
tw:=_rect.Right-_rect.Left-PicWidth-15;
{文字输出宽度}
tmprect:=rect(PicWidth+10,5,PicWidth+10+tw,0);
txtstrs.Text:=HintData.Memo;
if txtstrs.Count>20 then
begin
tmpstrs.Clear;
for tmpi:=0 to 19do
tmpstrs.Add(txtstrs.Strings[tmpi]);
str:=tmpstrs.Text;
end
else
str:=txtstrs.Text;
tmpi:=Length(str);
DrawText(_hint.Canvas.Handle,pchar(str),tmpi,tmprect,
DT_WORDBREAK or DT_LEFT or DT_CALCRECT);
th:=tmprect.Bottom-tmprect.Top;;
if th>PicHeight then
_rect.Bottom:=_rect.Top+th+10
else
_rect.Bottom:=_rect.Top+PicHeight+10;
_hint.ActivateHint(_rect,'');
_hint.Refresh;
_hint.Canvas.Draw(5,5,dbmp);
SetBkMode(_hint.Canvas.Handle,Transparent);
DrawText(_hint.Canvas.Handle,pchar(str),tmpi,tmprect,
DT_WORDBREAK or DT_LEFT);
finally
Sbmp.Free;
Dbmp.Free;
end;
end;
end;
 
如果这个员工有多张图片的话,如: 员工#001,然后另一个员工图片表,专门放该员工001的多张图片。那记录移动时,以上的代码可以实现吗?
 
都没人能懂吗?
 
......还没搞定?
不明白这有什么难的,上面的代码就是个随鼠标在纪录上的移动显示不同纪录对应图片的效果
员工图片表,把图片取出来同样的方法画到hint上不就行了?多张图片就在hint上的不同位置多draw几次不就OK了?
 
hs-kill,虽然看不懂以上你的代码,但明白肯定可行,谢谢~,我看看是否有其它简单的方法~
 
-_-......其实.....过程很简单
首先定义个公共变量纪录当前显示图片的纪录
然后在鼠标移动事件里判断当前鼠标所在的纪录是否已经显示
如果没显示则判断是否hint已经显示,如果有则先隐藏,再生成timer 300毫秒后触发显示图片的事件
如果和上次显示的是同一条纪录则不做任何操作
在显示图片事件中先获取当前纪录的rect 然后定义对应的hint的rect
然后获取图片大小,计算图片显示的位置,然后在这个位置上draw出来 就OK了....
 
顶部