2016-04-28 140 views
3

我想以vtTest組件中的ImageList1作爲覆蓋圖顯示圖像。用TVirtualStringTree.OnGetImageIndex覆蓋圖像

我在互聯網上發現了很多資源,並在這裏像this - 但我不能讓他們都無法正常工作。

我確定我錯過了一些極其微不足道的東西,但我無法弄清楚它可能是什麼。


我能得到什麼:    enter image description here          我想什麼有:    enter image description here


這裏是包含這說明我的問題的基本連接的形式。

Unit1.pas

unit Unit1; 

interface 

uses 
    Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, 
    Vcl.Controls, Vcl.Forms, Vcl.Dialogs, VirtualTrees, Vcl.ImgList; 

type 
    PMyVtTestData = ^TMyVtTestData; 
    TMyVtTestData = record 
    isLocked: Boolean; 
    end; 

    TForm1 = class(TForm) 
    vtTest: TVirtualStringTree; 
    ImageList1: TImageList; 
    procedure FormCreate(Sender: TObject); 
    procedure vtTestGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; 
     Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; 
     var ImageIndex: Integer); 
    private 
    { Private declarations } 
    public 
    { Public declarations } 
    end; 

var 
    Form1: TForm1; 

implementation 

{$R *.dfm} 

procedure TForm1.FormCreate(Sender: TObject); 
var 
    i, j, m: Integer; 
    Node, Node1, Node2: PVirtualNode; 

    procedure SetCustomNodeDataValue(const Node: PVirtualNode; const Value: Boolean = False); 
    var 
    Data: PMyVtTestData; 
    begin 
    Data := vtTest.GetNodeData(Node); 
    Data^.isLocked := Value; 
    end; 
begin 
    vtTest.NodeDataSize := SizeOf(TMyVtTestData); 

    //initialize some node 
    //every TMyVtTestData.isLocked = False, except the 3rd TMyVtTestData.isLocked which is True 
    Randomize; 
    for i := 0 to Random(3)+3 do begin 
    Node := vtTest.AddChild(nil); 
    SetCustomNodeDataValue(Node, i = 2); 
    for j := 0 to Random(3)+2 do begin 
     Node1 := vtTest.AddChild(Node); 
     SetCustomNodeDataValue(Node1); 
     for m := 0 to Random(5) do begin 
     Node2 := vtTest.AddChild(Node1); 
     SetCustomNodeDataValue(Node2); 
     end; 
    end; 
    end; 
end; 

procedure TForm1.vtTestGetImageIndex(Sender: TBaseVirtualTree; 
    Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; 
    var Ghosted: Boolean; var ImageIndex: Integer); 
var 
    Data: PMyVtTestData; 
begin 

    if Node = nil then 
    Exit; 

    case Column of 
    0: begin 
     if Kind in [ikNormal, ikSelected] then 
     ImageIndex := 0 
     else if Kind = ikOverlay then begin 
     Data := Sender.GetNodeData(Node); 
     if Data^.isLocked then 
      ImageIndex := 1; 
     end; 
    end; 

    end; 
end; 

end. 

Unit1.dfm

