How to let TVirtualStringTree to display an icon in disabled state?

How to let TVirtualStringTree to display an icon in disabled state?

I need to display files in a directory to a TVirtualStringTree.

So, I use SHGetFileInfo to get files' icons.

But seems I can only get "normal" icons (Left side on following screen shot).

If so, can TVirtualStringTree draw icons as "disabled"?

Just like you disabled the a node. Please see a screen shot:

UPDATED

There is a similar thread in Soft Gems forum.

I can get the rect of the icon then draw the icon myself.

I'm using TcxImageList and it can draw the "disabled" icon easily.

I firstly assigned a non-exist image index in GetImageIndex event

so I have a room to draw the icon. Then using following code to draw.

procedure TfrmMain.tvSharesAfterItemPaint(Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode; ItemRect: TRect); 
var 
  rImage: TRect; 
  OffsetLeft: Integer; 
begin 
    rImage  := ItemRect; 

    with TVirtualStringTree(Sender) do begin 
      if (toShowRoot in TreeOptions.PaintOptions) then 
        OffsetLeft := Indent * (GetNodeLevel(Node) + 1) 
      else 
        OffsetLeft := Indent * GetNodeLevel(Node); 

      Inc(rImage.Left, Margin + OffsetLeft); 
      Inc(rImage.Top, (NodeHeight[Node] - Images.Height) div 2); 
      rImage.Right  := rImage.Left + Images.Width; 
      rImage.Bottom := rImage.Top + Images.Height; 
    end; 

    // draw the "normal" or "disabled" icon here
    imageList.Draw(TargetCanvas, rImage.left, rImage.Top, ...);
  end; 
end;

No, TVirtualStringTree does not have an explicit DisabledIcon property or any thing similiar.

However, you can achieve your desired result by an appropriate handler for the GetImageIndex event.

In the event handler for this event, determine if the node is disabled or not,

and use this test as a discriminator for computing the image index.

In your imagelist, you will need to have normal versions of glyphs and disabled versions.

VirtualTree will not magically create the disabled versions for you,

however it is a trivial matter to clone a glyph and grey wash it.

Let me know if you need demo code, either for the GetImageIndex event handler, or for grey washing.

 

There's no direct way to draw disabled image state.

I would prefer to create the event for custom drawing of the images

