📄 fcdbtreeview.pas
字号:
// if ActiveNodeIndex-GetStartOffset(ActiveDataSet)>=CacheSize then
// SetStartOffset(ActiveDataSet, fcmax(ActiveNodeIndex+1-CacheSize, 0));
end;
if ActiveNodeIndex-GetStartOffset>=CacheSize then
SetStartOffset(ActiveDataSet, fcmax(ActiveNodeIndex+1-CacheSize, 0));
if (ActiveNodeIndex>=0) and (ActiveNodeIndex<=Nodes.Count-1) then
begin
FActiveNode:= TfcDBTreeNode(Nodes[ActiveNodeIndex]);
end
else FActiveNode:= nil;
NewMaxTextWidth:= 0;
for i:= 0 to Nodes.Count-1 do begin
if HorzScrollBar.Visible then
begin
if (i>=CacheSize+1) then break;
end
else if i>=CacheSize then break;
if (i+GetStartOffset>=Nodes.count) then break;
PaintingRow:= i;
Node:= TfcDBTreeNode(Nodes[i+GetStartOffset]);
FPaintCanvas.Font.Assign(Font); { Restore original font }
FPaintCanvas.Pen.Color := FLineColor; //clBtnShadow; { for line drawing }
PrevActiveRecord:= Node.DataLink.ActiveRecord;
try
Node.DataLink.ActiveRecord:= Node.ActiveRecord;
Node.MultiSelected:= FindCurrentMultiSelectIndex(Node.DataLink.DataSet)>=0;
ActiveNode:= ActiveNodeIndex=i+GetStartOffset;
if ActiveNode and not FMultiSelectAttributes.enabled then
begin
if Focused then begin
FPaintCanvas.Brush.Color:= clHighlight;
FPaintCanvas.Font.Color := clHighlightText;
end
else begin
if not (dtvoHideSelection in Options) then
begin
if InactiveFocusColor<>Color then
FPaintCanvas.Brush.Color:= InactiveFocusColor
else
FPaintCanvas.Brush.Color:= clGray;
end
else begin
FPaintCanvas.Brush.Color := Color;
end;
FPaintCanvas.Font.Color:= Font.Color;
end
end
else if FMultiSelectAttributes.enabled then
begin
if Node.MultiSelected then begin
if Focused then begin
FPaintCanvas.Brush.Color:= clHighlight;
FPaintCanvas.Font.Color := clHighlightText;
end
else begin
FPaintCanvas.Brush.Color:= InactiveFocusColor;
FPaintCanvas.Font.Color:= Font.Color;
end
end
else begin
if (Imager<>nil) and ActiveNode then
FPaintCanvas.Brush.Color := clNone
else
FPaintCanvas.Brush.Color := Color;
FPaintCanvas.Font.Color := Font.Color;
end
end
else begin
FPaintCanvas.Brush.Color := Color;
FPaintCanvas.Font.Color := Font.Color;
end;
{ 4/5/99 - Set Node.Hot property }
if dtvoHotTracking in Options then
begin
R:= TextRect(Node, i);
Node.Hot:= (PaintingRow = HotTrackRow) and (sp.x>r.left) and (sp.x<r.right);
end;
DoCalcNodeAttributes(Node);
NewMaxTextWidth:=
fcMax(Canvas.TextWidth(Node.Text) + TextRect(Node, i).Left, NewMaxTextWidth);
FocusRect:= TextRect(Node, i);
if not odd(fcRectHeight(r) div 2) and (FocusRect.Top>0) then
begin
FocusRect.top:= FocusRect.Top - 1;
end
else FocusRect.Bottom:= FocusRect.Bottom + 1;
FocusRect.Left:= FocusRect.Left - 1;
if FPaintCanvas.Brush.Color <> clNone then
begin
if dtvoRowSelect in Options then
begin
if BorderStyle=bsNone then { 5/25/99 }
FocusRect.Right:= FPaintBitmap.Width
else
FocusRect.Right:= FPaintBitmap.Width-4;
if Images <> nil then dec(FocusRect.Left, TImageList(Images).Width);
if UseStateImages(node) then dec(FocusRect.Left, GetStateImageWidth);
if (Images<>nil) and UseStateImages(node) then dec(FocusRect.Left, 1);
if (Images<>nil) or UseStateImages(node) then dec(FocusRect.Left, 2);
end;
if (Node.Selected or
(Node.MultiSelected and FMultiSelectAttributes.enabled)) then
FPaintCanvas.FillRect(FocusRect);
end;
PaintLines(node);
PaintImage(node);
R:= TextRect(Node, i);
SetBkMode(FPaintCanvas.Handle, TRANSPARENT);
try
DefaultDrawing:= True;
if dtvoHotTracking in Options then
begin
R:= TextRect(Node, i);
if Node.Hot then begin
if not node.selected then FPaintCanvas.Font.Color:= clBlue;
FPaintCanvas.Font.Style:= [fsUnderline];
if (fsBold in Font.Style) then
FPaintCanvas.Font.Style:= FPaintCanvas.Font.Style + [fsbold];
end
else if (PaintingRow = HotTrackRow) then
HotTrackRow:= -1;
end;
if odd(fcRectHeight(r) div 2) then R.Top:= R.Top + 1;
R.Left:= R.Left + 1;
DoDrawText(self, Node, r, DefaultDrawing);
if DefaultDrawing then begin
if Assigned(Header) then
begin
r.Left:= r.Left - 2; // Adjust for 1st column
DrawColumnText(Node, r)
end
else begin
FPaintCanvas.DrawText(Node.Text, R, DT_END_ELLIPSIS OR DT_NOPREFIX);
R.Left:= R.Left - 1;
if odd(fcRectHeight(r) div 2) then R.Top:= R.Top - 1;
if ActiveNode and Focused then begin
if (not (dtvoRowSelect in Options)) then
begin
FPaintCanvas.Brush.Color := clBlack;
if FMultiSelectAttributes.enabled and (Imager=nil) then
begin
SetBkColor(FPaintCanvas.Handle, ColorToRGB(Color));
SetTextColor(FPaintCanvas.Handle, ColorToRGB(Font.Color));
end
else begin
SetBkColor(FPaintCanvas.Handle, ColorToRGB(clHighlight));
SetTextColor(FPaintCanvas.Handle, ColorToRGB(clHighlightText));
end;
FPaintCanvas.DrawFocusRect(FocusRect);
end
else begin
if FMultiSelectAttributes.enabled then
begin
FPaintCanvas.DrawFocusRect(FocusRect);
end;
end;
end
end
end
finally
SetBkMode(FPaintCanvas.Handle, OPAQUE);
end;
finally
Node.DataLink.ActiveRecord:= PrevActiveRecord;
end;
end;
// 9/5/01 - Scrolling width should total columns in header
if Header<>nil then
begin
NewMaxTextWidth:= ComputeHeaderWidth;
end;
UpTreeButton.enabled:= (FFirstDataLink<>nil) and (ActiveDataSet<>FFirstDataLink.DataSet);
DownTreeButton.enabled:= (FLastDataLink<>nil) and (ActiveDataSet<>FLastDataLink.DataSet) and
(FActiveNode<>nil) and FActiveNode.hasChildren;
OrigCheckMaxWidth:= CheckMaxWidth;
if (((MaxTextWidth<>NewMaxTextWidth) and (CheckMaxWidth or CheckMaxWidthGrow))
or ResetScroll) and
(dtvoShowHorzScrollBar in Options) then
begin
CheckMaxWidth:= False;
CheckMaxWidthGrow:= False;
if (MaxTextWidth<NewMaxTextWidth) or
((HorzScrollBar.position=0) and OrigCheckMaxWidth) then
begin
MaxTextWidth:= NewMaxTextWidth;
ResetScroll:= False;
with HorzScrollBar do begin
Min:= 0;
Max:= NewMaxTextWidth+3;
InComputeHorzWidthOnly := True;
PageSize:= self.ClientRect.Right - self.ClientRect.Left;
InComputeHorzWidthOnly := False;
GetClientRect; // Updates scrollbars if necessary after PageSize is set
ScrollSize:= Max;
// if PageSize>Max then
// LayoutChanged;
HorzScrollBar.Invalidate;
end
end;
end
else begin
CheckMaxWidth:= False;
CheckMaxWidthGrow:= False;
end;
if FActiveNode<>nil then with FActiveNode.DataLink.DataSet do
begin
FActiveBookmark:= GetBookmark;
if ActiveDataSetChanged then
begin
FreeLastActiveBookmark;
LastActiveBookmark:= FActiveBookmark;
try { 4/25/99 - Catch exception }
Change(FActiveNode);
except
ActiveDataSetChanged:= False;
raise;
end;
ActiveDataSetChanged:= False;
exit;
end;
if (FActiveBookmark<>nil) then
begin
if LastActiveBookmark<>nil then
begin
res:= CompareBookmarks(LastActiveBookmark, FActiveBookmark);
NewNode:= (res<>CMPKeyEql) and (res<>CMPEql);
end
else NewNode:= True;
if NewNode then
begin
FreeLastActiveBookmark;
LastActiveBookmark:= FActiveBookmark;
Change(FActiveNode);
ActiveDataSetChanged:= False;
end
else FreeBookmark(FActiveBookmark);
end
end;
finally
EndPainting;
if HotTrackRow>=0 then
begin
SaveCursor:= Screen.Cursor;
Cursor:= crHandPoint;
end
else if Screen.Cursor<>crArrow then
Cursor:= SaveCursor;
end;
end;
procedure TfcDBCustomTreeView.WMEraseBkgnd(var Message: TWmEraseBkgnd);
begin
if True or SkipErase then begin { 4/31/99 - Always Remove erase to prevent flicker when resizing }
Message.result:= 1;
exit;
end
else inherited;
end;
Procedure TfcDBCustomTreeView.MouseToRow(X, Y: integer; var Row: integer);
begin
row:= -1;
if y<0 then exit;
if y>Height then exit;
row:= y div RowHeight;
end;
function TfcDBCustomTreeView.RowToNode(Row: integer; var Node: TfcDBTreeNode): boolean;
begin
result:= false;
Node:= nil;
if row<0 then exit;
if row> cacheSize-1 then exit;
if GetStartOffset+Row<=Nodes.count-1 then
begin
Node:= Nodes[GetStartOffset + Row];
result:= true;
end
else result:= false;
end;
{function TfcDBCustomTreeView.NodeToIndex(Node: TfcDBTreeNode): integer;
var i: Integer;
begin
result:= -1;
for i:= 0 to Nodes.count-1 do begin
if nodes[i]=node then begin
result:= i;
break;
end
end
end;
}
function TfcDBCustomTreeView.NodeToRow(Node: TfcDBTreeNode; var Row: integer): boolean;
var i: integer;
begin
result:= false;
row:= -1;
for i:= 0 to Nodes.count-1 do begin
if nodes[i]=node then
begin
Row:= i - GetStartOffset;
if Row>=0 then result:= True;
break;
end
end;
end;
procedure TfcDBCustomTreeView.Collapse(Node: TfcDBTreeNode);
var DataLink: TfcTreeDataLink;
begin
if Node=nil then exit;
try
SkipFreeNodes:= True;
DoUserCollapse(Node);
DataLink:= TfcTreeDataLink(FDataLinks[Node.Level]);
ActiveDataSet:= DataLink.DataSet;
if LastVisibleDataSet<>ActiveDataSet then
begin
LastVisibleDataSet := ActiveDataSet;
CheckMaxWidth:= True;
end;
InvalidateClient;
finally
FreeOldNodes;
SkipFreeNodes:= False;
end;
end;
procedure TfcDBCustomTreeView.FreeOldNodes;
var i: integer;
begin
for i:= 0 to OldNodes.count-1 do TfcDBTreeNode(OldNodes[i]).Free;
OldNodes.Clear;
end;
procedure TfcDBCustomTreeView.Expand(Node: TfcDBTreeNode);
var DataLink: TfcTreeDataLink;
begin
if Node=nil then exit;
if ActiveNode<>Node then MoveTo(Node); { 3/9/99 }
try
SkipFreeNodes:= True;
if (Header<>nil) and (displayfields.count<=1) then
begin
displayfields.clear;
displayfields.add('');
displayfields.add('');
end;
DoUs
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -