-
3 Attachment(s)
(VB6) SSTabEx: SSTab replacement. Themed and with new features
Note: this control has been superseded by NewTab control and is no longer updated/maintained.
This control is a direct replacement of the SSTab control.
It fully replaces the SSTab control (TabCtl32.ocx), while adding more features.
Download from GitHub.
Read the help documentation online.
Some enhancements are:
- It supports Windows visual styles or themes
- The background color of the tabs can be changed (property TabBackColor)
- Another Style has been added (along with the two available in the original): it can be also rendered with the TabStrip look alike.
- Several new events and properties available
- More control at design time, for example the controls can be moved from one tab to another (that is available in a property page)
- Since many properties that define the appearance can be customized, the customized values can be saved (from a property page) and restored into another SSTabEx control.
- It fixes the focus to hidden controls issue that the original SSTab suffers when navigating with the tab key.
Themed in Windows 10:
Attachment 162323
Not themed but TabBackColor changed (and also Style = ssStyleTabStrip):
Attachment 155989
One note: if you use the Tab property of the control in code, you'll have to change it to TabSel.
I couldn't use Tab as a property name because it is a VB6 reserved keyword.
It should work in any Windows version from Windows 2000.
(Not tested, just tested on XP SP3 and Windows 10).
For documentation, there are two files:
- docs/Readme - Notes.txt, and explains things related to the component development and compiling.
- And docs/tabexctl_reference.html that is the control documentation, from the point of view of using the control. The same information is in a property page.
Changelog:
2022-06-28 Validation added: TabsPerRow property now doesn't accept 0 as a value.
2022-06-27 Fix in Property Page "General". Some validations were missing and change behavior when a text field gets focused (.
2022-06-26 Fix in CheckContainedControlsConsistency procedure.
2022-06-26 Fixed errors when the control was used in VBA.
2022-06-25 Behavior change: when an OLE element is dragged over an inactive tab, the drop is disabled.
2022-06-25 Fixed: OLEDropMode property was not applying value changed at design time.
2022-06-25 Removed dependency on vba6.dll for the compiled ocx.
2022-06-19 Fixed bug introduced in 2022-08-06 fix
2022-06-12 Fixed issue regarding gaps between tabs when control is themed and noticiable mostly when the backcolor is different to the tab color.
2022-06-08 Improved compatibility with Krool's controls (fixed an issue with .hWnd of the controls).
2021-11-30 Added ContainedControlMove method
2021-11-28 fix in ContainedControlLeft property
2021-11-16 important bug fix in TabVisible property
2021-10-27 bug fix in TabVisible property when no visible tab is left, and after that a tab is made visible.
2021-10-23 improvements regarding disabled state (Enabled = False).
2021-07-02 fixed bug in tab appearance when TabSeparation > 0 and control is themed.
2021-07-02 fixed bug in font when TabOrientation is set to bottom.
2021-06-27 changed constant names in cDlg to avoid conflict with other components.
2021-06-27 fixed bug related to tab border width when VisualStyles = False and Style = ssStyleTabbedDialog.
2021-06-27 fixed bug related to tab background color glitch when VisualStyles = False, Style = ssStyleTabbedDialog, BackColor <> TabBackColor and mouse hovers over a tab being screen DPI = 100%.
2021-05-06 Updated documentation
2021-04-07 Added property AutoTabHeight.
2021-04-07 The automatic tab width when Style is set to ssStyleTabStrip or when the control is themed and Style is ssStyleTabStrip or ssStylePropertyPage has been changed to add a little space between tabs.
2021-04-06 Made some minor corrections to the interface with the help of VBCompareInterface and VBCopyInterface - https://www.vbforums.com/showthread.php?890861
2021-04-06 Changed/reorganized folders and files locations.
2021-04-06 Removed file subclass.cls (GSubclass class), and changed isubclass.cls to cIBSSubclass.cls, mSubclass.bas to mBSSubclass.bas and mPropsDB to mBSPropsDB (These files are all under the 'subclass' folder. Whatch that if you are updating from a previous version in an existing project).
2021-04-06 Added IDE protection for the subclassing code when it runs in source code. It does not cover all and every situation, but most normal situations that can crash the IDE are covered, like when the UserControl goes into zombie state or start compiling with an instance of the control open at design time. This code doesn't get added to the compiled version (it is automatically excluded).
2021-04-02 Changed the ToolBoxBitmap.
[cut, full version in Changelog.txt inside]
2018-02-06: Initial release
Download from GitHub.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Good work. A solid SSTab was overdue and now as you have done it I might stick to your version instead of the unflexible TabStrip.
Just two advise upfront related to DPI awareness, since I trapped over all this.
1. Don't use ScaleX to convert Himetric to pixels, it's not precise on some DPI settings. Instead use an API way. (Like I did via CHimetricToPixel_X/Y functions)
2. In the UserControl_Resize handler you shall do a following to correct the sizes VB reports from the host:
Code:
With UserControl
If DPICorrectionFactor() <> 1 Then
.Extender.Move .Extender.Left + .ScaleX(1, vbPixels, vbContainerPosition), .Extender.Top + .ScaleY(1, vbPixels, vbContainerPosition)
.Extender.Move .Extender.Left - .ScaleX(1, vbPixels, vbContainerPosition), .Extender.Top - .ScaleY(1, vbPixels, vbContainerPosition)
End If
End With
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Krool
Good work. A solid SSTab was overdue and now as you have done it I might stick to your version instead of the unflexible TabStrip.
Just two advise upfront related to DPI awareness, since I trapped over all this.
1. Don't use ScaleX to convert Himetric to pixels, it's not precise on some DPI settings. Instead use an API way. (Like I did via CHimetricToPixel_X/Y functions)
2. In the UserControl_Resize handler you shall do a following to correct the sizes VB reports from the host:
Code:
With UserControl
If DPICorrectionFactor() <> 1 Then
.Extender.Move .Extender.Left + .ScaleX(1, vbPixels, vbContainerPosition), .Extender.Top + .ScaleY(1, vbPixels, vbContainerPosition)
.Extender.Move .Extender.Left - .ScaleX(1, vbPixels, vbContainerPosition), .Extender.Top - .ScaleY(1, vbPixels, vbContainerPosition)
End If
End With
I found a problem when converting from/to vbContainerSize/vbContainerPosition. More info here.
That's why I made four functions: FromContainerSizeY, FromContainerSizeX, ToContainerSizeY and ToContainerSizeX.
They are just internal functions.
I also found a problem related to units, and is that in the property window, when the ScaleMode of the container is changed, the properties that work with container coordinates, may show rounding errors. For example the TabHeight may show 400.0002.
That doesn't happen in the original.
I made a function FixRoundingError that fixes that.
I don't know if those issues could be related to what you are pointing. I didn't realize of something related particulary with vbHimetric, but those problems perhaps has to do with it?
I would like to know if you see that something is bahaving wrongly. Please provide steps to reproduce the problem.
You said:
Quote:
Don't use ScaleX to convert Himetric to pixels, it's not precise on some DPI settings
I tested mainly in 120 DPI that is what I normally use in my computer, and also at 96 DPI and 144 DPI (not too much, but it seemed to work OK in every DPI setting).
What circumstances should I set up to see that problem?
Thanks for your imput Krool.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Eduardo-
I tested mainly in 120 DPI that is what I normally use in my computer, and also at 96 DPI and 144 DPI (not too much, but it seemed to work OK in every DPI setting).
What circumstances should I set up to see that problem?
See post #9 in LaVolpe's Being DPI aware Tutorial:
http://www.vbforums.com/showthread.p...=1#post5165851
Edit: I'm aware of the Single > Long > Single (HIMETRIC) rounding issue with vbContainerSize/vbContainerPosition.
I kind of live with that. Like the MSComCtl.ocx did the same as they didn't offer a ScaleMode property like you did now. As for msflexgrid.ocx I also stick hard-coded to vbTwips for my VBFlexGrid.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Krool
See post #9 in LaVolpe's Being DPI aware Tutorial:
http://www.vbforums.com/showthread.p...=1#post5165851
Edit: I'm aware of the Single > Long > Single (HIMETRIC) rounding issue with vbContainerSize/vbContainerPosition.
I kind of live with that. Like the MSComCtl.ocx did the same as they didn't offer a ScaleMode property like you did now. As for msflexgrid.ocx I also stick hard-coded to vbTwips for my VBFlexGrid.
Yes, but this issue is not just related to Himetric, it is also related to Twips.
VB6 doesn't work properly at DPI's that 1440/DPI is a non integer, because it internally works with integers. Screen.TwipsPerPixelsX/Y also works with integers. It can work at 160 DPI, 180 DPI, but not at 192 DPI (200%) or 168 DPI (175%).
Many things will work wrong in such DPI settings, not just this one.
VB6 is not ready for that.
DPI settings where a VB6 program can work fine are 96, 103, 111, 120, 131, 144, 160, 180, 206, 240, 288, 360, 480, 720 and 1440.
(It is 1440 / DPI = Twips. The above are values that lead to integers and VB6 can handle)
The ones in blue, may work, but should be tested each one because they have still a small rounding.
The ones in bold, are the ones offered to easily set in Windows GUI, so are the ones the people use.
It is also offered 192 DPI (200%) and I don't know if in some Windows version may be (168 DPI) 175%?
VB6 will have multiple issues running in those DPI, not just this one.
My programs explicitely check that and just show a message at startup saying that the program can't run at that DPI setting.
There is no easy solution for that, just a VB update where it could use single precission values intead of integer for TwipsPerPixelsX/Y.
Fortunatelly, people are not using -nowaday- those DPI setting (normally).
Edit: In other words: if you want to handle that, you should not use ScaleX/Y(vbTwips/vbPixels, vbPixels/vbTwips) nor Screen.TwipsPerPixelsX/Y either.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
I agree. However the UserControl_Resize *fix* is important. Because in atypical DPI we have some offsets which we can live with. However UserControls are even more off then what's set by the host (Form). So at least that's fixed even if overall there is something off, but that's a minor difference.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Krool
I agree. However the UserControl_Resize *fix* is important. Because in atypical DPI we have some offsets which we can live with. However UserControls are even more off then what's set by the host (Form). So at least that's fixed even if overall there is something off, but that's a minor difference.
I'll study that at some point.
Since I considered that VB6 is not ready to work at such DPI settings, because any mid-sized program will surely have many of those issues, I didn't pay attention to them.
But still, if something could be fixed, it would be better.
As I said, in my programs I show a message telling the user that the program won't display right in such DPI setting. So, it isn't a feature that for me personally would make a difference.
But I'll still study it when I have more time, for the ones that make small programs that perhaps have only a few controls and could benefit from that fix (and that also have users with those -today's- quite strange DPI settings).
Thanks Kroll, I'll do it when I finish other things that I'm currently working on.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Also, just in case that you would like to add it to your controls set, and make modifications (or not) or to add more features, feel free to do it.
I'm releasing it as free software, or public domain like license, so there is no need to cite author or anything (*).
I only would like (althoughit is not a condition or requirement), for you or anyone else, is that if you find bugs or problems, to report here, so I can also fix my own code.
I'm already using it in my programs.
Thanks.
Edit: (*) but you can still do it if you want, to say people that you are not responsable of the bugs -that it could have- or the coding style if you don't like it.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Nice work, Eduardo. :) This (along with Krool's work) gives me a path to completely dump OCX files if I ever decide to do the necessary testing.
Take Care,
Elroy :)
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
New release.
Fixed bugs with controls that don't have Width property, or Left property can't be changed at run time.
The changes are in Sub SetVisibleControls, Function MouseIsOverAContainedControl and Sub RearrangeContainedControlsPositions
Fixed bug in HideAllContainedControls.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Hello Krool,
Quote:
Originally Posted by
Krool
1. Don't use ScaleX to convert Himetric to pixels, it's not precise on some DPI settings. Instead use an API way. (Like I did via CHimetricToPixel_X/Y functions)
I corrected that. It is an issue of converting to and from pixels (from/to any scale).
I added two internal custom functions: pScaleX and pScaleY that do the conversion right.
Also, I added two other functions: Screen_TwipsPerPixelsX and Screen_TwipsPerPixelsY for correcting those values, and two correction factors: mXCorrection and mYCorrection for correcting X and Y at Mouse_Move/Up/Down events.
It seems to work fine at 192 DPI now.
Quote:
Originally Posted by
Krool
2. In the UserControl_Resize handler you shall do a following to correct the sizes VB reports from the host:
Code:
With UserControl
If DPICorrectionFactor() <> 1 Then
.Extender.Move .Extender.Left + .ScaleX(1, vbPixels, vbContainerPosition), .Extender.Top + .ScaleY(1, vbPixels, vbContainerPosition)
.Extender.Move .Extender.Left - .ScaleX(1, vbPixels, vbContainerPosition), .Extender.Top - .ScaleY(1, vbPixels, vbContainerPosition)
End If
End With
I still didn't study that...
Thanks.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Hi Eduardo,
really a nice job!
I am testing SStabEx, it seems really good.
But there is something wrong: in your help you said:
"Events:
Original from the SSTab:
Click(PreviousTab As Integer)
DblClick()
KeyDown(KeyCode As Integer, Shift As Integer)
KeyPress(KeyAscii As Integer)
KeyUp(KeyCode As Integer, Shift As Integer)
MouseDown(Button As Integer, Shift As Integer, X As Single, Y As Single)
MouseMove(Button As Integer, Shift As Integer, X As Single, Y As Single)
MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
OLECompleteDrag(Effect As Long)
OLEDragDrop(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single)
OLEDragOver(Data As DataObject, Effect As Long, Button As Integer, Shift As Integer, X As Single, Y As Single, State As Integer)
OLEGiveFeedback(Effect As Long, DefaultCursors As Boolean)
OLESetData(Data As DataObject, DataFormat As Integer)
OLEStartDrag(Data As DataObject, AllowedEffects As Long)"
That's not true, those events in the original sstab have all a first argument "index" i.e.
Original SSTab
MouseUp(Index As Integer, Button As Integer, Shift As Integer, X As Single, Y As Single)
SStabex
MouseUp(Button As Integer, Shift As Integer, X As Single, Y As Single)
that's really a problem if you have to move to sstabex an existing code.
Please can you fix it ?
Best regards
Maurizio
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Maurizio
Please can you fix it ?
Best regards
Maurizio
Not sure which SSTab you're using, but it's not the same everyone else is using. ;)
I'm kidding of course - but you're still mistaken. You have your SSTab setup as a Control Array.
Delete whatever is in the the Index Property, so it's blank, and try and re-create your event functions.
Start a new form, and add a new SSTab to verify.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Yes, or make an array of SStabEx.
How? Copy an SSTabEx control to the clipboard, then paste it into the same form, and when you are asked to create a control array, answer "yes".
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Eduardo-
This control is a direct replacement of the SSTab control.
Some enhancements are:
- It supports Windows visual styles or themes
- The background color of the tabs can be changed (property TabBackColor)
- Another Style has been added (along with the two available in the original): it can be also rendered with the TabStrip look alike.
- Several new events and properties available
- More control at design time, for example the controls can be moved from one tab to another (that is available in a property page)
- Since many properties that define the appearance can be customized, the customized values can be saved (from a property page) and restored into another SSTabEx control.
- It fixes the focus to hidden controls issue that the original SSTab suffers when navigating with the tab key.
Attachment 156005
Attachment 155989
One note: if you use the
Tab property of the control in code, you'll have to change it to
TabSel.
I couldn't use
Tab as a property name because it is a VB6 reserved keyword.
It should work in any Windows version from Windows 2000.
(Not tested, just tested on XP SP3).
For documentation, there are two files:
- _Readme - Notes.txt that is in the root folder, and explains things related to the component development and compiling.
- And [root folder]/others/Help SSTabEx control.txt that is the control documentation, from the point of view of using the control. The same information is in a property page.
Initial release: 06 Feb 2018.
Last update: 26 Feb 2018
Code:
Begin vbExtra.SSTabEx SSTabEx1
Height = 4116
Left = 252
TabIndex = 0
Top = 108
Width = 4644
_ExtentX = 8192
_ExtentY = 7260
Tabs = 7
BeginProperty Font {0BE35203-8F91-11CE-9DE3-00AA004BB851}
Name = "Tahoma"
Size = 9
Charset = 0
Weight = 400
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
TabsPerRow = 4
Tab = 1
TabHeight = 582,083 'in your code this "," ,have error. in my system must change to "."
Themed = -1 'True
TabPic16(0) = "frmTest.frx":0166
TabPic20(0) = "frmTest.frx":04B8
TabPic24(0) = "frmTest.frx":09BA
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Updated.
It turns out that it seems that there is a bug in VB6, that saves the single values of control properties localized (commas instead of points). These property settings then were rounded to integers to avoid the problem.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Elroy
Nice work, Eduardo. :) This (along with Krool's work) gives me a path to completely dump OCX files if I ever decide to do the necessary testing.
Take Care,
Elroy :)
Hi Elroy,
You are a big Tab user.
Have you switched over (any of your projects) to use this yet ?
How goes it ?
Thanks,
Rob
PS I have never used the VB6 Tab control (except a couple of plays with it years ago).
This might make me a believer.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Updated, a bug related to properly show some themes fixed.
09-Oct 2018: added property TabHoverEffect.
TabHoverEffect: default is True.
Returns/sets a value that determines if the tabs will show an effect when they are being highlighted with the mouse over them.
It only works when the control is displayed without visual styles.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Updated.
A small bug fixed (in the highlight effect).
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Bobbles
Hi Elroy,
You are a big Tab user.
Have you switched over (any of your projects) to use this yet ?
How goes it ?
Hi Bobbles,
Sorry for the late response. And sorry, but I haven't switched over. My program is entirely in English, so I've got very little need for Unicode. In the few places where I do have a need, I use less comprehensive solutions.
However, I do watch this thread as well as Krool's threads. All put together, it seems that a fairly complete Unicode solution is available for VB6. I do have a couple of installations where English isn't the primary language (one in Montreal and one in Manila). But I work entirely as a consultant (no charge for the software), and nobody has offered to pay me to convert the language. If they ever do, I may take a closer look at some of the Unicode controls (possibly switching over the whole project).
And yes, I do use the SSTab control in several places in my primary project. Personally, I think it's an excellent control, in terms of both development and end-user function.
Best Of Luck,
Elroy
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
I know this is an old thread but I'm trying to do something with SSTabEx (which works GREAT by the way, thanks for writing it) but I can't seem to figure out how to do it.
I'd like the currently selected tab to be a different color (the tab itself not the caption) when active.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
KenHorse
I'd like the currently selected tab to be a different color (the tab itself not the caption) when active.
Hello, I added the properties TabSelBackColor and TabSelForeColor
Also, in this last update, it now has RightToLeft support.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Question.
In the readme, you say:
To compile the OCX file:
Got to File/Make... and make the OCX.
Save the project.
Close the IDE.
Copy the *.OCX that you generated to the folder cmp
Rename it as *.cmp
Open the project in the IDE.
Go to Project/Properties, and in the Components tab, in Binary compatibility select the file *.cmp in the folder cmp.
Click OK.
Save the project.
I don't see a 'cmp' directory
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Question.
In the readme, you say:
To compile the OCX file:
Got to File/Make... and make the OCX.
Save the project.
Close the IDE.
Copy the *.OCX that you generated to the folder cmp
Rename it as *.cmp
Open the project in the IDE.
Go to Project/Properties, and in the Components tab, in Binary compatibility select the file *.cmp in the folder cmp.
Click OK.
Save the project.
I don't see a 'cmp' directory
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
KenHorse
I don't see a 'cmp' directory
I had named that folder "compat", but I usually use "cmp" for the folder name, and so I wrote there.
Just rename the folder "compat" to "cmp".
(anyway I will upload the zip again with the folder name already changed)
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
One more stupid question if I may
Got to File/Make... and make the OCX.
Save the project.
Close the IDE.
Copy the *.OCX that you generated to the folder cmp
Rename it as *.cmp
Open the project in the IDE.
Go to Project/Properties, and in the Components tab, in Binary compatibility select the file *.cmp in the folder cmp.
Click OK.
Save the project.
I assume by that 2nd instance of "project", you mean the one you want to use the new SSTabEx in, correct?
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Nevermind I figured it out
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
KenHorse
One more stupid question if I may
Got to File/Make... and make the OCX.
Save the project.
Close the IDE.
Copy the *.OCX that you generated to the folder cmp
Rename it as *.cmp
Open the project in the IDE.
Go to Project/Properties, and in the Components tab, in Binary compatibility select the file *.cmp in the folder cmp.
Click OK.
Save the project.
I assume by that 2nd instance of "project", you mean the one you want to use the new SSTabEx in, correct?
No, the "project" on that list is always the ocx project.
But those steps are only necesary if you are going to compile the ocx more than once.
They are necessary for keeping the compatibility of the ocx file if you compile the it later again, otherwise when loading the client that uses the old version of the ocx, you would get an error telling that the component could not be loaded (the client project, also called host project, is the exe project that uses the ocx).
But doing so would not be really necessary if you are going to compile the ocx only once.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
As I am trying to "upgrade" from the previous version of SSTabEx, I can't get VB6 to allow me to remove the old component to add the new as they share the same 'name'......
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Are you using the SSTabEx in source code or have you compiled the OCX of the old version and you are using that now in the exe?
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
I compiled and used the ocx. Finally figured the easiest thing to do was just replace the existing ocx (the original SSTabEx) with the new one. Problem solved
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
In that case you need to copy the old ocx file to the cmp folder of the project with new version and to set the compatibility to that file.
Then compile the new ocx with the new version.
-
2 Attachment(s)
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Hi Eduardo and thanks for your work and a much welcomed control. Now, I have compiled it as an ocx and been working on implementing a first instance in my project. And for over 2 weeks it has all worked fine. Then today suddenly something went hey-wack, as can be see on the screenshots. To the left, how it looks in the IDE designer and to the right how it looks when I run the project in the IDE.
Attachment 177889 Attachment 177890
What happens here is that whichever of the 2 tabs that is set to show when the form first displays loks ok, but when I click on the 2nd tab everything seems to be moved to the left with about 50% of the containers width. Now if set in code to show the tab in the images first, it displays fine but the same happens with the other tab when it's clicked to get selected.
I have no idea "why" this happens now of a sudden, it has worked fine up until today. The only change I did in my code, as far as I can recall, between functional and non-function control is to change this code:
Code:
tabChartEntry.TabSel = CInt(GetIniVal(INICHT, "EntryMode", "0", sIniFile))
to this code:
Code:
With tabChartEntry
.TabCaption(0) = cLang.GetString("529")
.TabCaption(1) = cLang.GetString("840")
.TabSel = CInt(GetIniVal(INICHT, "EntryMode", "0", sIniFile))
End With
in the startup form's Load event. Changing it back makes no change to the above.
BTW, all controls in the containers are placed either on a picturebox or a frame control, to possibly avoid subclassing issues.
I have not changed anything in the SSTabEx's code, but I have added the code to my own ActiveX project, which also contains other controls, and thus I changed the files path to avoid file collisions. This shouldn't be a source of problem though and I know what I am doing here, and as said it has worked fine for about 14 days or so.
Oh, I recall now one thing that has happened since last successful run, that "might" can have impacted. Yesterday, while I was out shortly there was a power break that outlasted my APC Power Backup system, and as far as I know it did with VB6 IDE running, I may even have had my project in run mode, but cannot really recall. Just leaving this here for your information in case it tells you something.
Thanks again and hope you may have an idea...
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Hello. Can you attach the form (or send it in private)?
I'm thinking but I don't figure something that could be happening to cause that.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Hi Eduardo and thanks for quick reply. While I wrote my originally post I came to think of that power break, and then after it crossed my mind that some corrupt data got saved to the property bag or something. So I simply cut and pasted out the picture boxes with controls from the tab containers, deleted the control instance, sited a new tab and paste the picture boxes back - and not it all seems to work again. So I am fine. If it were to happen again, I will make a copy of the form immediately, before I start to experiment, and send it to you.
Thanks.
-
2 Attachment(s)
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
-
1 Attachment(s)
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Hello, thanks for sharing it, they are nice effects.
You have to take into account that if you leave the VisualStyles property to True and the program is manifested, it won't show the buttons styles.
In my case I have the IDE manifested so I had to set the VisualStyles property to False to see the effect.
Also, people with VB6 in other languages than Chinese can have problems loading the project.
I'll upload here a version with the project's file name changed.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Updated the download in the OP.
Added fix to support high-DPI above 300.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Fixed a bug introduced in the last update.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Hi Eduardo,
now it has happened again... suddenly, the tabs that are out of focus when showing the form, when selected don't show the picturebox containers with controls, just the tab background.
This time, as I have got further in completing the whole form with controls outside of the tab control, I noticed that the controls in containers still worked indication they are there, somewhere. So I put in some debug code to see where they are by checking their .Left and .Top properties, and this is what I found:
In the designer the 3 picturebox controls (in a control array) I use as containers all are set to .Left = 120 & .Top = 440
When I check their locations in the Form_Load event, before I interact with the tab control, it shows:
Tab0: Left 120 Top 440
Tab1: Left -74880 Top 440
Tab2: Left -74880 Top 440
I then interact with the control by setting tab captions, and then in code select the tab selected on last program close. For simplicity I have used the sequential 0-1-2 order here, but the results are logically the same no matter which tab I start with, it always starts with same values as in the designer.
So when the tab control first show, the selected visible tab has the correct values:
Tab 0: Left 120 Top 440
I then click on the 2nd tab and it has now changed to:
Tab 1: Left-8583 Top 483
Same when I click on the 3rd tab:
Tab 2: Left-8583 Top 483
I now click again on the first tab and look, it has changed position of the container as well, although it was correct to begin with:
Tab 0: Left 134 Top 483
These values then remains the same if go back and forth between the tabs.
I can work around this by positioning the containers in my code, but even if I do this in the Form_Load event values of
Tab 1: Left-8583 Top 483
Tab 2: Left-8583 Top 483
Tab 0: Left 134 Top 483
comes back. So I have to do this later. To do it in the _TabSelChange() event works, although not optimal, but for now it's OK while I'm still coding ahead of release.
Last time it worked by removing the containers, delete the tab control and site a new one, pasting back the containers (to cut and paste back the tab doesn't work in any way) but I will wait with that to see if I somehow can figure out what the problem is. The form itself is >400k and also contains a commercial control (UniSuitePlus) as well as some of my own controls, so I'm hesitant to that sending you the form would be of much help. Also, I cannot exclude that the problem is caused by something in my code or any of the other controls sited on the form.
One thing is odd though, even when I put in my workaround to get the containers correctly placed, there is still an artifact on the 1st tab (tab(0)), a horizontal line just below the tabs and I suspect it's the container top border that is leaking through even if container BorderStyle = 0 - None and Apperance = 0 - Flat
If this info brings some light to your thinking, great and I'm prepared to produce whatever info you may need, otherwise, don't let it trouble you, not yet ;-) I will try to investigate more as time allows, an din worst case I can always recreate the control instance as last measure before I complete my program.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Some more info, I now concluded that the change from -74880 set of values to the -8583 set happens somewhere between Form_Load() and Form_Activate(), meaning they have changed when checked in the latter event. I don't have the order of form events in my head, so not sure if there is an even in between or not, but too tired to check any further right now.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Ok that didn't work, sleep I mean... but think I'm closer to solving the mystery. It appears the whole thing with trowing the containers a hard left jab happens in the Form_Resize event, even though I have no code there - except for debug code now. However, I do have a resizer control on the form that resize controls proportionally on form resize and I suspect that it at least play a part in this. Question is though why it plays havoc with controls placed on SSTabEx and and not other container controls? "It takes two to tango" so to speak, so even if it plays a part, I suspect there may be some "weakness" in SSTabEx's container walls allowing (or even inviting) this to happen. But frankly I don't know and now it's too late to get any further with this.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
7edm
However, I do have a resizer control on the form that resize controls proportionally on form resize and I suspect that it at least play a part in this.
That's a very probable cause.
The SStab, and also the SSTaEx hides the controls that are not in the current tab by positioning them .Left - 75000
These resize controls usually changes sizes and position of controls to fit a new window size.
The control may be ready to handle SStab, but not SSTabEx because it doesn't know about it.
On the other hand (probably unrelated), I suggest if possible to use the SStabEx compiled into an OCX to avoid problems.
If there are bugs, I can investigate and work to fix them, but I need first to be able to reporduce the situation.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
Eduardo-
The control may be ready to handle SStab, but not SSTabEx because it doesn't know about it.
One thing I would try is to change the base name (of type name) of the control from SSTabEx to SSTab to see if the resize control handles it right.
But first I would remove the resize control to see if that's the cause or not.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
It was too late yesterday to think of that simple thing, and actually was the first thing popping my mind as I woke up today - remove the resizer and we have the answer and yes I can confirm that is the problem. Removing it, all is fine, putting it back and the problem is back. Strange though how it first worked for several runs, then problem first time. I remove and recreate the SSTabEx on the form and it works again for some time while I work, make changes, even added another tab and its container, still ran fine and then suddenly...
Anyhow, the good thing here is that the resizer is actually my own control I created a few years ago by merging together some work/ideas from PSC and added my own thoughts to it to get what I wanted/needed. I just don't have it setup to run in IDE mode currently as I finished my testing and have just used the compiled OCX. I guess I will have to bring it back in to find out what's happening and adjust it.
I'm glad the problem as such wasn't in SSTabEx though, although it kind of was with the way it hides the tab containers. Didn't realize that was the case as I haven't looked closer at the SSTabEx code, but obviously it trips up my resizer. Just another challenge to face and thanks for your fast reply.
BTW I do SStabEx compiled into an OCX, in fact it lives in the OCX together with other of my own or modified controls for the sole use of my own programs.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
In the last version the shift to the left to hide controls is no more fixed in -75000, now to handle very high DPI settings (above 300 DPI) it is dynamic, I mean, it changes with the DPI setting.
This is transparent for normal operations, but if you want to know the actual Left of the controls you can no more just add 75000 twips.
If you want to know this value, it is now not exposed in the current version but you can add the property in the SSTabEx code:
Code:
Public Property Get LeftShiftToHide() As Long
LeftShiftToHide = mLeftShiftToHide
End Property
Or, I could add a couple of methods to set and retrieve the Left of any contained control, regardless it is visible or not.
If you or anyone else need that, I'll do it.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Ok, this is the new code, I'll add it in the next update:
Code:
Public Property Get LeftShiftToHide() As Long
LeftShiftToHide = mLeftShiftToHide
End Property
Public Property Let ContainedControlLeft(ByVal ControlName As String, Left As Single)
Dim iCtl As Control
Dim iFound As Boolean
ControlName = LCase$(ControlName)
For Each iCtl In UserControl.ContainedControls
If LCase$(iCtl.Name) = ControlName Then
iFound = True
Exit For
End If
Next
If Not iFound Then
RaiseError 1501, , "Control not found."
Else
If iCtl.Left < -mLeftThresholdHided Then
iCtl.Left = Left - mLeftShiftToHide
Else
iCtl.Left = Left
End If
End If
End Property
Public Property Get ContainedControlLeft(ByVal ControlName As String) As Single
Dim iCtl As Control
Dim iFound As Boolean
ControlName = LCase$(ControlName)
For Each iCtl In UserControl.ContainedControls
If LCase$(iCtl.Name) = ControlName Then
iFound = True
Exit For
End If
Next
If Not iFound Then
RaiseError 1501, , "Control not found."
Else
If iCtl.Left < -mLeftThresholdHided Then
ContainedControlLeft = iCtl.Left + mLeftShiftToHide
Else
ContainedControlLeft = iCtl.Left
End If
End If
End Property
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Thanks Eduardo,
I have now setup my project as a group with both my resizer control and the SSTabEx control to have a closer look at what's happening. It's 2-3 years since I completed my resizer though and haven't looked at it since, so will probably take me some time to refresh my memory of what the code actually is doing and where... I'll be back when I know more.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Eduardo, I just realized that I am using the 28 April release and that you actually done 2 updates since, so I will start out with doing that update and see what the result is. However, looking at the code changes in my file comparison app I notice that you are changing many numeric variables from type Long to Integer, may I ask why? I already noticed that you often use the Integer type where I normally would go for Long as well Integer is 16-bit and kind of Windows 3.x
The only (legit) reason I can see is if you want it to be a 100% drop-in replacement of SSTab, although I would probably still keep the use of Integer type to a minimum, limited to the public interfaces and internally converting input/output between Long and Integer. Personally, I don't find the idea of 100% drop-in compatibility that useful and would gladly make smaller changes to some of my code (like variable types) to get a much better end result - after all there is usually a reason why you want to change from something old to something new, right. Anyway, just some thoughts.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
7edm
looking at the code changes in my file comparison app I notice that you are changing many numeric variables from type Long to Integer, may I ask why?
I changed the API declaration for ColorRGBToHLS and ColorHLSToRGB APIs from Long to Integer, because although it worked, it were wrong. I changed them to avoid any possible issues that could araise from these wrong declarations.
That led me to also change variables declarations that iteract with those APIs.
Quote:
Originally Posted by
7edm
I already noticed that you often use the Integer type where I normally would go for Long as well Integer is 16-bit and kind of Windows 3.x
The only (legit) reason I can see is if you want it to be a 100% drop-in replacement of SSTab, although I would probably still keep the use of Integer type to a minimum, limited to the public interfaces and internally converting input/output between Long and Integer.
Yes, that's the reason, full backward compatibility with the SSTab.
Internal use sometimes is to avoid performing so many conversions.
Quote:
Originally Posted by
7edm
Personally, I don't find the idea of 100% drop-in compatibility that useful and would gladly make smaller changes to some of my code (like variable types)
I prefer to have drop in compatibility, and the speed gain that you propose IMO would be negligible.
Quote:
Originally Posted by
7edm
to get a much better end result
I don't think that changing Integer to Long could have any noticiable impact, just some few nanoseconds on operations that are not so frequent to have any impact IMO.
You are free to make any changes that you want, but I don't think it worth. Unless you care that for example, when the user clicks a tab, it responds let's say 10 nanoseconds faster.
It would be good to make a test sample, one with Longs and other with Integers, and to measure how much faster it performs. Still, there is any intensive operation in the SSTabEx to care (or measure).
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Eduardo,
you might be right of the negligent speed advantage with Integer vs Long, although for me it's also about coding style and convention, same goes with the use of GoSub and GoTo (except for in error handlers with the latter), but peace, I'm not gonna spend time here on such issues, nor do I intend to change anything in your code as long as I don't have a deeper understanding of what it does across the project. I was merely curious to know more about your thinking and I think it's a blessing that you have taken up and realized this project. Great work!
Now to real issues. I upgraded your control to use the latest code and run into a problem, and this time my resizer control isn't involved, meaning, it's in the toolbox but not seated on the form. What happens is that when ever I click on any of the tabs, the first tab (index=0) is always selected. Like if on Form_Load I assign SSTabEx.TabSel = 0, clicking any of the other tabs has no effect, it's "locked/fixed" on tab0. However, if I assign SSTabEx.TabSel = 1 that tab is initially shown, but as soon as I click on any tab, 2, or 0, tab0 is selected and then it's not able to change to any of the other tabs.
I tried to debug what happens after having set a break in SSTabEx the project simply didn't want to run, same if I start with F8 the first thing to open is SSTabEx.UserControl.WriteProperties() event and then it dies on the first line of code. So I really don't know more at this stage, and I am sorry if I bring you worries.
Anyway, I went back to the old version and all works fine again, except for the interaction with my resizer control. So I will first focus on figure that out, probably by setting up a smaller test project to cut down on the potential of 3rd factors interacting.
Oh btw, I did one change. I saw you run the SSTabEx project with the "Single-Threaded" threading model, and I have changed that to "Apartment-Threaded" as I think that's the VB default and what all other of my controls use. But just out of curiosity, is there any special reason you choose to run it single-threaded?
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
7edm
Oh btw, I did one change. I saw you run the SSTabEx project with the "Single-Threaded" threading model, and I have changed that to "Apartment-Threaded" as I think that's the VB default and what all other of my controls use. But just out of curiosity, is there any special reason you choose to run it single-threaded?
I really don't know how that setting changed, I don't remember I made that change on purpose. Perhaps I was testing something and I forgot it that way.
Quote:
Originally Posted by
7edm
Now to real issues. I upgraded your control to use the latest code and run into a problem, and this time my resizer control isn't involved, meaning, it's in the toolbox but not seated on the form. What happens is that when ever I click on any of the tabs, the first tab (index=0) is always selected. Like if on Form_Load I assign SSTabEx.TabSel = 0, clicking any of the other tabs has no effect, it's "locked/fixed" on tab0. However, if I assign SSTabEx.TabSel = 1 that tab is initially shown, but as soon as I click on any tab, 2, or 0, tab0 is selected and then it's not able to change to any of the other tabs.
I tried to debug what happens after having set a break in SSTabEx the project simply didn't want to run, same if I start with F8 the first thing to open is SSTabEx.UserControl.WriteProperties() event and then it dies on the first line of code. So I really don't know more at this stage, and I am sorry if I bring you worries.
Anyway, I went back to the old version and all works fine again, except for the interaction with my resizer control. So I will first focus on figure that out, probably by setting up a smaller test project to cut down on the potential of 3rd factors interacting.
I have no idea because I just downloaded the project and it works for me.
Without being able to reproduce the problem I can't do or say anything.
Quote:
Originally Posted by
7edm
you might be right of the negligent speed advantage with Integer vs Long, although for me it's also about coding style and convention, same goes with the use of GoSub and GoTo (except for in error handlers with the latter), but peace, I'm not gonna spend time here on such issues, nor do I intend to change anything in your code as long as I don't have a deeper understanding of what it does across the project. I was merely curious to know more about your thinking and I think it's a blessing that you have taken up and realized this project. Great work!
If you want to know my thinking, it is:
I think that some things are justified and other are extreme positions where programmers limit themselves but are not always justified (rationally).
About using always Long type intead of Integer (or other types):
It is important on time consuming processes, when they can introduce noticiable delays because they are in long running loops, or something like that.
Still, if I have to choose, I always choose Long, unless I have a reason to use other types and when I think it will have no practical impact.
About GoTo and GoSub:
I know there is a thinking out there that Goto is evil, and never to use it.
Well, you are limiting yourself. Sometimes a GoTo is the perfect option.
Try to avoid it, do not use it as something normal, but in some cases it is a solution, and the code is still easier to follow than the big mess that you would have to do, to perform the task without any GoTo.
If you want to write perfect structured rountines, then never use Exit Sub, Exit For, Exit Do, anything like that, either.
Do you see much difference between an Exit Sub and a GoTo Exit_Sub (where you can do something before exiting the process)?
Same about GoSub. Try to avoid it, but sometimes it is a solution when you need to make some repetitive task inside a procedure that uses many local variables. Otherwise you would have to make another procedure and pass all those variables, just to avoid a Gosub. And why? Because it is a extreme view. It is not rational for me to complicate things so much just to follow a rule that someone stated and other spreaded everywhere.
Still, as I said, try to avoid it, do not use it normally.
There are other rules out there.
Like the one: never, ever use DoEvents, it is evil.
Not true. It is dangerous, yes, you have to think very well what could happend in the middle. The world after DoEvent might be very different of the world before it, but if you handle the possible scenarios right, there is no problem. And it allows to do some things that otherwise would be very difficult or even impossible in VB6, that is single theaded.
Also, try to avoid it all possible, and when you put a DoEvent think very well what could have happened after it returns.
There are also some other options, like using PeekMessage that soometimes can be used intead of DoEvents, a bit less dangerous.
Never use On Error Resume Next, another one.
Do not use that indiscriminately, and set the error control again as soon as you are done (most of the times after one line), but it is a practical solution for many cases.
I think may be more like these, but I don't remember another one now.
That's my thinking.
Of course, there are also some justified:
Never use End.
Yes, that's justified I think.
But I would not say: never use End, intead: using End should be never the solution.
PS: in other words: the rules should be understood, and not to follow rules blindy because someone said it (or because you fear to be doing something wrong).
But when you don't understand some rule, then better follow it, you'lll be safer.
This is programming, you are not breaking the law, either a commandment.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Thanks for sharing your thoughts Eduardo, appreciated. We humans are complex beings and what makes perfectly sense to some, may appear as nonsense (or something else) to others. Personally, I like to take an approach of consistency and simplicity, but of course make an exception where it makes sense (in my mind). You are technically right about GoTo, my sticking point though is that it invites to bad habits and temporary solutions (that by time tend to become permanent) that eventually tends to stack up causing complexities that is both hard to understand and to debug, when need arises. Although a relatively mild example from your code, I would never choose this solution:
Code:
Set iControls = UserControl.Parent.Controls
If iControls Is Nothing Then GoTo Exit_Function
For Each iCtl In iControls
Set iContainer_Prev = Nothing
Set iContainer = Nothing
Set iContainer = iCtl.Container
Do Until iContainer Is Nothing
If iContainer Is nContainer Then
GetContainedControlsInControlContainer.Add iCtl
End If
Set iContainer_Prev = iContainer
Set iContainer = Nothing
Set iContainer = iContainer_Prev.Container
Loop
Next
Exit_Function:
Err.Clear
but like this:
Code:
Set iControls = UserControl.Parent.Controls
If Not iControls Is Nothing Then
For Each iCtl In iControls
Set iContainer_Prev = Nothing
Set iContainer = Nothing
Set iContainer = iCtl.Container
Do Until iContainer Is Nothing
If iContainer Is nContainer Then
GetContainedControlsInControlContainer.Add iCtl
End If
Set iContainer_Prev = iContainer
Set iContainer = Nothing
Set iContainer = iContainer_Prev.Container
Loop
Next
End If
Err.Clear
Anyway, I think I have figured out what the problem is with SSTabEx vs my Resizer control, although I haven't looked in detail what exactly is taking place, just out of how you explained it above.
When proportional resizing takes place it will change the .Left value of each control, with the result that it will differ from what your control expect it to be, causing the end result to be wrong. However, my control can also do anchored resizing, which should work as long as the tabs container control is anchored to the same side as it's moved into hide. Problem though, I just found a bug that has slipped my eyes, and once that is fixed it "should" work and if not I will have to look deeper.
Any special reason to .Move the containers out of view rater than just setting its .Visible property, speed, flicker etc.?
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
7edm
Any special reason to .Move the containers out of view rater than just setting its .Visible property, speed, flicker etc.?
Yes.
1) Backward compatibility with existing code that used the original SSTab (and stored properties).
2) Not to mess with the Visible property, that the programmer could have used (or want to use) to show/hide controls. I think that must have been the reason why the original developers of the SStab did that way.
When the host program changes the .Left of a control that is hidden (shifted to the left), the SSTabEx has implemented a way to place it in the right tab anyway. In case of controls that are windows and thus can be subclassed, that is done at the moment, in case of windowless controls, they are handled when the tab changes (it is not possible to know that a label changed place, perhaps only executing a lot of code on every form paint, but that doesn't seem something reasonable to do).
In sum: the SSTabEx has better handling than the SSTab regarding the host program changing control's Left. But still, not perfect.
3) A solution could have been to put the controls into a container, for example a picturebox or a frame, but it is not possible to change the container of a contained control in an UserControl from a container of the host program to one of the component program. I tried, it raises an error.
Any suggestion can be considered, now I don't have an alternative.
Note: Now I remember that I saw some tab control that said it used containers to hide the controls, but I don't remember now where it was. I think it was some old commercial control. Perhaps it worked only with windowed controls and set the parent with the SetParent API.
About your resizer program, test for the TypeName of the control's container, and when it is "SSTabEx", then use ctl.Container.ContainedControlLeft(ctl.Left) instead of ctl.Left. (Add the code, it is on post #47, but you need to be using the latest version)
Did you have code in the resizer to handle the SSTab? How?
About the routine with GoTo Exit_Function that you quoted, it surely won't win any beauty contest, but I don't see a functional problem with it.
If I had made it from the start, surely I would had made it as you suggested, but when I had the control already written and working, I realized that I was leaving the Err object with some errors set in some parts. It wouldn't be a problem most of the times, but I thought better not to leave them because when the control is used in source code, the host program shares the same Err object, and if the host program is checking for errors, it could lead to a false positive.
Then I looked for the places where Exit Sub/Function's where inside an error handling and quicky changed them to GoTo Exit_Sub/Function, added that label, and cleared the Err object at the end before exiting. Without having to resort to adding flags and more code.
That specific case that you quoted could have been resolved without adding a flag, but I replaced all the same way without studing each one in detail.
About picking up bad habits, yes, if you can't control yourself or you are a beginner then you better abide by the rules and never break any.
I know it is not only about beginners, but I don't want to start a war (many here will agree with your view).
They are all good rules, I encourage to follow them... the 99% of the times.
When I code, I am very focused on what I'm doing and don't want to add the burden of "someone won't like it". I'm not saying I don't care or I don't consider that, but I don't like to spend much time on these things.
Anyway I read objections, and I can change things when someone express reasons that I see valid.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
I understand, as SSTabEx is labeled as a replacement, that you like to give priority to keeping it 100% backwards compatible. I have no objections to that. Still, SStab is an old control (one may even argue an unmodern one) and breaking some of that backward compatibility, still building on the base, may not be a totally bad or even unwelcome idea. Not trying to urge you doing this though, as I am just interested in getting it to work with my resizer or resizing in general as I think that probably presents a problem for it. So thinking of how to best accomplish this, and maybe a fork would be a way to go. For the moment only analyzing the situation though, but I need it to work with resizing.
Quote:
Originally Posted by
Eduardo-
3) A solution could have been to put the controls into a container, for example a picturebox or a frame, but it is not possible to change the container of a contained control in an UserControl from a container of the host program to one of the component program. I tried, it raises an error.
Any suggestion can be considered, now I don't have an alternative.
Things that have crossed my mind are that maybe a better solution would be if the control handled the resizing of it's containers itself, and even provided the container for each tab where to site controls. Is this what you tried to do with a picturebox but it didn't work? I know that siting an UC on another UC container control presents a problem as the contained UC's Ambient.UserMode is set to 'True' causing it to behave as in run mode. A picturebox (as a control array matching tabs) shouldn't present the same problem - theoretically - while the practical implementation may present other challenges I'm not aware of at this point.
Anyway, I have now setup a test project to have a closer look on these things. I haven't made my resizer SSTabEx aware so far, as using TypeOf I think require SSTabEx to be referenced in my Resizer project, and it's really its container (a picturebox in this case) I need to deal with. It's possible I have to rethink how I structure the handling of controls in my resizer. But again, maybe the resizing (at least of the main container) would be best handled directly in SSTabEx. I have to put the brilliance of my mind to it! :)
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
7edm
A picturebox (as a control array matching tabs) shouldn't present the same problem - theoretically - while the practical implementation may present other challenges I'm not aware of at this point.
There is *no* other practical approach to tabbed UI, incl. SSTab/SSTabEx. You just *have* to place controls in a "tab container" which will be shown only when it's designated tab becomes current. Otherwise, relying only on SSTab's Left shenanigans, the end-user will be able to focus controls on "non-current" tabs using TAB/Shift+TAB keys which will no doubt become a non-stop stream of support calls. Ouch!
Let me reiterate -- no one writing production code will use SSTab control without container-per-tab + manual hide/show on tab click. At this point, arriving at the PictureBox control array, one has to ask themsleves how hard it is to migrate to themed TabStrip control and be welcome to the new century of OS provided bells and whistles?
cheers,
</wqw>
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
wqweto
relying only on SSTab's Left shenanigans, the end-user will be able to focus controls on "non-current" tabs using TAB/Shift+TAB keys which will no doubt become a non-stop stream of support calls. Ouch!
That was a problem in the SSTab, but in the SStabEx I already fixed that. I set the TabStop property of the hidden (shifted to the left) contained controls to False, and restore to its original setting once they are in the current tab.
Quote:
Originally Posted by
wqweto
Let me reiterate -- no one writing production code will use SSTab control without container-per-tab + manual hide/show on tab click. At this point, arriving at the PictureBox control array, one has to ask themsleves how hard it is to migrate to themed TabStrip control and be welcome to the new century of OS provided bells and whistles?
cheers,
</wqw>
There will be little gain, since the SStabEx is already themed.
And ther are are things to loose, since the VB6's TabStrip is not a control container.
BTW, the .Net's TabStrip is a control container, like the SStab and unlike VB6's TabStrip.
For me, being control container, is the main advantage of the SStab. Mainly to be able to have the controls ordered and easily visible at design time, I never liked the TabStrip for that reason.
If you have a large form with several tabs, it is impossible to place all the tab-containers on the form without overlapping each other. It is very cumbersome IMO.
The main dissavantage of the original SSTab was that it was not themed. It is fixed now here.
Also, the TabStrip can show the tabs stretching their widths to fill all the control width. Setting the SSTabEx with Style set to ssStyleTabStrip does that.
So, in regard to look and behavior at run time, there are little difference between the SStabEx and the TabStrip.
The only thing I didn't implement was:
The TabStrip, when all the tabs do not fit on the control's width, the TabStrip has the option to show more than one row of tabs, or to show a little arrows at the end to let the user navigate to the non visible tabs by clicking them.
I didn't implement the second option (at least for now) in the SSTabEx, so the only option is to show more than one row of tabs.
I didn't do it because I never used and maybe I don't like it. I think the user might not figure that he must click there to show more tabs.
I've implemented other things that sometimes are needed, like being able to change its background color (only works when it is not themed, of course).
To move controls from one tab to another (it can be done in a property page).
Another thing that the SStab has and the TabStrip lacks is to be able to have the tabs in other place than the top. Sometimes I use the tabs at the bottom.
So, there isn't many advantages to list of the TabStrip, could you list some?
-
1 Attachment(s)
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Quote:
Originally Posted by
7edm
I understand, as SSTabEx is labeled as a replacement, that you like to give priority to keeping it 100% backwards compatible. I have no objections to that. Still, SStab is an old control (one may even argue an unmodern one) and breaking some of that backward compatibility, still building on the base, may not be a totally bad or even unwelcome idea. Not trying to urge you doing this though,
Doing exactly what are you talking about?
Quote:
Originally Posted by
7edm
as I am just interested in getting it to work with my resizer or resizing in general as I think that probably presents a problem for it. So thinking of how to best accomplish this, and maybe a fork would be a way to go. For the moment only analyzing the situation though, but I need it to work with resizing.
Does your resizer already handle the SStab? How? (post code)
Quote:
Originally Posted by
7edm
Things that have crossed my mind are that maybe a better solution would be if the control handled the resizing of it's containers itself, and even provided the container for each tab where to site controls.
I'm not going to do a resizer control, not inside the SSTabEx and improbably in other specific control.
I think that having these resizers, most of the times is a wrong concept.
There is no point on making a button bigger because the form was resized, at least not following the form's size, I mean: it can be a couple of steps where you take advantage of the available space to make things more readable, but that's it.
IMO when a form changes size, you need to think the logic of what to do in the available space (smaller or larger that the "normal") for each form particularly, and that would hardly be something that could be automated for every case in a control. Making everything to resize accordingly to the form's size is a wrong approach IMO (and the opinion of many others).
Quote:
Originally Posted by
7edm
Is this what you tried to do with a picturebox but it didn't work? I know that siting an UC on another UC container control presents a problem as the contained UC's Ambient.UserMode is set to 'True' causing it to behave as in run mode. A picturebox (as a control array matching tabs) shouldn't present the same problem - theoretically - while the practical implementation may present other challenges I'm not aware of at this point.
No, the problem is not that.
I mean error 425 (Invalid object use).
See the attached test project.
Quote:
Originally Posted by
7edm
Anyway, I have now setup a test project to have a closer look on these things. I haven't made my resizer SSTabEx aware so far, as using TypeOf I think require SSTabEx to be referenced in my Resizer project, and it's really its container (a picturebox in this case) I need to deal with. It's possible I have to rethink how I structure the handling of controls in my resizer. But again, maybe the resizing (at least of the main container) would be best handled directly in SSTabEx. I have to put the brilliance of my mind to it! :)
Do not use TypeOf, but TypeName (Control). With that you don't need an early-binding reference.
Quote:
Originally Posted by
Eduardo-
About your resizer program, test for the TypeName of the control's container, and when it is "SSTabEx", then use ctl.Container.ContainedControlLeft(ctl.Left) instead of ctl.Left. (Add the code, it is on post #47, but you need to be using the latest version)
If the resizer code is not too complex, post it.
Or, you can use this code in the host program to position the containers:
Code:
Private Sub Form_Load()
Dim c As Long
For c = 0 To picContainer.UBound
picContainer(c).Move SSTabEx1.TabBodyLeft, SSTabEx1.TabBodyTop
Next
End Sub
Private Sub SSTabEx1_Click(PreviousTab As Integer)
picContainer(SSTabEx1.TabSel).Move SSTabEx1.TabBodyLeft, SSTabEx1.TabBodyTop
End Sub
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Updated.
2020-09-02 Added properties ContainedControlLeft and LeftShiftToHide.
2020-09-02 TabBodyLeft, TabBodyTop, TabBodyWidth, TabBodyHeight now return the value in Twips (regardless of the SStabEx's container ScaleMode), that is what the SSTabEx's contained controls use.
-
Re: (VB6) SSTabEx: SSTab replacement. Themed and with new features
Eduardo,
good news, I was able to update SSTabEx to your latest version (from today) - and it works! also with my resizer control, in my test project so far only. Will test and check some bit before I switch over to apply it on my main project. The solution was actually quite simple, and already available - to use anchored resizing rather than proportional. I think this is why I have it working originally, but then it crashed and I had to remove and put back SSTabEx as well as resizer, and it was coded to use proportional resizing by default. I never thought of this and when I checked my Subversion logs I see I completed the control back in 2015 and haven't looked at the code since, just used it.
Anyway, this means I am up and running again! I will try to come back later and respond to your questions/statements above, when I have more time. Just one thing about GoTo :-) I think your changes like:
Code:
If iControls Is Nothing Then GoTo Exit_Sub
....
Exit_Sub:
Err.Clear
are redundant really, as VB automatically fires Err.Clear on any 'Exit Sub', 'Exit Function' and 'Exit Property' call.
Also, I was wondering over this, what do you like to accomplish with this code:
Code:
iTiUsr = -1
iTiUsr = UserControl.Extender.TabIndex
If iTiUsr = -1 Then Exit Sub
from what I understand, iTiUsr can never get a value of -1 here, thus what you are trying to address will never happen i.e. Exit Sub gets called.
Also, let me fill in, the shortcomings of the TabStrip control is what lead me here. The ability to site your controls inside the tab at design time is worth so much, so let me just say that the work you are doing here is of great importance!