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

📄 fcdbtreeview.pas

📁 一套及时通讯的原码
💻 PAS
📖 第 1 页 / 共 5 页
字号:
    tempDS, curDS: TDataSource;
    index, tempIndex: integer;
    token: string;
    OldLinks: TList;

   { Retrieve TDataSource with the name of the datasource }
   Function DataSourceFromToken(DataSourceName: string): TDataSource;
   var Component: TComponent;
       token1, token2: string;
   begin
      result:= nil;
      if (pos('.', DataSourceName)<=0) and
         (pos('->', DataSourceName)<=0) then
      begin
         Component:= GetParentForm(self).FindComponent(DataSourceName);
      end
      else begin
         token1:= fcGetToken(DataSourceName, '.', 0);
         token2:= fcGetToken(DataSourceName, '.', 1);
         Component:= FindGlobalComponent(token1);
         if Component<>nil then
            Component:= Component.FindComponent(token2);

         if Component=nil then { 7/25/99 - Builder notation }
         begin
           token1:= fcGetToken(DataSourceName, '->', 0);
           token2:= fcGetToken(DataSourceName, '->', 1);
           Component:= FindGlobalComponent(token1);
           if Component<>nil then
              Component:= Component.FindComponent(token2);
         end
      end;
      if Component is TDataSource then
         result:= TDataSource(Component);
   end;

   Function GetDataLink(curDS: TDataSource): TfcTreeDataLink;
   var i: integer;
   begin
      for i:= 0 to OldLinks.count-1 do begin
         if TfcTreeDataLink(OldLinks[i]).DataSource = curDS then
         begin
             result:= OldLinks[i];
             OldLinks.Delete(i);  { Remove from list so that its not destroyed later }
             exit;
         end
      end;
      result:= TfcTreeDataLink.Create(Self);
   end;


