如何从listview中的资源正确绘制gif图像?

时间:2015-10-22 01:23:53

标签: delphi listview delphi-xe7

我有listview项目,我尝试将图片添加到subitem作为status-image我已经可以从图像列表中设置图像但我想获取图像列表并使用图像从资源我已经创建了资源文件,并尝试将Tgifimage添加到项目绘制,但现在图像图像不绘制

这是我的代码

procedure TForm1.Add_Item(strCaption: String; ListView: TListView;
  strFile: String; boolBlink: Boolean; strUniqueID: String;
  CurrentStatus: string);
var
  Item: TListItem;
begin
  Item := ListView1.Items.Add;
  Item.Caption := '';
  Item.SubItems.Add(strCaption);// subitem 0
  Item.SubItems.AddObject( '0', nil ); // subitem 1
  Item.SubItems.Add( strUniqueID ); // subitem 2 // UniqueID
  Item.SubItems.Add('0'); // subitem 3 // Next User Idx (beside)
  Item.SubItems.Add(Currentstatus); // subitem 4 // StateIdx
  Item.Data := nil;
  SetItemStatusGif(Item, Currentstatus); // here start to set status
  end;

  // here setitemStatusGif procedure

  procedure TForm1.SetItemStatusGif(Item: TListItem; State: String);
  var
    ResStream: TResourceStream;
    aGif: TGifImage;
    strStateImg: String;
    ImgIdx: Integer;
  begin
    strStateImg := 'State_' + State;
    ImgIdx := StatusGifs.IndexOf(strStateImg);
    if ImgIdx <> -1 then
      aGif := TGifImage(StatusGifs.Objects[ImgIdx])
    else
    begin
      try
        ResStream := TResourceStream.Create(HInstance, strStateImg, RT_RCDATA);
        try
          aGif := TGifImage.Create;
          try
            aGif.LoadFromStream(ResStream);
            aGif.Transparent := True;
            StatusGifs.AddObject(strStateImg, aGif);
          except
            aGif.Free;
            raise;
          end;
        finally
          ResStream.Free;
        end;
      except
        aGif := nil;
      end;
    end;
    Item.SubItems.Objects[1] := aGif;
    ListView1.UpdateItems(Item.Index, Item.Index);
  end;

  // here listview draw event code
procedure TForm1.ListView1DrawItem(Sender: TCustomListView; Item: TListItem;
    Rect: TRect; State: TOwnerDrawState);
Var
    xOff, yOff: Integer;
    R: TRect;
    i: Integer;
    NewRect: TRect;
begin
    With TListView(Sender).Canvas do
    begin // User State Image
    if (StrToint(Item.SubItems[1]) <> 0) And (Item.SubItems[1] <> '') then
    begin
    NewRect := Rect;
    NewRect.Left   := NewRect.Left + 2;
    NewRect.Width  := 24;
    Newrect.Height :=  23;
    NewRect.Top    := NewRect.Top;
    NewRect.Bottom := NewRect.Bottom;
    if Panel2.Visible AND (Item.Index = 0) then
    //do nothing
else
   Sender.Canvas.StretchDraw( NewRect, TGIFImage( Item.SubItems.Objects[1])  );
   end;
       end;
        end;


procedure TForm1.Timer1Timer(Sender: TObject);
begin
ListView1.Invalidate; // This is for animation over ListView Canvas
end;

1 个答案:

答案 0 :(得分:3)

我们在一个月前在您的另一个问题中介绍过这个问题:

how do i update listview item index inside thread

在该问题中,您正在从在线下载图像,其中下载线程创建TGifImage对象并将其分配给TListItem以进行绘制。现在,您要添加资源图像。您仍然需要为它们创建一个TGifImage对象,并将其分配给您的TListItem对象,以便您可以绘制它。您只需要使用线程来处理它。当您向列表中添加新项目时,可以立即创建TGifImage对象并从资源中填充它,例如:

type
  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject); 
    procedure FormDestroy(Sender: TObject); 
    procedure ListView1Deletion(Sender: TObject; Item: TListItem);
    ...
  private
    StatusGifs: TStringList;
    procedure Add_Item(strCaption: String; ListView: TListView; strFile: String; boolBlink: Boolean; strUniqueID: String; CurrentStatus: string);
    procedure StatuseHandle;
    procedure SetItemStatusGif(Item: TListItem; State: String);
    ...
  end;

procedure TForm1.FormCreate(Sender: TObject); 
begin
  StatusGifs := TStringList.Create(True);
end;

procedure TForm1.FormDestroy(Sender: TObject); 
begin
  StatusGifs.Free;
end;

procedure TForm1.ListView1Deletion(Sender: TObject; Item: TListItem);
begin
  TGifImage(Item.SubItems.Objects[1]).Free;
  TGifImage(Item.Data).Free;
end;

procedure TForm1.Add_Item(strCaption: String; ListView: TListView; strFile: String; boolBlink: Boolean; strUniqueID: String; CurrentStatus: string);
var
  Item: TListItem;
begin
  Item := ListView1.Items.Add;
  Item.Caption := '';
  Item.SubItems.Add( strCaption ); // subitem 0
  Item.SubItems.AddObject( 'IMA', TGifImage.Create ); // subitem 1
  Item.SubItems.Add( strUniqueID ); // subitem 2 // UniqueID
  Item.SubItems.Add('0'); // subitem 3 // Next User Idx (beside)
  Item.SubItems.Add(Currentstatus); // subitem 4 // StateIdx
  Item.Data := nil; // populated by TURLDownload

  SetItemStatusGif(Item, Currentstatus);
  TURLDownload.Create(strFile, UpdateVisual, Item);
end;

procedure TForm1.StatuseHandle;
var
  i : integer;
  Item : TListItem;
begin
  try
    for i := 0 to ListView1.Items.Count-1 do
    begin
      Item := ListView1.Items[i];
      if Item.SubItems[2] = Trim(LineToid) then
      begin
        Item.SubItems[4] := LineTostatus;
        SetItemStatusGif(Item, LineTostatus);
      end;
    end;
  except
  end;
end;

procedure TForm1.SetItemStatusGif(Item: TListItem; State: String);
var
  ResStream  : TResourceStream;
  aGif : TGifImage;
  strStateImg : String;
  ImgIdx: Integer;
begin
  strStateImg := 'State_' + State;

  ImgIdx := StatusGifs.IndexOf(strStateImg);
  if ImgIdx <> -1 then
    aGif := TGifImage(StatusGifs.Objects[ImgIdx])
  else
  begin
    try
      ResStream  := TResourceStream.Create(HInstance, strStateImg, RT_RCDATA);
      try
        aGif := TGifImage.Create;
        try
          aGif.LoadFromStream(ResStream);
          aGif.Transparent := True;
          StatusGifs.AddObject(strStateImg, aGif);
        except
          aGif.Free;
          raise;
        end;
      finally
        ResStream.Free;
      end;
    except
      aGif := nil;
    end;
  end;

  TGifImage(Item.SubItems.Objects[1]).Assign(aGif);
  ListView1.UpdateItems(Item.Index, Item.Index);
end;