How to automatically resize TStringGrid row (DefaultRowHei开发者_StackOverflowght) to match the height of the font used? I do something like
Grid.DefaultRowHeight:= Grid.Canvas.TextHeight('X') + 4;
but it is not working. For small fonts, the height of the rows is way too big.
Update:
It seems to be actually a problem with program's logic. If I change the font multiple times, the current height of the row matches the size of the font from previous font change event (it is one step behind).
I use this code to intercept font's size change:
procedure TStrGrid.CMFontChanged(var Message: TMessage);
begin
inherited; // let TControl react first
DefaultRowHeight:= Canvas.TextHeight('ApApM')+ 4;
end;
It acts as if the procedure will be:
begin
DefaultRowHeight:= Canvas.TextHeight('ApApM')+ 4;
inherited;
end;
(like first it changes the height, then it actually sets the correct font size - therefore the height is one step behind)
It has nothing to do with this order: both the inherited CMFontChanged
message handler and the DefaultRowHeight
property setter call invalidate. It is due to the current font setting which is not yet updated:
procedure TStrGrid.CMFontchanged(var Message: TMessage);
begin
Canvas.Font := Font;
DefaultRowHeight := Canvas.TextHeight('Ap') + GridLineWidth + 3;
end;
Explanation:
Invalidate only flags windows to repaint the window (the grid) somewhere in future. That happens certainly after obtaining the text height. As alternative you can call Repaint
prior to the request for the new text height, but that would result in a double repaint, hence setting Canvas.Font
.
When it comes to event ordering related issues then the easiest and quickest solution often was posting yourself a message via PostMessage
(here from your CMFontChanged
handler) and doing the update when receiving the posted message.
This has the advantage that it doesn't interfer with whatever the grids need to do to update its inner state.
精彩评论