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) + )
else
OffsetLeft := Indent * GetNodeLevel(Node); Inc(rImage.Left, Margin + OffsetLeft);
Inc(rImage.Top, (NodeHeight[Node] - Images.Height) div );
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 = (, 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 := -;
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 > -) and (ImageInfo[iiOverlay].Index < ) then
ExtraStyle := ILD_TRANSPARENT or ILD_OVERLAYMASK and
IndexToOverlayMask(ImageInfo[iiOverlay].Index + )
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 >= 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), );
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 := ;
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):

How to let TVirtualStringTree to display an icon in disabled state?的更多相关文章
- quick-cocos2d-x游戏开发【3】——display.newSprite创建向导
游戏嘛.没有图片没有图片可以称为你的游戏,所以,我们看一下使用quick如何创建精灵的方式. quick的api精灵族的创造仍然是非常具体的解释.因此,建立非常easy. display.newSpr ...
- icon工具类
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using Sys ...
- [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法
一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...
- [asp.net core] Tag Helpers 简介(转)
原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro What are Tag Helpers? ...
- System Error Codes
很明显,以下的文字来自微软MSDN 链接http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx M ...
- Python之路【第十四篇】前端补充回顾
布局和事件 1.布局 首先看下下面的图片: 上面的内容都是居中的,怎么实现这个效果呢,第一种方法是通过float的方式,第二种是通过“div居中的方式” 第一种方式不在复述了,直接看第二种方式: 1. ...
- javascript树形菜单简单实例
参考博客地址:http://chengyoyo2006.blog.163.com/blog/static/8451734820087843950604/ <!DOCTYPE HTML PUBLI ...
- 【转】Delphi的消息对话框
Delphi的消息对话框 输入输出inputBox()函数MessageBox()ShowMessage 对话框是Windows操作系统中程序与用户沟通的一种常见的交互方式,对话框可以向用户提供当前程 ...
- openerp学习笔记 context 的应用
1.在Action中定义,context用于传递搜索条件和分组条件,在搜索视图中默认显示: 示例代码: <record model="ir.actions.act_window&quo ...
随机推荐
- JVM内存分配及GC简述
在阐述JVM的内存区域之前,先来看下计算机的存储单位.从小到大依次为Bit,Byte,KB,MB,GB,TB.相邻的单位相差2的10次方. 计算机运行中的存储元件主要分为寄存器(位于CPU)和内存,寄 ...
- system()函数
windows下system () 函数详解 windows操作系统下system () 函数详解(主要是在C语言中的应用) 函数名: system 功 能: 发出一个DOS命令 用 法: i ...
- python基础(6)---set、collections介绍
1.set(集合) set和dict类似,也是一组key的集合,但不存储value.由于key不能重复,所以,在set中,没有重复的key. 集合和我们数学中集合的概念是一样的,也有交集.并集.差集. ...
- springcloud 显示服务详细健康信息
pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="htt ...
- python脚本传入参数--精讲(getopt模块)
1.最常用的sys.argv[],这个不多谈 2.形如 dahu@dahu-OptiPlex-:~/json_folder$ python sub1.py -abb -oaaa --output=ou ...
- css 画的动画表情
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- python中的计时器:timeit
python中的计时器:timeit timeit 通常在一段程序的前后都用上time.time(),然后进行相减就可以得到一段程序的运行时间,不过python提供了更强大的计时库:timeit #导 ...
- mysql正则查询 模糊查询
-- ==============正则查询================ /* SQL默认是忽略大小写的 正则模式使用REGEXP和NOT REGEXP操作符(或RLIKE和NOT RLIKE,它们 ...
- post登录趴一趴百度贴吧美女
本次爬取的贴吧是百度的美女吧,给广大男同胞们一些激励 在爬取之前需要在浏览器先登录百度贴吧的帐号,各位也可以在代码中使用post提交或者加入cookie 爬行地址:http://tieba.baidu ...
- FastReport.Net使用:[11]公共对象属性介绍
公共对象属性介绍 1.Left(左),Top(上),Height(高度),Width(宽度) Left和Top,用来控制对象的位置:Height和Width用来控制对象的大小. 2.Anchor(基准 ...