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

📄 jvdocktree.pas

📁 East make Tray Icon in delphi
💻 PAS
📖 第 1 页 / 共 5 页
字号:
  // a tabbed set of other forms, so we have to check for that and
  // go down into those container forms. DoQuery calls itself and other
  // helper routines, recursively, and together this set of routines
  // descends through the Zones, Controls (Forms), etc, finding all
  // the Controls inside those zones.
  DoControlQuery(TopZone, FoundItems);
end;

//XXX Helper routines for DoQuery: XXX

procedure TJvDockTree._ParentQuery(LevelsLeft: Integer; AParent: TWinControl; FoundItems: TList );
var
 DockServer: TJvDockServer;
 LClassName, LName: string;
begin
  if Assigned(AParent) then
  begin
    LClassName := AParent.ClassName;
    LName := AParent.Name;
    //Write(Indent + '      <parent>');
    //Write(Indent + '        <class>' + LClassName + '</class>');
    //Write(Indent + '        <name>' + LName + '@' + IntToHex(Integer(AParent), 8) + '</name>');
    if AParent is TJvDockPanel then
    begin
      DockServer := TJvDockPanel(AParent).DockServer;
      if Assigned(DockServer) then
      begin
        //Write(Indent + '        <dockserver>' + DockServer.Name + '</dockserver>');
      end
      else
      begin
        //Write(Indent + '        <error>TJvDockPanel has no DockServer</name>');
      end;
    end;
    // recurse down:
    if LevelsLeft > 0 then
      if AParent.Parent <> AParent then // don't show controls where they are their own parent!
        _ParentQuery(LevelsLeft - 1, AParent.Parent, FoundItems);
    //Write(Indent + '      </parent>');
  end;
end;

procedure TJvDockTree._PageControlQuery(PageControl: TWinControl; FoundItems: TList); {actually TJvDockTabPageControl}
var
  I, J, Count: Integer;
  PageID: string;
  LPageControl: TJvDockTabPageControl;
  LClassName, LName: string;
begin
  if Assigned(PageControl) then
  begin
    LPageControl := PageControl as TJvDockTabPageControl;
    LClassName := LPageControl.ClassName;
    LName := LPageControl.Name;
    Count := LPageControl.Count;
    //Write(Indent + '      <pageControl>');
    //Write(Indent + '         <class>' + LClassName + '</class>');
    //Write(Indent + '         <name>' + LName + '</name>');
    for I := 0 to Count - 1 do
    begin
      PageID := 'Page' + IntToStr(I + 1);
      //Write(Indent + '           <' + PageID + '>');
      //Write(Indent + '              <class>' + LPageControl.Pages[I].ClassName + '</class>');
      //Write(Indent + '              <name>' + LPageControl.Pages[I].Name + '</name>');
      //Write(Indent + '              <pageCaption>' + LPageControl.Pages[I].Caption + '</pageCaption>');
      //Write('');
      for J := 0 to LPageControl.Pages[I].ControlCount - 1 do
        _ControlQuery(LPageControl.Pages[I].Controls[J] as TWinControl, FoundItems);
      //Write(Indent + '           </' + PageID + '>');
    end;
    //Write(Indent + '      </pageControl>');
    //Write('');
  end;
end;

procedure TJvDockTree._ControlQuery(AControl: TWinControl; FoundItems: TList);
var
 LClassName, LName: string;
 LForm: TForm;
 DockClient: TJvDockClient;
