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?的更多相关文章

  1. quick-cocos2d-x游戏开发【3】——display.newSprite创建向导

    游戏嘛.没有图片没有图片可以称为你的游戏,所以,我们看一下使用quick如何创建精灵的方式. quick的api精灵族的创造仍然是非常具体的解释.因此,建立非常easy. display.newSpr ...

  2. icon工具类

    using System; using System.Drawing; using System.Collections; using System.ComponentModel; using Sys ...

  3. [转载]C#中MessageBox.Show用法以及VB.NET中MsgBox用法

    一.C#中MessageBox.Show用法 MessageBox.Show (String) 显示具有指定文本的消息框. 由 .NET Compact Framework 支持. MessageBo ...

  4. [asp.net core] Tag Helpers 简介(转)

    原文地址 https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro What are Tag Helpers? ...

  5. System Error Codes

    很明显,以下的文字来自微软MSDN 链接http://msdn.microsoft.com/en-us/library/windows/desktop/ms681382(v=vs.85).aspx M ...

  6. Python之路【第十四篇】前端补充回顾

    布局和事件 1.布局 首先看下下面的图片: 上面的内容都是居中的,怎么实现这个效果呢,第一种方法是通过float的方式,第二种是通过“div居中的方式” 第一种方式不在复述了,直接看第二种方式: 1. ...

  7. javascript树形菜单简单实例

    参考博客地址:http://chengyoyo2006.blog.163.com/blog/static/8451734820087843950604/ <!DOCTYPE HTML PUBLI ...

  8. 【转】Delphi的消息对话框

    Delphi的消息对话框 输入输出inputBox()函数MessageBox()ShowMessage 对话框是Windows操作系统中程序与用户沟通的一种常见的交互方式,对话框可以向用户提供当前程 ...

  9. openerp学习笔记 context 的应用

    1.在Action中定义,context用于传递搜索条件和分组条件,在搜索视图中默认显示: 示例代码: <record model="ir.actions.act_window&quo ...

随机推荐

  1. Python 生成随机数

    import random x = int(input('Enter a number for x: '))  --随机数最小值y = int(input('Enter a number for y: ...

  2. 【题解】BZOJ 3065: 带插入区间K小值——替罪羊树套线段树

    题目传送门 题解 orz vfk的题解 3065: 带插入区间K小值 系列题解 一 二 三 四 惨 一开始用了一种空间常数很大的方法,每次重构的时候merge两颗线段树,然后无限RE(其实是MLE). ...

  3. java版云笔记(四)

    页面的笔记本加载完成了,接下来就是点击笔记本显示将笔记显示,同时把笔记在右边的编辑器中,同时把编辑后的笔记更新. 注:这个项目的sql文件,需求文档,需要的html文件,jar包都可以去下载,下载地址 ...

  4. CentOS 7.1使用yum安装MySql5.6.24

    http://www.cnblogs.com/yuanfeiblog/p/5276492.html

  5. 详述Linux配置静态IP、设置DNS和主机名(一)

    Linux配置静态IP.设置DNS和主机名首先要找到配置文件,这是在Linux系统下进行工作的必须知道工作方式.后面一步步的跟着这个范例来进行配置相信你最终也会完成Linux配置静态IP.设置DNS和 ...

  6. POJ 3087 Shuffle'm Up (模拟+map)

    题目链接:http://poj.org/problem?id=3087 题目大意:已知两堆牌s1和s2的初始状态, 其牌数均为c,按给定规则能将他们相互交叉组合成一堆牌s12,再将s12的最底下的c块 ...

  7. git配置用户名跟邮箱

    因为我有两个git账号 所以我现在要改变我的默认用户名跟邮件 我就需要去终端设置用户名跟邮箱 具体的命令行就是 设置git的用户名 git config --global user.name &quo ...

  8. python基础(9)--递归、二叉算法、多维数组、正则表达式

    1.递归 在函数内部,可以调其他函数,如果一个函数在内部调用它本身,这个函数就是递归函数.递归算法对解决一大类问题是十分有效的,它往往使算法的描述简洁而且易于裂解 递归算法解决问题的特点: 1)递归是 ...

  9. 借助Visual Studio Code提高基于ActionScript的LayaAir HTML5游戏的调试效率

    借助Visual Studio Code提高基于ActionScript的LayaAir HTML5游戏的调试效率 使用Visual Studio Code(VS Code)调试的优势 借助VS Co ...

  10. loadrunner 分用户日志

    loadrunner 分用户日志 loadrunner在run脚本时,模拟多用户并发场景下,通常需要分别关注每个用户的脚本执行日志,可以按照以下操作进行: 在“Run Load Tests”中选择需要 ...