Virtual StringTree: как определить, полностью ли отображается текст узла? - PullRequest
3 голосов
/ 20 января 2010

Когда TVirtualStreeTree.HintMode = hmTooltip, текст узла становится текстом подсказки, когда мышь наводится на узел и столбец, где текст узла отображается не полностью. Но я должен установить HintMode = hmHint, чтобы в четном обработчике я мог предоставлять различный текст подсказки в зависимости от положения текущего курсора мыши, и в этом HintMode текст подсказки не генерируется автоматически.

Мой вопрос заключается в том, как узнать, отображается ли текст узла полностью или нет, чтобы я знал, должен ли я указывать текст узла или пустую строку в качестве текста подсказки?
Спасибо.

Ответы [ 2 ]

2 голосов
/ 20 января 2010

Вы можете позвонить TBaseVirtualTree.GetDisplayRect, чтобы определить текстовые границы узла. В зависимости от параметра Unclipped он даст вам полную или фактическую ширину текста. TextOnly должно быть установлено на True:

function IsTreeTextClipped(Tree: TBaseVirtualTree; Node: PVirtualNode; Column: TColumnIndex): Boolean;
var
  FullRect, ClippedRect: TRect;
begin
  FullRect := Tree.GetDisplayRect(Node, Column, True, True);
  ClippedRect := Tree.GetDisplayRect(Node, Column, True, False);
  Result := (ClippedRect.Right - ClippedRect.Left) < (FullRect.Right - FullRect.Left);
end;

Обратите внимание, что функция будет неявно инициализировать узел, если он еще не был инициализирован.

0 голосов
/ 20 января 2010

Вы можете использовать то, что использует сам элемент управления деревом.Вот выдержка из обработчика сообщений cm_HintShow для однострочных узлов, когда действует режим hmTooltip.

NodeRect := GetDisplayRect(HitInfo.HitNode, HitInfo.HitColumn, True, True, True);
BottomRightCellContentMargin := DoGetCellContentMargin(HitInfo.HitNode, HitInfo.HitColumn
, ccmtBottomRightOnly);

ShowOwnHint := (HitInfo.HitColumn > InvalidColumn) and PtInRect(NodeRect, CursorPos) and
  (CursorPos.X <= ColRight) and (CursorPos.X >= ColLeft) and
  (
    // Show hint also if the node text is partially out of the client area.
    // "ColRight - 1", since the right column border is not part of this cell.
    ( (NodeRect.Right + BottomRightCellContentMargin.X) > Min(ColRight - 1, ClientWidth) ) or
    (NodeRect.Left < Max(ColLeft, 0)) or
    ( (NodeRect.Bottom + BottomRightCellContentMargin.Y) > ClientHeight ) or
    (NodeRect.Top < 0)
  );

Если ShowOwnHint true, то вы должны вернуть текст узла в качестве подсказкитекст.В противном случае оставьте текст подсказки пустым.

Основным препятствием для использования этого кода является то, что DoGetCellContentMargin защищен, поэтому вы не можете вызвать его напрямую.Вы можете либо отредактировать источник, чтобы сделать его общедоступным, либо дублировать его функциональность в своей собственной функции;если вы не обрабатываете событие OnBeforeCellPaint, то оно всегда возвращает (0, 0) в любом случае.

Данные HitInfo поступают из вызова GetHitTestInfoAt.

...