begin
  //Write(Indent + '   <Control>');
  LClassName := AControl.ClassName;
  LName := AControl.Name;
  //Write(Indent + '      <class>' + LClassName + '</class>');
  //Write(Indent + '      <name>' + LName + '</name>');
  //Write(Indent + '      <visible>' + BoolToStr(AControl.Visible, True) + '</visible>');
  //Write(Indent + '      <enabled>' + BoolToStr(AControl.Enabled, True) + '</enabled>');

  if AControl is TForm then
  begin
    LForm := TForm(AControl);
    //Write(Indent + '      <caption>' + LForm.Caption + '</caption>');
    DockClient := FindDockClient(AControl);
    if Assigned(DockClient) then
    begin
      LClassName := DockClient.ClassName;
      LName := DockClient.Name;

      // FOUND A CONTROL WHICH IS A FORM AND HAS A JVDOCK CLIENT.
      // Add it to FoundItems:
      if DockClient.DockState = JvDockState_Docking then
      begin
        Assert(Assigned(FoundItems));
        FoundItems.Add(AControl);
      end;
      //Write(Indent + '      <dockclient>');
      //Write(Indent + '         <class>' + LClassName + '</class>');
      //Write(Indent + '         <name>' + LName + '</name>');
      //Write(Indent + '         <customdock>' + BoolToStr(DockClient.CustomDock, True) + '</customdock>');

      // uses DockStateStr - utility function in JvDockControlForm.pas:
      //Write(Indent + '         <dockstate>' + DockStateStr(DockClient.DockState) + '</dockstate>');

      //Write(Indent + '      </dockclient>');
    end
    else
    begin
      //Write(Indent + '      <WARNING>No dockclient found in this form.</WARNING>');
    end;
    if LForm is TJvDockTabHostForm then
      _PageControlQuery(TJvDockTabHostForm(LForm).PageControl, FoundItems);
  end;

  { LAST for each control, recursively query the TWinControl.Parent
    tree, but limit to only a few levels
    so we can avoid information overload. Oops. Too late. :-) }
  _ParentQuery(3, AControl.Parent, FoundItems);
  //Write(Indent + '   </Control>');
end;

// DoQuery:
// This is a recursive function called from top level function Query().
// This helps us to find particular Controls, that are docked to a particular
// dock panel, or are floating, etc.
procedure TJvDockTree.DoControlQuery(TreeZone: TJvDockZone; FoundItems: TList);
var
  Zone: TJvDockZone;
begin
  Zone := TreeZone;

  { while loop over siblings at this level...}
  while Assigned(Zone) do
  begin
    { Dump controls recursively }
    if Assigned( Zone.ChildControl) then
      _ControlQuery(Zone.ChildControl, FoundItems);
    { query children, descends recursively }
    DoControlQuery(Zone.ChildZones, FoundItems);

    {query all siblings at this level immediately after current item }
    Zone := Zone.NextSibling;
  end;
end;

{$ENDIF JVDOCK_QUERY}

{$IFDEF JVCL_DOCKING_NOTIFYLISTENERS}
// properties in Dock Style (FDockStyle) have changed.
procedure TJvDockTree.NotifyDockStyleChange;
var
 Changed: Boolean;
 LDockStyle: TJvDockBasicStyle;
begin
  if not Assigned(FDockStyle) then
    Exit;
  LDockStyle := FDockStyle as TJvDockBasicStyle;
  Changed := False;
  { change in grabber size: }
  if LDockStyle.ConjoinServerOption.GrabbersSize > 0 then
    if FGrabberSize <> LDockStyle.ConjoinServerOption.GrabbersSize then
    begin
      Changed := True;
      // we purposely DON'T use the TJvDockTree.SetGrabberSize function or
      // access the GrabberSize as a Property, instead we assign FGrabberSize
      // directly, because doing otherwise would cause TWO calls to UpdateAll
      // and DockSite.Invalidate.
      FGrabberSize := LDockStyle.ConjoinServerOption.GrabbersSize;
    end;

  // This now happens only when NotifyDockStyleChange is invoked, because
  // multiple properties might be updated, and we only want to update the whole
  // deal once, for less flickering, and more efficiency: Wpostma.
  if Changed then
  begin
    UpdateAll; // Update once with each change.
    DockSite.Invalidate;
  end;
end;
{$ENDIF JVCL_DOCKING_NOTIFYLISTENERS}

procedure TJvDockTree.AdjustDockRect(Control: TControl; var ARect: TRect);
begin
  InflateRect(ARect, -BorderWidth, -BorderWidth);
  case GrabbersPosition of
    gpTop:
      Inc(ARect.Top, GrabberSize);
    gpBottom:
      Dec(ARect.Bottom, GrabberSize);
    gpLeft:
      Inc(ARect.Left, GrabberSize);
    gpRight:
      Dec(ARect.Right, GrabberSize);
  end;
end;

procedure TJvDockTree.BeginUpdate;
begin
  Inc(FUpdateCount);
end;

procedure TJvDockTree.EndUpdate;
begin
  Dec(FUpdateCount);
  if FUpdateCount <= 0 then
  begin
    FUpdateCount := 0;
    UpdateAll;
  end;
end;

function TJvDockTree.FindControlZone(Control: TControl; IncludeHide: Boolean): TJvDockZone;
var
  CtlZone: TJvDockZone;

  procedure DoFindControlZone(StartZone: TJvDockZone);
  begin
    if (StartZone.ChildControl = Control) and (StartZone.Visibled or IncludeHide) then
      CtlZone := StartZone
    else
    begin
      if (CtlZone = nil) and (StartZone.NextSibling <> nil) then
        DoFindControlZone(StartZone.NextSibling);

      if (CtlZone = nil) and (StartZone.ChildZones <> nil) then
        DoFindControlZone(StartZone.ChildZones);
    end;
  end;

begin
  CtlZone := nil;
  if (Control <> nil) and (FTopZone <> nil) then
    DoFindControlZone(FTopZone);
  Result := CtlZone;
end;

procedure TJvDockTree.ForEachAt(Zone: TJvDockZone; Proc: TJvDockForEachZoneProc;
  ScanKind: TJvDockTreeScanKind; ScanPriority: TJvDockTreeScanPriority);

  procedure DoForwardForEach(Zone: TJvDockZone);
  begin
    Proc(Zone);
    if ScanPriority = tspSibling then
    begin
      if Zone.NextSibling <> nil then
        DoForwardForEach(Zone.NextSibling);

      if Zone.ChildZones <> nil then
        DoForwardForEach(Zone.ChildZones);
    end
    else
    begin
      if Zone.ChildZones <> nil then
        DoForwardForEach(Zone.ChildZones);

      if Zone.NextSibling <> nil then
        DoForwardForEach(Zone.NextSibling);
    end;
  end;

  procedure DoMiddleForEach(Zone: TJvDockZone);
  begin
    if ScanPriority = tspSibling then
    begin
      if Zone.NextSibling <> nil then
        DoMiddleForEach(Zone.NextSibling);
    end
    else
    begin
      if Zone.ChildZones <> nil then
        DoMiddleForEach(Zone.ChildZones);
    end;

    Proc(Zone);

    if ScanPriority = tspSibling then
    begin
      if Zone.ChildZones <> nil then
        DoMiddleForEach(Zone.ChildZones);
    end
    else
    if Zone.NextSibling <> nil then
      DoMiddleForEach(Zone.NextSibling);
  end;

  procedure DoBackwardForEach(Zone: TJvDockZone);
  begin
    if ScanPriority = tspSibling then
    begin
      if Zone.NextSibling <> nil then
        DoBackwardForEach(Zone.NextSibling);

      if Zone.ChildZones <> nil then
        DoBackwardForEach(Zone.ChildZones);
    end
    else
    begin
      if Zone.ChildZones <> nil then
        DoForwardForEach(Zone.ChildZones);

      if Zone.NextSibling <> nil then
        DoForwardForEach(Zone.NextSibling);
    end;
    Proc(Zone);
  end;

begin
  if Zone = nil then
  begin
    if FTopZone = nil then
      FTopZone := FDockZoneClass.Create(Self);
    Zone := FTopZone;
  end;

  case ScanKind of
    tskForward:
      DoForwardForEach(Zone);
    tskMiddle:
      DoMiddleForEach(Zone);
    tskBackward:
      DoBackwardForEach(Zone);
  end;
end;

procedure TJvDockTree.GetControlBounds(Control: TControl; out CtlBounds: TRect);
var
  Z: TJvDockZone;
begin
  Z := FindControlZone(Control);
  if Z = nil then
    FillChar(CtlBounds, SizeOf(CtlBounds), 0)
  else
    with Z do
      CtlBounds := Bounds(Left, Top, Width, Height);
end;

function TJvDockTree.HitTest(const MousePos: TPoint; out HTFlag: Integer): TControl;
var
  Zone: TJvDockZone;
begin
  Zone := InternalHitTest(MousePos, HTFlag);
  if Zone <> nil then
    Result := Zone.ChildControl
  else
    Result := nil;
end;

procedure TJvDockTree.InsertControl(Control: TControl; InsertAt: TAlign;
  DropCtl: TControl);
const
  {$IFDEF COMPILER6_UP}
  Orients: array [TAlign] of TDockOrientation =
    (doNoOrient, doHorizontal, doHorizontal, doVertical, doVertical, doNoOrient, doNoOrient);
  MakeLast: array [TAlign] of Boolean =
    (False, False, True, False, True, False, False);
  {$ELSE}
  Orients: array [TAlign] of TDockOrientation =
    (doNoOrient, doHorizontal, doHorizontal, doVertical, doVertical, doNoOrient);
  MakeLast: array [TAlign] of Boolean =
    (False, False, True, False, True, False);
  {$ENDIF COMPILER6_UP}
var
  Sibling: TJvDockZone;
  Me: TJvDockZone;
  Inser

⌨️ 快捷键说明

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