View Issue Details

IDProjectCategoryView StatusLast Update
0005023JEDI VCL00 JVCL Componentspublic2012-03-22 19:11
ReporterBiblinAssigned Towpostma 
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product VersionDaily / GIT 
Target Version3.40Fixed in Version 
Summary0005023: ManualTabDock fails to work first time and works incorrectly subsequent times, Dock to Tab Grabber invisibility.
DescriptionThis is reproducable in the DockingInCode demo project but applies to any custom project that uses ManualTabDock to dock programmatically.

Change the tab dock button functionality to create tabs to the RightDockPanel instead of custom.
Start the docking in code demo and click the tab dock button.
Instead of creating 3 tabs docked to the right, it creates a blank dock panel
Click the button again will now create 3 tabs docked to the Right Dock Panel but these windows will not resize with the panel.

If you create windows via another method and tab dock them via drag/drop, everything works as it should. It seems like ManualTabDock is not working correctly.

Also, workaround shown in comments, solves initial problem, but makes the Dock To Tabs grabber (a custom version of the windows titlebar nonclient area similar to the top of MDI windows) is not visible, preventing you from seeing the window caption (title) or closing tabs.
Additional InformationOS: Windows Vista.
Compiled with Delphi 7
TagsNo tags attached.

Relationships

related to 0005783 resolvedwpostma Add feature: JV Docking should notify client TForms when they are docked and undocked. 

Activities

wpostma416

2009-11-18 21:04

developer   ~0016896

Possible Fix/Workaround:

in JvDockControlForm.pas procedure ManualTabDock
right after this line:
  TabHost := DockClient1.CreateTabHostAndDockControl(Form1, Form2);

comment out the TabHost.Hide call:
// TabHost.Hide;
add this:
  TabHost.Align := alClient;

Biblin

2009-11-24 16:39

reporter   ~0016902

Workaround doesn't work. Allows tabs to appear but hides the grab bar so you can't then move it around or close any of the tabs (Since close button is on grab bar)

wpostma416

2009-11-24 17:00

developer   ~0016903

Last edited: 2009-11-24 17:02

Okay, I have seen this (grabber is gone) issue appear on my system in Delphi 2010, although it works fine in 2007. Updating description.

Could use some help from someone.

wpostma416

2009-12-11 17:35

developer   ~0016990

Okay this issue is worse than I thought:

1. it appears that versions of JVCL JvDocking code from delphi 2007 do certain docking operations better than current code does. I observe breakage in delphi 2007, delphi 7, and delphi 2010.

2. the exact kinds of breakage vary from version of delphi to version of delphi, but the common element is that something always goes wrong when trying to dock to tabs from code, as the original poster of this bug shows.

wpostma416

2009-12-11 20:10

developer   ~0016991

Fix (possible) in svn rev 12619, JvDockControlForm.pas.

log comment:

Fix for Mantis 0005023
 ManualTabDock fails to work first time and works incorrectly subsequent times, Dock to Tab Grabber invisibility.
  when using RightDockPanel.
 Also seems we had problems on Delphi 2010 systems, with ManualTabDock.

Kiriakos

2009-12-19 02:46

reporter   ~0017010

I have the same issue with the latest revision. What appears to have created the problem is the inheritance of TJvDockableForm from TJvForm. If I change that statement back to

TJvDockableForm = class(TForm)

the problem gets resolved!

wpostma416

2009-12-21 20:29

developer   ~0017012

Last edited: 2009-12-21 20:51

Testing change from Kiriakos note 0017010.

svn rev 12621 - JvDockControlForm.pas - dec 21, 2009

obones

2009-12-28 16:41

administrator   ~0017032

I don't like the change back to TForm because it means the form no longer benefits from the automatic translation mechanism introduced in TJvForm.
It would be much nicer to see what in TJvForm hinders the functionality of TJvDockableForm.

wpostma416

2009-12-30 15:19

developer   ~0017047

Last edited: 2009-12-30 15:19

What benefit does TJvForm offer to TJvDockable form. Remember that none of the user's forms which are dock clients are going to be TJvDockableForms, only the internal tab host form that wraps around it will be TForm, and there is absolutely no provision for any automatically translatable resource strings to ever exist in a JvDockableForm.

