⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fcdbtreeview.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
//        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 + -