Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

In this Discussion

Having problems showing and hiding Tool panels from code...

I am having a problem with hiding showing and hiding Tool panels.

I create user documents as tabbed docs at run time.  There are 2 different document types, an editor and a viewer.

When the viewer is in focus, I want a specific Tool panel to appear and that tool panel to hide when the user selects a different editor tab.

My code hides the viewer's tool panel when it closes and un-hides it when it is opened and this works fine.  However if I choose an editor tab without closing the Viewer tab, the Viewer tool panel remains.  When I return to the Viewer Tab the Viewer tool panel is then hidden.

In debug stepping  through the code it works as expected, its only when I run it direct that things get out of order which indicates to me that there is a race issue somewhere.

Below is the code I am using on entering, leaving and Closing the page.

procedure tfmPDFPage.DocEnter(Sender: TObject); // Code called on entering the Viewer Tab.
begin
  fmIDEMain.ActivePDF := Self;
  if PageID <> fmPdfExplorer.ActivePDFID then begin
    gtPDFViewer1.Active := false;
    fmPDFExplorer.gtPDFOutlineViewer1.Active := true;   // The viewers Tool panel
    gtPDFViewer1.Active := true;
    fmPDFExplorer.RefreshExplorer(Self);
    fmPDFExplorer.ActivePDFID := PageID;
  end;

  // Show the PDF Explorer
  fmIDEMain.dpPDFExplorer.PanelVisible := true; // Here we make the Viewer Tool panel visible
end;

procedure TfmPDFPage.DocExit(Sender: TObject); // Code is called on leaving the viewer tab.

begin
  fmPDFExplorer.gtPDFOutlineViewer1.Active := false;
  fmIDEMain.dpPDFExplorer.PanelVisible := false;
end;

procedure tfmPDFPage.DocClose(Sender: TObject; // Code called on closing the Viewer Tab.
Var Action: TLMDockPanelCloseAction);
Var dz,tz, prevz: TLMDDockZone; 
      dp: TLMDDockPanel;
i: Integer;
begin
  fmIDEMain.ActivePDF := nil;  //Select the previous tab
  if Assigned(ActivePanel) then begin
    dp := ActivePanel;
    dz := dp.zone;
    if Assigned(dz) then begin
      i := dz.Index;
      tz := dz.parent;
      if Assigned(tz) and (i > 0) then begin
        prevz := tz[i - 1];
        tz.SelectedPage := prevz;
        tz.SelectedPage.Panel.Show;
        ActivePanel := tz.SelectedPage.Panel;
      end
    else ActivePanel := nil;
    end;
  end;
  Action := caFree;
end;

Tagged:

Comments

  • 5 Comments sorted by Votes Date Added
  • I have written a small program to demonstrate the problem.  Run it, note tool panel on the left (lmdFixed) and one tabbed document.
    Click file, AddPage  a new tabbed page (MemoPage1) will be shown and a new left hand tool panel will appear (dpLMDTemp).
    LMDTemp should only appear when a memo page has focus and shoud hide when the LMDDocPanel2 page has focus.

    Now click between the MemoPage and LMDDockPanel2 (You will need to do it a couple of times) , note the LMDTemp panel gets out of sync and starts to appear when the LMDDocPanel2 has focus and when the LMDTemp has focus the LMDTemp is hidden.

    Any advice would be appreciated.

    JohnB
    zip
    zip
    DockDemo.zip
    54K
  • The problem is that you try to change dock layout (show or hide temp panel) from inside of internal layout re-calculation. Possible workaround will be to sho/hide required panel asynchronously, for example using post-message:

    procedure TfmMemoPage.DocEnter(Sender: TObject);
    begin
      FShowTempPanel := True;
      PostMessage(Handle, WM_USER, 0, 0);
    end;

    procedure TfmMemoPage.DocExit(Sender: TObject);
    begin
      FShowTempPanel := False;
      PostMessage(Handle, WM_USER, 0, 0);
    end;

    procedure TfmMemoPage.WMUser(var M: TMessage);
    begin
      fmMain.dpLMDTemp.PanelVisible := FShowTempPanel;
    end;

    Simpler to implement options will be to use TTimer with zero Interval. 
    Also, you probably can use TThread.ForceQueue instead of PostMessage or timer.
  • Tried the timer approach as it saved having to hook into windows messages.

    Generally it works except after first adding a page.  It seems that when clicking away from the just added page, the DocExit event is not triggered.  Switching back and forth after that and it works fine.

    I doubt any of the other techniques would work any better if the first exit event doesn't trigger.

    See my new code attached.
    zip
    zip
    DockDemo (2).zip
    54K
  • edited February 2020 Posts: 0 Accepted Answer Vote Up0Vote Down
    May be your DocExit does not fire, because the panel is not active right after docking?
  • Good thought, thanks, I think I have troubled you enough now, I have a working solution.
Sign In or Register to comment.