object Form1: TForm1 
    Left = 0 
    Top = 0 
    Caption = 'Form1' 
    ClientHeight = 300 
    ClientWidth = 313 
    Color = clBtnFace 
    Font.Charset = DEFAULT_CHARSET 
    Font.Color = clWindowText 
    Font.Height = -11 
    Font.Name = 'Tahoma' 
    Font.Style = [] 
    OldCreateOrder = False 
    OnCreate = FormCreate 
    DesignSize = (
    313 
    300) 
    PixelsPerInch = 96 
    TextHeight = 13 
    object vtTest: TVirtualStringTree 
    Left = 8 
    Top = 8 
    Width = 298 
    Height = 284 
    Anchors = [akLeft, akTop, akRight, akBottom] 
    Header.AutoSizeIndex = -1 
    Header.Font.Charset = DEFAULT_CHARSET 
    Header.Font.Color = clWindowText 
    Header.Font.Height = -11 
    Header.Font.Name = 'Tahoma' 
    Header.Font.Style = [] 
    Header.Images = ImageList1 
    Header.Options = [hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible] 
    Images = ImageList1 
    TabOrder = 0 
    OnGetImageIndex = vtTestGetImageIndex 
    Columns = < 
     item 
     Position = 0 
     Width = 200 
     WideText = 'column' 
     end> 
    end 
    object ImageList1: TImageList 
    Left = 256 
    Top = 240 
    Bitmap = { 
     494C010102000500040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 
     0000000000003600000028000000400000001000000001002000000000000010 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000868686003535350000000000000000000000000000000000939393005757 
     5700000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000000000000000000000000000000000000000000000000000D9D9 
     D9000505050000000000B1B1B1000000000000000000FCFCFC00222222000000 
     0000A2A2A2000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000000000000000000000000000000000000000000000000000CCCC 
     CC00353535007D7D7D002525250066666600939393001E1E1E00646464003434 
     340085858500000000000000000000000000000000000000000000000000140C 
     EB00B1AEF900FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B1AE 
     F900140CEB000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000000000006E6E6E0000000000000000002E2E2E00000000000000 
     0000000000000000000000000000000000000000000000000000140CEB000000 
     00000300EA00B9B6F900FFFFFF00FFFFFF00FFFFFF00FFFFFF00B9B6F9000300 
     EA0000000000140CEB0000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000007171 
     7100000000002F2F2F0015151500D0D0D000F0F0F00031313100252525002121 
     21005F5F5F000000000000000000000000000000000000000000B1AEF9000300 
     EA002018EC00160DEC00B9B6F900FFFFFF00FFFFFF00B9B6F900160DEC002018 
     EC000300EA00B1AEF90000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000000000000000000000000000000000000000000000000000BFBF 
     BF00000000002222220000000000000000000000000000000000666666000000 
     0000979797000000000000000000000000000000000000000000FFFFFF00B9B6 
     F900160DEC002018EC000300EA00B1AEF900B1AEF9000300EA002018EC00160D 
     EC00B9B6F900FFFFFF0000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000096969600B9B9B900000000007676760048484800D8D8D800EEEEEE006565 
     6500F8F8F8000000000000000000000000000000000000000000FFFFFF00FFFF 
     FF00B9B6F9000300EA0000000000140CEB00140CEB00000000000300EA00B9B6 
     F900FFFFFF00FFFFFF0000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000E9E9E900313131000000000010101000000000009F9F9F000000 
     0000000000000000000000000000000000000000000000000000FFFFFF00FFFF 
     FF00FFFFFF00B1AEF900140CEB000000000000000000140CEB00B1AEF900FFFF 
     FF00FFFFFF00FFFFFF0000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000001919190000000000353535007272720000000000000000009999 
     9900000000000000000000000000000000000000000000000000FFFFFF00FFFF 
     FF00FFFFFF00B1AEF900140CEB000000000000000000140CEB00B1AEF900FFFF 
     FF00FFFFFF00FFFFFF0000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     00009A9A9A003B3B3B00000000004F4F4F0000000000B3B3B300C3C3C3004040 
     4000000000000000000000000000000000000000000000000000FFFFFF00FFFF 
     FF00B9B6F9000300EA0000000000140CEB00140CEB00000000000300EA00B9B6 
     F900FFFFFF00FFFFFF0000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     00000D0D0D0062626200000000006F6F6F0000000000E5E5E500000000000000 
     0000ADADAD000000000000000000000000000000000000000000FFFFFF00B9B6 
     F900160DEC002018EC000300EA00B1AEF900B1AEF9000300EA002018EC00160D 
     EC00B9B6F900FFFFFF0000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000000000000000000000000000000000000000000000000000E2E2 
     E2000202020001010100555555000A0A0A000000000033333300444444000000 
     0000848484000000000000000000000000000000000000000000B1AEF9000300 
     EA002018EC00160DEC00B9B6F900FFFFFF00FFFFFF00B9B6F900160DEC002018 
     EC000300EA00B1AEF90000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000000000000000000000000000000000000000000000000000DEDE 
     DE00040404000000000000000000000000000000000000000000000000000000 
     00007E7E7E000000000000000000000000000000000000000000140CEB000000 
     00000300EA00B9B6F900FFFFFF00FFFFFF00FFFFFF00FFFFFF00B9B6F9000300 
     EA0000000000140CEB0000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     00003C3C3C000000000000000000000000000000000000000000000000000000 
     0000BDBDBD00000000000000000000000000000000000000000000000000140C 
     EB00B1AEF900FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00B1AE 
     F900140CEB000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000E1E1E1000E0E0E0000000000000000000000000000000000000000007676 
     7600000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000F5F5F5008787870042424200363636005C5C5C00C3C3C3000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     0000000000000000000000000000000000000000000000000000000000000000 
     000000000000000000000000000000000000424D3E000000000000003E000000 
     2800000040000000100000000100010000000000800000000000000000000000 
     000000000000000000000000FFFFFF00F3CFFFFF00000000E187FFFF00000000 
     E007E00700000000FC3FD00B00000000E007C00300000000E3C7C00300000000 
     F207C24300000000F81FC18300000000F80FC18300000000F20FC24300000000 
     F227C00300000000E007C00300000000E007D00B00000000F007E00700000000 
     F00FFFFF00000000F81FFFFF0000000000000000000000000000000000000000 
     000000000000} 
    end 
