How can you tell if a TJvDockServer Form is unpinn

2019-07-30 13:12发布

问题:

I was just wondering if anybody knew how to determine if a TJvDockServer Form is pinned or unpinned easily. The only way I've been able to do so is by checking if a parent form is a TJvDockVSPopupPanel via...

ancestor := GetAncestors(Self, 3);
if (ancestor is TJvDockTabHostForm) then
    if ancestor.Parent <> nil then
    begin
        if ancestor.Parent is TJvDockVSPopupPanel then
        begin
            // Code here
        end;  
    end;

and getAncestors is...

function GetAncestors(Control : TControl; AncestorLevel : integer) : TWinControl;
begin
    if (Control = nil) or (AncestorLevel = 0) then
        if Control is TWinControl then
            result := (Control as TWinControl)
        else
            result := nil // Must be a TWinControl to be a valid parent.
    else
        result := GetAncestors(Control.Parent, AncestorLevel - 1);
end; 

回答1:

I would check DockState first, like this:

function IsUnpinned(aForm:TMyFormClassName):Boolean;
begin
  result := false;
 if Assigned(aForm) then
    if aForm.Client.DockState = JvDockState_Docking then
    begin
      // it's docked, so now try to determine if it's pinned (default state,
      // returns false) or unpinned (collapsed/hidden) and if unpinned, return true.
      if aForm.Client.DockStyle is TJvDockVSNetStyle then
      begin
        if Assigned(aForm.Parent) and (aForm.Parent is TJvDockVSPopupPanel) then
        begin
          result := true;
        end;
      end;  
    end;
end;

Unpinned means that the dock style supports a bimodal (click it's on, click it's off) state change from pinned (the default state when you dock) to unpinned (but still docked) state which is entirely hidden except for a tiny name-plate marker.

The above code I wrote does not recurse through parents, and so it does not handle the case that your code is trying to handle it seems, which is if the form is part of a tabbed notebook which is then hidden inside a JvDockVSPopupPanel. (Make three pages, then hide them all by unpinning). You would need to use the Ancestors approach in that case, but I would at least still add the check to TJvDockClient.DockState to whatever approach you use.

However, your approach which appears to hard code a 3 level recursion is probably only applicable to your exact set of controls, so I would consider rewriting it generally, by saying "If aForm has a parent within the last X generations of parents that is a TJvDockVSPopupPanel, then return true, otherwise return false".