JVCL Users do not ever declare their own instances of TJvDockableForm, nor use them themselves. They are internal classes only. I think having TJvForm there when it provides no real benefit is only a harmful thing.

In fact, I wonder where else we use TJvForm in a way that just fattens up the app but is never used.

wpostma416

2009-12-30 15:23

developer   ~0017048

Last edited: 2009-12-30 17:26

I maintain after reading TJvForm that it is 100% harmful, and 0% useful to have TJvForm involved in JvDocking's internals.

JvForm has an auto-translation feature which is useless to this internal-only context, a Z-order bug fix (actually, shadow image issue with WinXP) that I do not think are applicable in Delphi 2009 and 2010 applications any more (MORE testing required to confirm though).

This is probably the ONLY case where inheritance from TJvForm should be changed back to TForm.

obones

2009-12-30 16:25

administrator   ~0017049

No need to be offensive here.
Just keep in mind that TJvForm was introduced to workaround that "bug" because it was not taken into account by any version of Delphi that was known at the time of writing. I was not even aware this workaround it is no longer needed in D2009 and upper.
The auto translate function was added later on and in an effort to get consistency across the whole JVCL, all forms were changed to inherit from TJvForm.
Sure, it was a blunt change and some special cases like docking were obviously missed. Fact is, those special cases are rare, I even suspect docking is the only one.
So what do we do from here?
Well, first, change back the ancestor of TJvDockableForm to TForm, but be sure to put a comment explaining why this form does not need TJvForm.
Then, IFDEF the workaround in TJvForm for D2009 and upper so that it has no impact on those versions, while keeping the auto-translate facility.

What do you think of this?

obones

2009-12-30 16:36

administrator   ~0017050

Just to make it clearer: Warren, I'm not saying you should be the one doing the changes I proposed, but I sure would like your opinion on them.

wpostma416

2009-12-30 17:21

developer   ~0017051

Excellent, 100% agreed with obones.

Sorry for being testy. comments were revised afterwards

obones

2009-12-31 10:56

administrator   ~0017054

No worries.
I have now changed TJvForm so that CM_SHOWINGCHANGED is only handled in D2007 and lower.
One last comment:

TJvDockableForm has a DFM associated to it, even if it is empty and pretty much useless. I know that removing it would make the application crash because inherited Create tries to load the DFM.
But that can be overcome by calling inherited CreateNew instead of inherited Create.
This way the DFM can be removed, making these internal forms even less visible to the naked eye.

What do you think?

wpostma416

2009-12-31 14:40

developer   ~0017058

Current JvDockableForm.dfm content:

object JvDockableForm: TJvDockableForm
  Left = 168
  Top = 133
  Width = 272
  Height = 241
  Caption = ''
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -12
  Font.Name = 'Arial'
  Font.Style = []
  OldCreateOrder = False
  Visible = False
  PixelsPerInch = 96
  TextHeight = 13
end

I can see some minor perks in removing it, functionally. Who needs it. It could cause problems in future anyways. I suppose we should have it grab certain parameters like PixelsPerInch and font, from some parent font location so TForm font and PixelsPerInch aren't uninitialized.

obones

2009-12-31 15:25

administrator   ~0017059

AFAIK, those values are initialized by the constructor and later stored in the DFM so that they don't change when loaded on another computer.
But, if I understand correctly, those forms are not meant to be displayed.
This is why I think it does not matter if those properties take the current values from the running environment instead of whatever values they picked up while development took place.

wpostma416

2009-12-31 16:33

developer   ~0017060

I don't think they are "displayed" as-is, per se, but rather the dockable form base class is the parent class for various internally created and managed forms that are made visible when used as tab containers or to show a grabber bar (emulated non-client area) with a real form below it, align=alClient in the client area (since these internal forms are only displayed in a docked state, and are auto-destroyed when the user undocks his client, these are more a set of auto-created TControl/TPanel objects, than like normal TForms).

Biblin

2010-01-11 17:24

reporter   ~0017093