(now I've suggested this as a new featurefor virtual tree view, due to this lack).

Here is the example with interposed class for virtual string tree.

For custom drawing of grayscale images, it uses the code from this post.

Surely, it's not a solution for permanent use, you would have to keep the PaintImage method code

synchronized with the actual code since the method is completely overriden.

Parameter count of the OnCustomDrawImage event points to that parameters deserve to wrap to some structure,

but it's just a showcase how would it look like.

This new event is fired twice;

first time for image draw (the DrawOverlay is False) and

second time for overlay (the DrawOverlay parameter is True):

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, DateUtils, StdCtrls, VirtualTrees, ImgList, CommCtrl;

type
  TCustomDrawImageEvent = procedure(Sender: TBaseVirtualTree; Node: PVirtualNode;
    ImageList: TCustomImageList; ImageIndex: Integer; TargetCanvas: TCanvas;
    X, Y: Integer; Style: Cardinal; DrawEnabled: Boolean; DrawOverlay: Boolean;
    var CustomDraw: Boolean) of object;
TVirtualStringTree
= class(VirtualTrees.TVirtualStringTree) private FOnCustomDrawImage: TCustomDrawImageEvent; protected function DoCustomDrawImage(Node: PVirtualNode; ImageList: TCustomImageList; ImageIndex: Integer; TargetCanvas: TCanvas; X, Y: Integer; Style: Cardinal; DrawEnabled: Boolean; DrawOverlay: Boolean): Boolean; virtual; procedure PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean); override; published property OnCustomDrawImage: TCustomDrawImageEvent read FOnCustomDrawImage write FOnCustomDrawImage; end; type TForm1 = class(TForm) VirtualStringTree1: TVirtualStringTree; ImageList1: TImageList; procedure FormCreate(Sender: TObject); procedure VirtualStringTree1GetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer); private procedure VirtualTreeCustomDrawImage(Sender: TBaseVirtualTree; Node: PVirtualNode; ImageList: TCustomImageList; ImageIndex: Integer; TargetCanvas: TCanvas; X, Y: Integer; Style: Cardinal; DrawEnabled: Boolean; DrawOverlay: Boolean; var CustomDraw: Boolean); public { Public declarations } end; var Form1: TForm1; implementation {$R *.dfm} { TVirtualStringTree } type TCustomImageListCast = class(TCustomImageList); function TVirtualStringTree.DoCustomDrawImage(Node: PVirtualNode; ImageList: TCustomImageList; ImageIndex: Integer; TargetCanvas: TCanvas; X, Y: Integer; Style: Cardinal; DrawEnabled: Boolean; DrawOverlay: Boolean): Boolean; begin Result := False; if Assigned(FOnCustomDrawImage) then FOnCustomDrawImage(Self, Node, ImageList, ImageIndex, TargetCanvas, X, Y, Style, DrawEnabled, DrawOverlay, Result); end; procedure TVirtualStringTree.PaintImage(var PaintInfo: TVTPaintInfo; ImageInfoIndex: TVTImageInfoIndex; DoOverlay: Boolean); var CutNode: Boolean; ExtraStyle: Cardinal; DrawEnabled: Boolean; PaintFocused: Boolean; const Style: array[TImageType] of Cardinal = (0, ILD_MASK); begin with PaintInfo do begin CutNode := (vsCutOrCopy in Node.States) and (tsCutPending in TreeStates); PaintFocused := Focused or (toGhostedIfUnfocused in TreeOptions.PaintOptions); if DoOverlay then GetImageIndex(PaintInfo, ikOverlay, iiOverlay, Images) else PaintInfo.ImageInfo[iiOverlay].Index := -1; DrawEnabled := not (vsDisabled in Node.States) and Enabled; with ImageInfo[ImageInfoIndex] do begin if (vsSelected in Node.States) and not (Ghosted or CutNode) then begin if PaintFocused or (toPopupMode in TreeOptions.PaintOptions) then Images.BlendColor := Colors.FocusedSelectionColor else Images.BlendColor := Colors.UnfocusedSelectionColor; end else Images.BlendColor := Color; if (ImageInfo[iiOverlay].Index > -1) and (ImageInfo[iiOverlay].Index < 15) then ExtraStyle := ILD_TRANSPARENT or ILD_OVERLAYMASK and IndexToOverlayMask(ImageInfo[iiOverlay].Index + 1) else ExtraStyle := ILD_TRANSPARENT; if (toUseBlendedImages in TreeOptions.PaintOptions) and PaintFocused and (Ghosted or ((vsSelected in Node.States) and not (toFullRowSelect in TreeOptions.SelectionOptions) and not (toGridExtensions in TreeOptions.MiscOptions)) or CutNode) then ExtraStyle := ExtraStyle or ILD_BLEND50; if (vsSelected in Node.States) and not Ghosted then Images.BlendColor := clDefault; // in this modified part of code, the new event OnCustomDrawImage // is fired once before the image is actually drawn and once when // the overlay is to be drawn; when you keep its CustomDraw param // in False value (what is, by default), the default drawing will // be done otherwise you need to take care of drawing by yourself // draw image default way when the CustomDraw parameter of the new // OnCustomDrawImage event remains False (what is, by default) if not DoCustomDrawImage(Node, Images, Index, Canvas, XPos, YPos, Style[Images.ImageType] or ExtraStyle, DrawEnabled, False) then TCustomImageListCast(Images).DoDraw(Index, Canvas, XPos, YPos, Style[Images.ImageType] or ExtraStyle, DrawEnabled); // draw overlay default way when the CustomDraw parameter of the new // OnCustomDrawImage event remains False (what is, by default) if PaintInfo.ImageInfo[iiOverlay].Index >= 15 then begin if not DoCustomDrawImage(Node, ImageInfo[iiOverlay].Images, ImageInfo[iiOverlay].Index, Canvas, XPos, YPos, Style[ImageInfo[iiOverlay].Images.ImageType] or ExtraStyle, DrawEnabled, True) then TCustomImageListCast(ImageInfo[iiOverlay].Images).DoDraw( ImageInfo[iiOverlay].Index, Canvas, XPos, YPos, Style[ImageInfo[iiOverlay].Images.ImageType] or ExtraStyle, DrawEnabled); end; end; end; end; { TForm1 } procedure TForm1.FormCreate(Sender: TObject); begin VirtualStringTree1.OnCustomDrawImage := VirtualTreeCustomDrawImage; end; type TImageListDrawParams = record cbSize: DWORD; himl: HIMAGELIST; i: Integer; hdcDst: HDC; x: Integer; y: Integer; cx: Integer; cy: Integer; xBitmap: Integer; yBitmap: Integer; rgbBk: COLORREF; rgbFg: COLORREF; fStyle: UINT; dwRop: DWORD; fState: DWORD; Frame: DWORD; crEffect: COLORREF; end; procedure DrawDisabledImage(DC: HDC; ImageList: TCustomImageList; Index, X, Y: Integer); var Options: TImageListDrawParams; begin FillChar(Options, SizeOf(Options), 0); Options.cbSize := SizeOf(Options); Options.himl := ImageList.Handle; Options.i := Index; Options.hdcDst := DC; Options.x := X; Options.y := Y; Options.fState := ILS_SATURATE; ImageList_DrawIndirect(@Options); end; procedure TForm1.VirtualStringTree1GetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer); begin ImageIndex := 0; end; procedure TForm1.VirtualTreeCustomDrawImage(Sender: TBaseVirtualTree; Node: PVirtualNode; ImageList: TCustomImageList; ImageIndex: Integer; TargetCanvas: TCanvas; X, Y: Integer; Style: Cardinal; DrawEnabled: Boolean; DrawOverlay: Boolean; var CustomDraw: Boolean); begin CustomDraw := True; if not DrawOverlay then DrawDisabledImage(TargetCanvas.Handle, ImageList, ImageIndex, X, Y); end; end.

 And the result (I have to say it would be fine to blend it yet):

 