end 

TIPS

  • VirtualTrees版本5.2.1德爾福XE4
  • ImageIndex := 1;vtTestGetImageIndex功能執行 - 調試器停止時有斷點在指數0設置
  • 圖像和1TImageList
  • 確實存在
  • 我已經能夠使用不同的圖像爲不同類型的節點沒有覆蓋
+0

優秀的問題。使用提供的信息很容易診斷問題。 – Johan

回答

4

您的項目中缺少兩件事。

  1. 疊加只會拿得出,如果他們有一個指數> = 15
  2. 您需要使用OnGetImageIndexEx,而不是普通的OnGetImageIndex

當您檢查VTV的來源時,原因就變得很清楚。

procedure TBaseVirtualTree.PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean); 
.... 
    // Now, draw the overlay. This circumnavigates limitations in the overlay mask index (it has to be 4 bits in size, 
    // anything larger will be truncated by the ILD_OVERLAYMASK). 
    // However this will only be done if the overlay image index is > 15, to avoid breaking code that relies 
    // on overlay image indices (e.g. when using system image lists). 
    if PaintInfo.ImageInfo[iiOverlay].Index >= 15 then //<<------! 
    // Note: XPos and YPos are those of the normal images. 
    DrawImage(ImageInfo[iiOverlay].Images, ImageInfo[iiOverlay].Index, Canvas, XPos, YPos, 
     Style[ImageInfo[iiOverlay].Images.ImageType] or ExtraStyle, DrawEnabled); 

!! Overlays with index < 15 do not get considered !! 

如果你不使用OnGetImageIndexEx從您的覆蓋被選中將是零的圖像列表,請參閱:

function TBaseVirtualTree.DoGetImageIndex(Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; 
    var Ghosted: Boolean; var Index: Integer): TCustomImageList; 

// Queries the application/descendant about certain image properties for a node. 
// Returns a custom image list if given by the callee, otherwise nil. 

begin 
    Result := nil; 

    // First try the enhanced event to allow for custom image lists. 
    if Assigned(FOnGetImageEx) then 
    FOnGetImageEx(Self, Node, Kind, Column, Ghosted, Index, Result) 
    else !! only the ....EX works for me !! 
    if Assigned(FOnGetImage) then 
     FOnGetImage(Self, Node, Kind, Column, Ghosted, Index); 
end; 

如果我用下面的代碼您的覆蓋工程:

procedure TForm1.vtTestGetImageIndexEx(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; 
    Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer; var ImageList: TCustomImageList); 
var 
    Data: PMyVtTestData; 
begin 

    if Node = nil then Exit; 

    case Column of 
    0: begin 
     if Kind in [ikNormal, ikSelected] then ImageIndex:= 0 
     else if Kind = ikOverlay then begin 
     Data:= Sender.GetNodeData(Node); 
     if Data^.isLocked then 
      ImageIndex:= 1+16; 
     end; 
    end; 
    end; 
    ImageList:= Self.ImageList1; //Or use a separate imagelist for overlays. 
end; 

雖然圖像索引覆蓋< 15沒有得到考慮VTV不會從索引中減去任何數字,所以你不得不把一個至少15張圖片在圖片列表中。

現在,它的工作原理:

enter image description here

+0

優秀的答案,它的作品像一個魅力:)非常感謝你 – fantaghirocco

4

你需要指定通過TImageList.Overlay疊加的影像,如:

procedure TForm1.FormCreate(Sender: TObject); 
begin 
    ImageList1.Overlay(1 , 0); // 1 = "Lock" index; 0=overlay index 

    // second overlay - just for example: 
    ImageList1.Overlay(7 , 1); // 7 = "Shortcut" index; 1=overlay index 
end; 

OnGetImageIndex你需要使用的ImageList 覆蓋指數, NOT image-index例如:

... 
if Kind = ikOverlay then begin 
    if Data^.isLocked then 
    ImageIndex := 0 
    else 
    if Data^.isShortcut then 
    ImageIndex := 1 
end 
+0

非常感謝你的答案(upvoted):這是我已經嘗試過的解決方案,但它不適用於我的真實用例(它仍然不,我不知道爲什麼),我認爲這是一個錯誤的方法。相反,它適用於我在問題中顯示的測試用例,它是一個簡短而優雅的解決方案。在我看來,我更願意將@ Johan的答案留作接受的答案,因爲它更側重於我提供的代碼。我希望你不介意@fantaghirocco – fantaghirocco

+0

,我相信這是正確的做法。這也是它在所有VT示例中的做法(以及我在應用程序中如何使用它)。您的「測試用例」中是否需要我的代碼至少16張圖像,正如接受的答案所建議的那樣? – kobik