View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0005023 | JEDI VCL | 00 JVCL Components | public | 2009-11-17 14:07 | 2012-03-22 19:11 |
Reporter | Biblin | Assigned To | wpostma | ||
Priority | normal | Severity | major | Reproducibility | always |
Status | resolved | Resolution | fixed | ||
Product Version | Daily / GIT | ||||
Target Version | 3.40 | Fixed in Version | |||
Summary | 0005023: ManualTabDock fails to work first time and works incorrectly subsequent times, Dock to Tab Grabber invisibility. | ||||
Description | This 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 Information | OS: Windows Vista. Compiled with Delphi 7 | ||||
Tags | No tags attached. | ||||
|
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; |
|
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) |
|
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. |
|
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. |
|
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. |
|
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! |
|
Testing change from Kiriakos note 0017010. svn rev 12621 - JvDockControlForm.pas - dec 21, 2009 |
|
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. |
|
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. |
|
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. |
|
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? |
|
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. |
|
Excellent, 100% agreed with obones. Sorry for being testy. comments were revised afterwards |
|
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? |
|
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. |
|
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. |
|
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). |
|
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. |
|
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. :-) |
|
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. |
|
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. |
|
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! :) |
|
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; |
|
I'm afraid the above doesn't work for me (on Delphi 2007, in case that helps). I still get a blank panel. |
|
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. |
|
I'm using the 3.39 release. Do I need SVN for the fix to work? |
|
That should be OK. Have you got any other Delphi version to try? |
|
Just tried JVCL 3.40. Seems to work fine without any additional fixing! |
|
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. |
|
So what do I do with this issue ? |
|
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. |
|
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 |
|
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 |
|
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; |
|
Thanks Kiriakos. I'll give that a try. Are you using Delphi 6? Or, a more current version? -Tony |
|
Delphi 2006, 2010, XE2 |
|
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 |
|
This issue is still reproducible for me in all Delphi versions. |
|
I made some fixes to some deep JvDocking glitches today that may have affected this issue. They are committed under Case 005783 |
|
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. |
|
Subversion commit 13279, 2012-03-33. |
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 |