2016-04-28 2 views
3

Я хотел бы отобразить изображение из ImageList1 в компоненте vtTest в качестве наложения.Наложенные изображения с TVirtualStringTree.OnGetImageIndex

Я нашел много ресурсов в Интернете и здесь, в SO - как 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 

СОВЕТЫ:

  • VirtualTrees версия 5.2.1 на Delphi xe4
  • Линия ImageIndex := 1; выполняется в функции vtTestGetImageIndex - отладчик останавливается там, когда точка останова установлена ​​
  • Изображения по индексу 0 и 1 существуют в TImageList
  • я уже в состоянии использовать различные изображения для различных видов узлов без наложения
+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 в ImageList, из которого накладываемого получает выбранный будет ноль, см:

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 не вычитает ни одного номера из индекса, поэтому вы вынуждены t не менее 15 изображений в imagelist.

Сейчас он работает:

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 индекс изображения, например:

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

Большое спасибо за ваш ответ (upvoted): это решение, которое я уже пробовал, но он не работал для моего реального случая использования (он все еще нет, и я не знаю, почему), и я предположил, что это неправильный подход. Напротив, он отлично работает для тестового случая, который я показал в своем вопросе, и это короткое и изящное решение. Я предпочитаю оставить ответ @ Johan в качестве принятого, потому что он больше сосредоточен на коде, который я предоставил, на мой взгляд. Надеюсь, вы не против – fantaghirocco

+0

@fantaghirocco, я считаю, что это правильный подход. это также то, как это делается во всех примерах VT (а также как я использую его в нашем приложении). Вам нужно как минимум 16 изображений с моим кодом в вашем «тестовом случае», как это было предложено принятым ответом? – kobik

Смежные вопросы