The "workaround" on line 1551 (Tabhost.Show) doesn't seem to be needed now that the ancestor has been changed to TForm. In fact it looks like it's detrimental in that with it you see the tabhost float temporarily before docking and without it the new window just appears along with the tabhost in the correct place; faster and better looking.

wpostma416

2010-01-11 17:26

developer   ~0017094

agreed, and that 'show' workaround code is not in the JVCL subversion repository.

i merely leave it in the comments above as a part of the history of this issue.

:-)

Biblin

2010-01-11 17:53

reporter   ~0017095

Ah. I just updated from SVN and it seemed to still be present otherwise I wouldn't have mentioned it. Could be I did something wrong though. Revision 12635.

wpostma416

2010-01-11 18:01

developer   ~0017096

It's like 1545 (Mantis 0005023) workaround, and it was still there on my working copy. But should not be. I should remove that workaround and repeat my testing.
I can not in good conscience make that reversion without testing it thoroughly, as there could be wicked breakage, beyond the annoying visible flashing of the undocked visible form. Luckily FEW people use this function ManualTabDock. Maybe just me and you.

thatistosay

2010-08-03 11:43

reporter   ~0017547

Just thought I'd say this is causing me problems too. The large project I work on is currently using JVCL 3.36, which doesn't have the problem, but I'm seeing it after trying an upgrade to 3.39. So it isn't just you two! :)

Kiriakos

2010-09-16 22:39

reporter   ~0017684

The new version of ManualTabDock by Warren is broken. It only works if Form1 is alread docked into DockSite.

I have tested the following which is close to the old version and it works for me under Delphi 2010. It also seems to resolve bug 5023. Please try and report if it works for you.

function ManualTabDock(DockSite: TWinControl; Form1, Form2: TForm): TJvDockTabHostForm;
var
  TabHost: TJvDockTabHostForm;
  DockClient1, DockCLient2: TJvDockClient;
  ScreenPos: TRect;
begin
  DockClient1 := FindDockClient(Form1);
  Form1.Hide;

  Assert(Assigned(DockClient1));

  if DockClient1.DockState = JvDockState_Docking then
  begin
    ScreenPos := Application.MainForm.ClientRect; // Just making it float temporarily.
    Form1.ManualFloat(ScreenPos); // This screws up on Delphi 2010.
  end;

  DockClient2 := FindDockClient(Form2);
  Assert(Assigned(DockClient2));
  Form2.Hide;

  if DockClient2.DockState = JvDockState_Docking then
  begin
    ScreenPos := Application.MainForm.ClientRect; // Just making it float temporarily.
    Form2.ManualFloat(ScreenPos);
  end;

  TabHost := DockClient1.CreateTabHostAndDockControl(Form1, Form2);

  TabHost.ManualDock(DockSite,nil,alClient);

  ShowDockForm(Form1);
  ShowDockForm(Form2);
  Result := TabHost;
end;

thatistosay

2010-09-24 12:25

reporter   ~0017707

I'm afraid the above doesn't work for me (on Delphi 2007, in case that helps). I still get a blank panel.

Kiriakos

2010-09-24 17:21

reporter   ~0017710

Are you using the latest release of JVCL or the SVN version? I wonder whether this is specific to Delphi 2007 since it works for me in Delphi 2006 and Delphi 2010.

thatistosay

2010-09-29 11:38

reporter   ~0017722

I'm using the 3.39 release. Do I need SVN for the fix to work?

Kiriakos

2010-09-29 12:47

reporter   ~0017723

That should be OK. Have you got any other Delphi version to try?

thatistosay

2010-09-29 12:54

reporter   ~0017724

Just tried JVCL 3.40. Seems to work fine without any additional fixing!

thatistosay

2010-09-29 12:56

reporter   ~0017725

Reading your description of the above fix again, I think I made a mistake. I assumed your code was for the original problem, which has since been fixed. The 3.40 JVCL code works for me, probably because Form1 is always already docked to the docksite in my case.

obones

2010-10-08 16:39

administrator   ~0017840

So what do I do with this issue ?

tbreina

2011-12-26 06:06

reporter   ~0019248

I think I have something similar. My legacy project worked fine with version 3.39; however, after my update to 3.45 I now get:

"ManualTabDock:TabHost not created. Your docking style may not support tabbed docking"

