Hallo Towmuz,
habe mich jetzt mal etwas länger durch den VST Source geklickt und gedebuggt. Hat erst noch etwas gedauert, bis ich dein Problem richtig nachvollziehen konnte.
Schlussendlich habe ich aber deinen Übeltäter gefunden und kann nur sagen, dass ist as designed. Warum? Kein Ahnung. Eventuell kannst du ja was daraus bauen.
Die von dir gedachte HitInfo macht dir das Problem eher nicht. Der Fehler tritt schon früher auf.
Folgende Methode macht dir einen Strich durch die Rechnung:
Delphi-Quellcode:
function TCustomVirtualStringTree.DoGetNodeWidth(Node: PVirtualNode; Column: TColumnIndex; Canvas: TCanvas =
nil): Integer;
// Returns the text width of the given node in pixels.
// This width is stored in the node's data member to increase access speed.
var
Data: PInteger;
begin
if (Column > NoColumn)
and (vsMultiline
in Node.States)
then /////// HIER IST DEIN PROBLEM
Result := FHeader.Columns[Column].Width
/////// DIE ZURÜCKGEGEBENE TEXTBREITE ENTSPRICHT IMMER DER BREITE DER AKTUELLEN COLUMN
else
begin
if Canvas =
nil then
Canvas := Self.Canvas;
if Column = FHeader.MainColumn
then
begin
// Primary column or no columns.
Data := InternalData(Node);
if Assigned(Data)
then
begin
Result := Data^;
if Result = 0
then
begin
Data^ := CalculateTextWidth(Canvas, Node, Column, Text[Node, Column]);
Result := Data^;
end;
end
else
Result := 0;
end
else
// any other column
Result := CalculateTextWidth(Canvas, Node, Column, Text[Node, Column]);
end;
end;
Die Folge daraus ist, dass in der
Procedure TBaseVirtualTree.DetermineHitPositionLTR(var HitInfo: THitInfo; Offset, Right: Integer; Alignment: TAlignment);
das Flag hiOnItemLabel gesetzt wird:
Delphi-Quellcode:
TextWidth := DoGetNodeWidth(HitInfo.HitNode, HitInfo.HitColumn);
// Check if the text can be aligned at all. This is only possible if there is enough room
// in the remaining text rectangle.
if TextWidth > Right - ImageOffset then
Include(HitInfo.HitPositions, hiOnItemLabel)
else
begin
...
end;
Und in der
function TBaseVirtualTree.DetermineDropMode(const P: TPoint; var HitInfo: THitInfo; var NodeRect: TRect): TDropMode;
wird dann der entsprechende DropMode gesetzt. Bitte die Kommentare hinter den Code Zeilen beachten!
Delphi-Quellcode:
function TBaseVirtualTree.DetermineDropMode(const P: TPoint; var HitInfo: THitInfo; var NodeRect: TRect): TDropMode;
// Determine the DropMode.
var
ImageHit: Boolean;
LabelHit: Boolean;
ItemHit: Boolean;
begin
ImageHit := HitInfo.HitPositions * [hiOnNormalIcon, hiOnStateIcon] <> [];
LabelHit := hiOnItemLabel in HitInfo.HitPositions; /////// Hier wird dann LabelHit auf true gesetzt
ItemHit := ((hiOnItem in HitInfo.HitPositions) and
((toFullRowDrag in FOptions.FMiscOptions) or (toFullRowSelect in FOptions.FSelectionOptions)));
// In report mode only direct hits of the node captions/images in the main column are accepted as hits.
if (toReportMode in FOptions.FMiscOptions) and not (ItemHit or ((LabelHit or ImageHit) and
(HitInfo.HitColumn = FHeader.MainColumn))) then
HitInfo.HitNode := nil;
if Assigned(HitInfo.HitNode) then
begin
if LabelHit or ImageHit or not (toShowDropmark in FOptions.FPaintOptions) then /// Hier springt er dann immer auf DropMode dmOnNode
Result := dmOnNode
else
if ((NodeRect.Top + NodeRect.Bottom) div 2) > P.Y then
Result := dmAbove
else
Result := dmBelow;
end
else
Result := dmNowhere;
end;
Ich hoffe ich konnte dir mit dieser Info weiterhelfen.