Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Method TVirtualTreeColumn.GetCaptionWidth handles owner-drawn caption badly #1250

Open
hermannoffen opened this issue Apr 9, 2024 · 5 comments
Labels
Repro Steps Missing A smple project is needed to reprodcue and analyze the issue. See our guidelines for opening issues!

Comments

@hermannoffen
Copy link
Contributor

Since #925 was merged, header captions may be considered optionally in TBaseVirtualTree.GetMaxColumnWidth.
Unfortunately, this is mostly insufficient for owner-drawn headers, as TVirtualTreeColumn.GetCaptionWidth calculates the text's total width by just calling GetTextExtentPoint32W(…). Since, in my case, FText does not contain plain text, but a HTML-formatted string, the result is way too big.
TBaseVirtualTree.DoHeaderDrawQueryElements is called before, to update local variable PaintInfo, as it seems. Apparently, the code was just copy-pasted selectively from TVirtualTreeColumns.PaintHeader. 😞

@joachimmarder
Copy link
Contributor

Please respect our guidelines on the project homepage for submitting bugs. Please include your version of Virtual TreeView and attach a sample compiling project as ZIP to your report. If you already have a solution, please supply a patch file.

Since #925 was merged

Well, that was 5 years ago. Maybe the original contributor @lyynxx can comment on this?

@hermannoffen
Copy link
Contributor Author

hermannoffen commented Apr 10, 2024

Pardon, I've been in a bit of a hurry, yesterday. The issue is easy reproducible in HeaderCustomDrawDemo's tab of Advanced.exe demo of current master (c3ddc11), as well as in the merge commit back then (2d4f75), when hoAutoResizeInclCaption is included in Header.Options property; see Virtual-TreeView-reproduce-issue-#1250.patch. Thus, the issue applies to all versions since 7.3.

This applied, if one holds ctrl-key and double-clicks the column headers' edges, the columns are resized badly:

  • The first (index 0) and second (index 1) column each become way to wide, as the captions' widths aren't measured properly.
  • The third (index 2) column does not apply a width for the caption's text, which is to be expected here – I guess – because there is no text set at all. Nonetheless, it would be nice to get control over the width being applied or not, e.g. by some event.

Unfortunately, I cannot provide a fix right now. I thought about delegating the text measurement to the already existing method TCustomVirtualStringTree.CalculateTextWidth, but did not find a proper way to call it from class TVirtualTreeColumns without casting its TBaseVirtualTreeView reference to TCustomVirtualStringTree.

@joachimmarder
Copy link
Contributor

joachimmarder commented Apr 11, 2024

The first (index 0) and second (index 1) column each become way to wide, as the captions' widths aren't measured properly

For some reason I could not yet figure out, in TVirtualTreeColumn.GetCaptionWidth() the canvas' font size was very large. I need to debug why this is the case here. Based on the font's size, the width is calculated correctly.

it would be nice to get control over the width being applied or not, e.g. by some event.

Have you tried the OnAfterGetMaxColumnWidth event?

@hermannoffen
Copy link
Contributor Author

The first (index 0) and second (index 1) column each become way to wide, as the captions' widths aren't measured properly

For some reason I could not yet figure out the canvas' font size was very large. I need to debug why this is the case here. Based on the font's size, the width is calculated correctly.

Yes. The values width is correct, based on the wrong value. Although, the way it's calculated duplicates a more sophisticated logic, elsewhere (see TVirtualTreeColumns.PaintHeader). This is quite uncommon for this project's code. Thus, the value may be equal in value, but logically it's not guaranteed to be the same.

it would be nice to get control over the width being applied or not, e.g. by some event.

Have you tried the OnAfterGetMaxColumnWidth event?

I am aware of the OnAfterGetMaxColumnWidth event. That's what I use ever since to include the column's header's width for the column. If TVirtualTreeColumn.GetCaptionWidth could call TCustomVirtualStringTree.CalculateTextWidth, then the events OnMeasureText… of method TCustomVirtualStringTree.DoTextMeasuring could be used to customize the calculation.

@joachimmarder
Copy link
Contributor

The values width is correct, based on the wrong value.

I found the reason why the font size is so large: It was modified that way in THeaderOwnerDrawForm.HeaderCustomDrawTreeAdvancedHeaderDraw() to draw the world map, but the original font was not restored. This is now changed and the columns now resize OK in your repro steps above.

If TVirtualTreeColumn.GetCaptionWidth could call TCustomVirtualStringTree.CalculateTextWidth

Well it couldn't as, it exists only in the derived class for the Virtual String Tree. Also, the events you mentioned are for painting the client area of the virtual string tree, they can't recognize if some text is from the client area or the header, which by the way has its own Font property. This would be a breaking change, and I don't think it is a good idea to mix up the tree header and the derived class TCustomVirtualStringTree.

@joachimmarder joachimmarder added the Repro Steps Missing A smple project is needed to reprodcue and analyze the issue. See our guidelines for opening issues! label Apr 14, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Repro Steps Missing A smple project is needed to reprodcue and analyze the issue. See our guidelines for opening issues!
Projects
None yet
Development

No branches or pull requests

2 participants