转载于:https://www.cnblogs.com/shangdawei/p/4042294.html

上传容量有限,含packge和source V5.5.2: (10 Nov 2014) * Various improvements regarding code style * Implemented #471: Added emVisibleDueToExpansion and emSelected to TVTExportMode * Fixed issue #488: XE7 packages should depend on one another and use suffix 21 * Fixed issue #462: Undo r636, make VirtualTreesD require VirtualTreesR again * Fixed issue #489 XE2 compiler switch error V5.5.1: (13 Oct 2014) * Fixed issue #479: The style hooks for the VCL styles are now registered for TVirtualStringTree and TVirtualDrawTree instead of TBaseVirtualTree, which makes it easier to use own style hooks in derived classes. * Partial fix for issue #478: The standard VCL property StyleElemets (public in TControl in RAD Studio XE3 and higher) is now supported and published for TVirtualStringTree and TVirtualDrawTree (XE3 and higher). This means you can define if the font and the backgrounbd color is taken from the VCL style or the control's properties. Leaving out seBorder is not yet working well, more work will be necessary. * Fixed issue #473: Return type of GetUtilityImages should be TCustomImageList * Fix for issue #470: VCL Styles and sorting failure * Added missing inherited to CMMouseEnter() * Fixed issue #468: Redundant code in CreateSystemImageSet() * Fixed issue #482: AutoScale() could cause exception during form load. * Added fix for #466: No parent window if column created in constructor * Fixed issue #446: ScrollIntoView does not work properly after applying patch from issue #339 * Improvements for toAlwaysSelectNode option: Selection of next sibling has been improved in case the currently selected node is being removed. * Added missing begin/end-block in MeasureItemHeight() * Improved fix for issue #438: Now correctly initializing member of property TVTColors.UnfocusedColor * Improved fix for issue #447: DoMeasureItem() was called for Node instead of Child. * Minor improvement in appearance of border lines in HTML export. * Fixed issue #480: Warning when compiling Delphi XE2 packages * Fixed #472: Redundant conditions in TVclStyleScrollBarsHook.WMMouseMove * Fixed #476: Simplify TVTDragImage.WillMove() * Fixed issue #485: unit VirtualTrees does not compile with {$TYPEDADDRESS ON}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值