Since this is someone else's code, I'm flying a little blind here and was hoping someone could point me in the right direction. I'm sure there's just some problem with the code we have.

Is there a way that I can set the docking style to something that will support tabbed docking?

Here's the offending line that's generating the runtime exception:

LeftDockTabs := ManualTabDock(DockServer.LeftDockPanel, panel1, panel2);

where panel1 and panel2 are type TForm and DockServer is TJvDockServer.

tbreina

2011-12-27 04:03

reporter   ~0019251

I just tested the DockingInCode example project under Delphi 6PE (yes, it's a very old compiler). It compiles fine, but fails at runtime when I click the "Tab Dock" button.

Again, it's the old

"EInvalidClassOperation with message 'ManualTabDock: TabHost not created. Your Docking Style may not support tabbed docking.'

Not sure if anyone wants to support such an old compiler, but if there are any takers, I'd sure appreciate the help.

Thanks.
-Tony

tbreina

2011-12-27 05:05

reporter   ~0019252

One more clue: I just tested the DockingInCode example with Delphi 6PE using JVCL 3.38, 3.39, and 3.40.

The first two worked fine with the "Tab Dock" button. When I migrated to 3.40, it gave the ManualDockTab: TabHost not created" runtime error.

So it's some change from JVCL 3.39 to 3.40 that caused the runtime error with manual tab docking.

-Tony

Kiriakos

2011-12-27 17:44

reporter   ~0019253

In my projects I use the latest version of JvDockControlForm.pas but with the ManualTabDock replaced with a variation of the old one.

function ManualTabDock(DockSite: TWinControl; Form1, Form2: TForm): TJvDockTabHostForm;
var
  TabHost: TJvDockTabHostForm;
  DockClient1, DockCLient2: TJvDockClient;
  ScreenPos: TRect;
begin
  DockClient1 := FindDockClient(Form1);
  Form1.Hide;

  Assert(Assigned(DockClient1));

  if DockClient1.DockState = JvDockState_Docking then
  begin
    ScreenPos := Application.MainForm.ClientRect; // Just making it float temporarily.
    Form1.ManualFloat(ScreenPos);
  end;

  DockClient2 := FindDockClient(Form2);
  Assert(Assigned(DockClient2));
  Form2.Hide;

  if DockClient2.DockState = JvDockState_Docking then
  begin
    ScreenPos := Application.MainForm.ClientRect; // Just making it float temporarily.
    Form2.ManualFloat(ScreenPos);
  end;

  TabHost := DockClient1.CreateTabHostAndDockControl(Form1, Form2);

  TabHost.ManualDock(DockSite,nil,alClient);

  ShowDockForm(Form1);
  ShowDockForm(Form2);
  Result := TabHost;
end;

tbreina

2011-12-27 18:05

reporter   ~0019254

Thanks Kiriakos. I'll give that a try. Are you using Delphi 6? Or, a more current version?

-Tony

Kiriakos

2011-12-27 18:13

reporter   ~0019255

Delphi 2006, 2010, XE2

tbreina

2011-12-29 02:49

reporter   ~0019270

Awesome fix! Seems to work just fine on both the DockingInCode example and my app compiled with Delphi 6PE and Jedi JVCL 3.45. (Ok, the windows float for an instance, but I can live with that).

One bug in the DockingInCode example: MainFm.pas (line 192) says,

"uses JvDockTree, JvDockAdvTree;"

However, JvDockTree has already been declared in line 139. So it needs to be removed in order for the example to compile.

Thanks again Kiriakos.
-Tony

wpostma

2012-02-03 22:09

developer   ~0019369

This issue is still reproducible for me in all Delphi versions.

wpostma

2012-03-12 19:41

developer   ~0019664

Last edited: 2012-03-12 19:41

I made some fixes to some deep JvDocking glitches today that may have affected this issue. They are committed under Case 005783

Kiriakos

2012-03-19 15:31

reporter   ~0019677

It still does not work here. The only working solution I found is the one on my note above (2011-12-27 17:44). At least please replace the old method branch with the code above.

wpostma416

2012-03-22 19:11

developer   ~0019680

Subversion commit 13279, 2012-03-33.

Issue History

Date Modified Username Field Change
2009-11-17 14:07 Biblin New Issue
2009-11-18 21:04 wpostma416 Note Added: 0016896
2009-11-18 21:10 wpostma416 Assigned To => wpostma416
2009-11-24 16:39 Biblin Note Added: 0016902
2009-11-24 17:00 wpostma416 Note Added: 0016903
2009-11-24 17:01 wpostma416 Summary ManualTabDock fails to work first time and works incorrectly subsequent times => ManualTabDock fails to work first time and works incorrectly subsequent times, Dock to Tab Grabber invisibility.
2009-11-24 17:01 wpostma416 Description Updated
2009-11-24 17:01 wpostma416 Description Updated
2009-11-24 17:02 wpostma416 Note Edited: 0016903
2009-12-04 15:29 obones Status new => confirmed
2009-12-11 17:33 wpostma416 Target Version => 3.40 - not yet released
2009-12-11 17:35 wpostma416 Note Added: 0016990
2009-12-11 20:10 wpostma416 Note Added: 0016991
2009-12-19 02:46 Kiriakos Note Added: 0017010
2009-12-21 20:29 wpostma416 Note Added: 0017012
2009-12-21 20:51 wpostma416 Note Edited: 0017012
2009-12-28 16:41 obones Note Added: 0017032
2009-12-30 15:19 wpostma416 Note Added: 0017047
2009-12-30 15:19 wpostma416 Note Edited: 0017047
2009-12-30 15:23 wpostma416 Note Added: 0017048
2009-12-30 15:28 wpostma416 Note Edited: 0017048
2009-12-30 15:31 wpostma416 Note Edited: 0017048
2009-12-30 15:31 wpostma416 Note Edited: 0017048
2009-12-30 16:25 obones Note Added: 0017049
2009-12-30 16:36 obones Note Added: 0017050
2009-12-30 17:21 wpostma416 Note Added: 0017051
2009-12-30 17:26 wpostma416 Note Edited: 0017048
2009-12-31 10:56 obones Note Added: 0017054
2009-12-31 14:40 wpostma416 Note Added: 0017058
2009-12-31 15:25 obones Note Added: 0017059
2009-12-31 16:33 wpostma416 Note Added: 0017060
2010-01-11 17:24 Biblin Note Added: 0017093
2010-01-11 17:26 wpostma416 Note Added: 0017094
2010-01-11 17:53 Biblin Note Added: 0017095
2010-01-11 18:01 wpostma416 Note Added: 0017096
2010-08-03 11:43 thatistosay Note Added: 0017547
2010-09-16 22:39 Kiriakos Note Added: 0017684
2010-09-24 12:25 thatistosay Note Added: 0017707
2010-09-24 17:21 Kiriakos Note Added: 0017710
2010-09-29 11:38 thatistosay Note Added: 0017722
2010-09-29 12:47 Kiriakos Note Added: 0017723
2010-09-29 12:54 thatistosay Note Added: 0017724
2010-09-29 12:56 thatistosay Note Added: 0017725
2010-10-08 16:39 obones Note Added: 0017840
2011-12-26 06:06 tbreina Note Added: 0019248
2011-12-27 04:03 tbreina Note Added: 0019251
2011-12-27 05:05 tbreina Note Added: 0019252
2011-12-27 17:44 Kiriakos Note Added: 0019253
2011-12-27 18:05 tbreina Note Added: 0019254
2011-12-27 18:13 Kiriakos Note Added: 0019255
2011-12-29 02:49 tbreina Note Added: 0019270
2012-02-03 22:08 wpostma Assigned To wpostma416 => wpostma
2012-02-03 22:09 wpostma Note Added: 0019369
2012-03-12 19:41 wpostma Note Added: 0019664
2012-03-12 19:41 wpostma Note Edited: 0019664
2012-03-12 19:41 wpostma Relationship added related to 0005783
2012-03-19 15:31 Kiriakos Note Added: 0019677
2012-03-22 19:11 wpostma416 Note Added: 0019680
2012-03-22 19:11 wpostma416 Status confirmed => resolved
2012-03-22 19:11 wpostma416 Resolution open => fixed