Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.8k views
in Technique[技术] by (71.8m points)

delphi - VirtualTreeView with UseExplorerThemes

I just discovered that using the Option toUseExplorerTheme allows to produce a nice selection rectangle for a VirtualStringTree. However, if the Option toGridExtensions is set and there are several columns in the tree, the vertical border of the selection is not drawn for the inner cells, and the rounded corners are missing as well. Only the outermost edges and corners of the left- and right-most columns are drawn correctly. It looks as if the selection rectangle is drawn between the outermost columns and the background of the non-selected columns is just drawn over the selection rectangle.

Turning off the toGridExtensions results in a correct selection rectangle, but I prefer to have it on because a cell can only be selected by clicking on the text in the standard mode (not by clicking on the empty space next to the text).

The issue occurs with Delphi 7 and XE2, and probably also with other versions.

To reproduce add a TVirtualStringTree to a form, show the header, add several columns to the header, and activate the options toGridExtensions (MiscOptions), toUseExplorerTheme (PaintOptions), toExtendedFocus (SelectionOptions), run the program and click on any cell.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

In my view it's a bug, because who would like to have a selection like this:

enter image description here

To fix it in a Virtual Tree View code (in my case v.5.1.4), go to the TBaseVirtualTree.PrepareCell method (in my case line 25802) and check this nested procedure code (comments are mine):

procedure DrawBackground(State: Integer);
begin
  // here the RowRect represents the row rectangle and InnerRect the cell
  // rectangle, so there should be rather, if the toGridExtensions is NOT
  // in options set or the toFullRowSelect is, then the selection will be
  // drawn in the RowRect, otherwise in the InnerRect rectangle
  if (toGridExtensions in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions) then
    DrawThemeBackground(Theme, PaintInfo.Canvas.Handle, TVP_TREEITEM, State, RowRect, nil)
  else
    DrawThemeBackground(Theme, PaintInfo.Canvas.Handle, TVP_TREEITEM, State, InnerRect, nil);
end;

To fix this issue modify the code this way:

procedure DrawBackground(State: Integer);
begin
  // if the full row selection is disabled or toGridExtensions is in the MiscOptions, draw the selection
  // into the InnerRect, otherwise into the RowRect
  if not (toFullRowSelect in FOptions.FSelectionOptions) or (toGridExtensions in FOptions.FMiscOptions) then
    DrawThemeBackground(Theme, PaintInfo.Canvas.Handle, TVP_TREEITEM, State, InnerRect, nil)
  else
    DrawThemeBackground(Theme, PaintInfo.Canvas.Handle, TVP_TREEITEM, State, RowRect, nil);
end;

And you'll get a selection like this:

enter image description here

The same applies also to the next DrawThemedFocusRect nested procedure.

I have reported this problem as Issue 376, which is fixed in revision r587.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to WuJiGu Developer Q&A Community for programmer and developer-Open, Learning and Share
...