begin
   if csDestroying in ComponentState then exit;

   OldLinks:= TList.Create;
   try
     for i:= 0 to FDataLinks.count-1 do begin
        if (FDataLinks[i]<>FFirstDataLink) and
           (FDataLinks[i]<>FLastDataLink) then
         OldLinks.Add(FDataLinks[i]);
     end;

     if ((LastDS=nil) or (LastDS.DataSet=nil)) and (DataSources='') then
     begin
        { Clearing datasource }
        if FDataLinks.Count>0 then invalidate;
        FDataLinks.Clear;
        exit;
     end;

     FDataLinks.Clear;

     if FFirstDataLink.DataSet<>nil then
     begin
        FDataLinks.Add(FFirstDataLink);
        if FFirstDataLink.Active then // 2/23/01 - Make sure active so that recordcount gets set
           FFirstDataLink.BufferCount := CacheSize;
        index:= 1;
     end
     else index:= 0;

     if FFirstDataLink.Dataset<>FLastDataLink.DataSet then
     begin
        FDataLinks.Add(FLastDataLink);
        if FFirstDataLink.Active then  // Make sure active so that recordcount gets set
           FLastDataLink.BufferCount := CacheSize;
     end;

     if (DataSources='') then begin
       { 3/2/99 - Special case of only one level so don't add any more datalinks}
       if FFirstDataLink.Dataset=FLastDataLink.DataSet then exit;

       try
          curDS:= LastDS;
          repeat
             tempDS:= fcGetControlMasterSource(curDS.dataset);
             if tempDS=nil then
                tempDS:= fcGetControlDataSource(curDS.dataset);
             curDS:= tempDS;

             if (curDS<>FirstDS) and (curDS<>nil) then
             begin
                FDataLink:= GetDataLink(curDS);
                FDataLink.BufferCount := CacheSize;
                FDataLink.DataSource := curDS;
                FDataLinks.Insert(index, FDataLink);
             end
          until (curDS=FirstDS) or (curDS=nil);
       finally
       end
     end
     else begin
        HaveBadLink:= False;

        tempIndex:= 0;
        repeat
           token:= fcGetToken(DataSources, ';', tempIndex);
           curDS:= DataSourceFromToken(token);
           if (curDS=nil) and
              ((pos('.', token)>0) or (pos('->', token)>0)) then { 7/25/99 - Suppport Builder notation }
                 HaveBadLink:= True;

           if (curDS<>nil) and (curDS<>FirstDS) and (curDS<>LastDS) then
           begin
              FDataLink:= TfcTreeDataLink.Create(Self);
              FDataLink.BufferCount := CacheSize;
              FDataLink.DataSource := curDS;
              FDataLinks.Insert(index, FDataLink);
              inc(index);
           end;
           inc(tempIndex);
        until token = '';
     end;
  finally
     for i:= 0 to OldLinks.Count-1 do TfcTreeDataLink(OldLinks[i]).Free;
     OldLinks.Free;
  end
end;

procedure TfcDBCustomTreeView.SetDataSource(Value: TDataSource);
begin
  FreeLastActiveBookmark;  // Free LastActiveBookmark when datasource changes

  FFirstDataLink.Datasource:= Value;

  RefreshDataLinks(Value, FLastDataLink.DataSource);

  { Initialize other data links }
  if (Value<>nil) and (Value.DataSet<>nil) then
     LinkActive(Value.DataSet, Value.Dataset.Active);
end;

procedure TfcDBCustomTreeView.SetDataSources(Value: String);
begin
  if Value<>FDataSourcesMiddle then
  begin
     FreeLastActiveBookmark;  // Free LastActiveBookmark when datasource changes

     FDataSourcesMiddle:= Value;
     RefreshDataLinks(FFirstDataLink.DataSource, FLastDataLink.DataSource);
     if not HaveValidDataLinks then invalidate;
  end
end;

procedure TfcDBCustomTreeView.SetLastDataSource(Value: TDataSource);
begin
  FreeLastActiveBookmark;  // Free LastActiveBookmark when datasource changes

  FLastDataLink.Datasource:= Value;
  RefreshDataLinks(FFirstDataLink.DataSource, Value);

  { Initialize other data links }
  if (Value<>nil) and (Value.DataSet<>nil) then
     LinkActive(Value.DataSet, Value.Dataset.Active);
end;

procedure TfcDBCustomTreeView.LinkActive(DataSet: TDataSet; Value: Boolean);
begin
  SaveIfFirstRecordBookmark(DataSet);
  if (FDataLinks.count>0) and (Dataset = TfcTreeDataLink(FDataLinks[0]).DataSet) then begin
     FreeRootBookmark;
     IsRootDataSetMoved;
  end;
  LayoutChanged;
  UpdateScrollBar;
end;

{ Return true if master node has changed }
{ This code is not implemented yet }
Function TfcDBCustomTreeView.InMasterChanging(DataSet: TDataSet): boolean;
begin
    if DataSet = DatasourceFirst.dataset then result:= False
    else result:= True;
end;

Function TfcDBCustomTreeView.IsRootDataSetMoved: boolean;
var TempRootDataSetBookmark: TBookmark;
   res: CmpBkmkRslt;
   RootDataSet: TDataSet;
begin
   result:= False;
   if FDataLinks.count<=0 then exit;
   RootDataSet:= TfcTreeDataLink(FDataLinks[0]).DataSet;
   if (RootDataSet=nil) then exit;
   if RootDataSet.state <> dsBrowse then exit;

   TempRootDataSetBookmark:= RootDataSet.GetBookmark;
   if TempRootDataSetBookmark=nil then exit;

   if RootDataSetBookmark=nil then begin
      RootDataSetBookmark:= TempRootDataSetBookmark;
      exit;
   end;

   res:= RootDataSet.CompareBookmarks(RootDataSetBookmark, TempRootDataSetBookmark);
   if (res=CMPKeyEql) or (res=CMPEql) then begin
      RootDataSet.FreeBookmark(TempRootDataSetBookmark);
      exit;
   end;
   result:= True;
   FreeRootBookmark;
   RootDataSetBookmark:= TempRootDataSetBookmark;
end;

procedure TfcDBCustomTreeView.DataChanged(DataSet: TDataSet);
var ChildDataLink: TfcTreeDataLink;
begin
  if FDataLinks.Count=0 then exit;
  
  if Dataset = TfcTreeDataLink(FDataLinks[0]).DataSet then begin
     SaveIfFirstRecordBookmark(DataSet);
     if IsRootDataSetMoved then
        ActiveDataSet:= DataSet;
     UpdateScrollBar;
  end
  else if FScrollWithinLevel then UpdateScrollBar;

  if dataset.state = dsBrowse then
  begin
     ChildDataLink:= GetChildDataLink(Dataset);
     if ChildDataLink<>nil then ResetStartOffsets(ChildDataLink.DataSet);
  end;
//     ResetStartOffsets(DataSet); { 12/23/98 }

  CheckMaxWidthGrow:= True;
  invalidateClient;

end;

Function TfcDBCustomTreeView.GetDataLinkIndex(Dataset: TDataset): integer;
var i:integer;
begin
   result:= -1;
   if DataSet =nil then exit;

   for i:= 0 to FDataLinks.count-1 do begin
      if TfcTreeDataLink(FDataLinks[i]).dataset = DataSet then
      begin
         result:= i;
         break;
      end
   end;
end;

Function TfcDBCustomTreeView.GetDataLink(Dataset: TDataset): TfcTreeDataLink;
var i:integer;
begin
   result:= nil;
   if DataSet =nil then exit;

   for i:= 0 to FDataLinks.count-1 do begin
      if TfcTreeDataLink(FDataLinks[i]).dataset = DataSet then
         result:= TfcTreeDataLink(FDataLinks[i]);
   end;
end;

Function TfcDBCustomTreeView.GetParentDataLink(Dataset: TDataset): TfcTreeDataLink;
var i:integer;
begin
   result:= nil;
   for i:= 0 to FDataLinks.count-1 do begin
      if TfcTreeDataLink(FDataLinks[i]).dataset = DataSet then
      begin
         if i>0 then
            result:= TfcTreeDataLink(FDataLinks[i-1]);
         break;
      end
   end;
end;

Function TfcDBCustomTreeView.GetChildDataLink(Dataset: TDataset): TfcTreeDataLink;
var i:integer;
begin
   result:= nil;
   for i:= 0 to FDataLinks.count-1 do begin
      if TfcTreeDataLink(FDataLinks[i]).dataset = DataSet then
      begin
         if (i+1)<=FDataLinks.count-1 then
            result:= TfcTreeDataLink(FDataLinks[i+1]);
         break;
      end
   end;
end;

procedure TfcDBCustomTreeView.Scroll(DataSet: TDataSet; Distance: Integer);
var DataLink: TfcTreeDataLink;
begin
  if not HandleAllocated then Exit;

  if FDataLinks.Count>0 then begin
     if Dataset = TfcTreeDataLink(FDataLinks[0]).DataSet then begin
        IsRootDataSetMoved;
        UpdateScrollBar;
     end
     else if FScrollWithinLevel then UpdateScrollBar;
  end;

  if IsChildDataSetOfActive(DataSet) then
  begin
     if (dtvoAutoExpandOnDSScroll in Options) then
        LastVisibleDataSet:= dataset;
  end
  else LastVisibleDataSet:= dataset;

  if ActiveDataSet<>DataSet then
  begin
     if (dtvoAutoExpandOnDSScroll in Options) then
        ActiveDataSet:= DataSet;
     DataLink:= GetChildDataLink(ActiveDataSet);
     if DataLink<>nil then begin
        ResetStartOffsets(DataLink.DataSet);
     end;
  end
  else begin
     DataLink:= GetChildDataLink(ActiveDataSet);
     if DataLink<>nil then ResetStartOffsets(DataLink.DataSet);
  end;

  SaveIfFirstRecordBookmark(DataSet);
  CheckMaxWidthGrow:= True;
  InvalidateClient;
end;

Procedure TfcDBCustomTreeView.SaveIfFirstRecordBookmark(DataSet: TDataSet);
begin
  if DataSet=nil then exit;
  if FDataLinks.Count>0 then
  begin
     if Dataset <> TfcTreeDataLink(FDataLinks[0]).DataSet then exit;

     if (DataSet.state = dsBrowse) and (DataSet.Bof) and (TfcTreeDataLink(FDataLinks[0]).DataSet = DataSet) then
     begin
         FreeFirstBookmark;
         FirstBookmark:= dataset.GetBookmark;
     end
  end;

  if DataSet.state in [dsEdit, dsInsert] then FreeFirstBookmark;

end;

Procedure TfcDBCustomTreeView.FreeFirstBookmark;
begin
     {$ifdef fcdelphi4up}
     if FirstBookmark<>Nil then FreeMem(FirstBookmark);
     FirstBookmark:= nil;
     {$else}
     if FirstBookmark<>Nil then StrDispose(FirstBookmark);
     FirstBookmark:= nil;
     {$endif}
end;

Procedure TfcDBCustomTreeView.FreeLastActiveBookmark;
begin
     {$ifdef fcdelphi4up}
     if LastActiveBookmark<>Nil then FreeMem(LastActiveBookmark);
     LastActiveBookmark:= nil;
     {$else}
     if LastActiveBookmark<>Nil then StrDispose(LastActiveBookmark);
     LastActiveBookmark:= nil;
     {$endif}
end;

procedure TfcDBCustomTreeView.DoCalcNodeAttributes(Node: TfcDBTreeNode);
begin
   if Assigned(FOnCalcNodeAttributes) then
      FOnCalcNodeAttributes(Self, Node);
end;

procedure TfcDBCustomTreeView.DoCalcSectionAttributes(Node: TfcDBTreeNode;
  Section: TfcTreeHeaderSection; var DisplayText: string);
begin
   if Assigned(FOnCalcSectionAttributes) then

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -