# VBForums CodeBank > CodeBank - Visual Basic 6 and earlier >  (VB6) SSTabEx: SSTab replacement. Themed and with new features

## Eduardo-

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 themesThe 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 availableMore 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:


Not themed but TabBackColor changed (and also Style = ssStyleTabStrip):


*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. 


Read the help documentation online.



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.

----------


## 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:


```
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
```

----------


## Eduardo-

> 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:
> 
> 
> ```
> With UserControl
> ...


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:



> 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.

----------


## Krool

> 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.

----------


## Eduardo-

> 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.

----------


## 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.

----------


## Eduardo-

> 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.

----------


## Eduardo-

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.

----------


## Elroy

Nice work, Eduardo.   :Smilie:   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  :Smilie:

----------


## Eduardo-

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*.

----------


## Eduardo-

Hello 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.




> 2. In the UserControl_Resize handler you shall do a following to correct the sizes VB reports from the host:
> 
> 
> ```
> 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
> ...


I still didn't study that...
Thanks.

----------


## Maurizio

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

----------


## DEXWERX

> 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.  :Wink: 

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.

----------


## Eduardo-

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".

----------


## xxdoc123

> This control is a direct replacement of the SSTab control.
> 
> Some enhancements are:
> 
> It supports Windows visual styles or themesThe 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 availableMore 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
> 
> 
> ...




```
 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
```

----------


## Eduardo-

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.

----------


## Bobbles

> 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.

----------


## Eduardo-

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.

----------


## Eduardo-

Updated.

_A small bug fixed (in the highlight effect)._

----------


## Elroy

> 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

----------


## KenHorse

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.

----------


## Eduardo-

> 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.

----------


## KenHorse

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

----------


## KenHorse

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

----------


## Eduardo-

> 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)

----------


## 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?

----------


## KenHorse

Nevermind I figured it out

----------


## Eduardo-

> 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.
> ...


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.

----------


## KenHorse

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'......

----------


## Eduardo-

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?

----------


## KenHorse

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

----------


## Eduardo-

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.

----------


## 7edm

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.

 

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:


```
tabChartEntry.TabSel = CInt(GetIniVal(INICHT, "EntryMode", "0", sIniFile))
```

to this 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...

----------


## Eduardo-

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.

----------


## 7edm

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.

----------


## ln_0

Changes to menu toolbar style
Attachment 178157

ctlSSTabEx Toolbar.zip

----------


## Eduardo-

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.

----------


## Eduardo-

Updated the download in the OP.
Added fix to support high-DPI above 300.

----------


## Eduardo-

Fixed a bug introduced in the last update.

----------


## 7edm

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.

----------


## 7edm

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.

----------


## 7edm

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.

----------


## Eduardo-

> 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.

----------


## 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.

----------


## 7edm

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.

----------


## Eduardo-

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:



```
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.

----------


## Eduardo-

Ok, this is the new code, I'll add it in the next update:



```
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
```

----------


## 7edm

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.

----------


## 7edm

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.

----------


## Eduardo-

> 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.




> 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.




> 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.




> 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).

----------


## 7edm

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?

----------


## Eduardo-

> 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.




> 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.




> 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.

----------


## 7edm

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:


```
    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:


```
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.?

----------


## Eduardo-

> 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.

----------


## 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, 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.




> 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!  :Smilie:

----------


## wqweto

> 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>

----------


## Eduardo-

> 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.




> 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?

----------


## Eduardo-

> 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?




> 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)




> 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).




> 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.




> 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.




> 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:


```
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
```

----------


## Eduardo-

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.

----------


## 7edm

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:


```
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:


```
    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!

----------


## Eduardo-

> 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.


It works exactly as it worked before, there is no change that could affect you (and the resizer).




> 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 thought we were already clear that the problem is in your resizer and not in the SStabEx.




> 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:
> 
> 
> ```
> If iControls Is Nothing Then GoTo Exit_Sub
> ....
> 
> Exit_Sub:
>     Err.Clear
> ...


Wrong, and easy to test:


```
Private Sub Form_Load()
    AAA
    Debug.Print Err.Number
End Sub

Private Sub AAA()
    On Error Resume Next
    Debug.Print 1 / 0
End Sub
```

When there is an On Error GoTo 0 before leaving it clears the Err object, otherwise the error is left.




> Also, I was wondering over this, what do you like to accomplish with this 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.


If someone changes the CanGetFocus property of the UserControl, then there is not TabIndex property in the Extender.




> 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!


I always used the SStab instead of the TabStrip for the same reason.
And for the ones that say that it looks old because of the 3D look, they have the option to set Style to ssStylePropertyPage and it looks like the TabStrip.
But a problem arose with the original: it does not apply Windows visual styles.

----------


## 7edm

Hi Eduardo, it's me again.
While I was able to solve my original problem discussed above, I have now run into another one.

I have a UniSuitePro Listbox on the first tab as part of a controlarray, which gets loaded with records during start of the form. In Code I then set .ListIndex = 0 to triggers the ListIndexChange event that runs this code:


```
Private Sub lstChartsOnFile_ListIndexChange(Index As Integer)


Dim bHasSelection As Boolean

With lstChartsOnFile(Index)
  bHasSelection = CBool(.ListIndex > -1)
  If Index = 0 Then
     If bHasSelection Then
        mLastChartID = .ItemItemData(.ListIndex)
         Set mEditChart = GetChartByIdFromDb(mLastChartID)
     End If
     tabCM.TabEnabled(1) = bHasSelection
     cmdDelete.Enabled = bHasSelection
     cmdDelete2.Enabled = bHasSelection 'button outside of SSTabEx for referense
     cmdLoad(0).Enabled = bHasSelection
     cmdLoad(1).Enabled = bHasSelection
  End If

End With


End Sub
```

The code above is triggered as should at startup and works perfectly fine;
The first list item is select  and bHasSelection is set to True,
the mLastChartID variable is asigned a Long from the list items itemdata property
and is the used to fetch a data set from my Sqllite database, which is assigned to a class.

So far all well, and also next operations works as it should in code, the .Enabled property is set to the value in bHasSelection (which is True, I debug.print checked this)
I also debug.print checked that the properties really had a value of True, so so far all is as it should, but...

When the form shows, the List item is not really selected, but is "highlighted" with a light grey stripe, not the blue highlighting it get when clicked on, and furthermore, the buttons are shown in its .Enabled = False state. 

To check if this was a SSTabEx issue or not, I placed another button on the form, outside of SSTabEx as a reference (cmdDelete2 in the code) and it gets enabled as it should, and as the other buttons should have been as well. 

So something happens there that shouldn't, and my intuition tells me that it might have to do with subclassing, either in UniSuitePro listbox or in SSTabEx, or possibly in both. 
If I click on any row in the listbox, the item gets selected as it should (blue highlighting) and the buttons are all set to correct .Enabled state.

Any idea if there is anything that can be done about this? I still haven't had time to look closer on the SSTabEx code as I been too busy with getting my own code working.

----------


## Eduardo-

Do you mean "UniSuitePlus" from CyberActiveX?

----------


## 7edm

yes that's correct.

----------


## Eduardo-

If you can provide a test sample project it would be great

----------


## 7edm

I will try to do that later when I have a bit more time. The issue is not fatal as all works once the user click an item in the list. It just doesn't get selected from the preset value assigned by code on load, or refill of list, as intended. So I can live with it for now while I complete other things.

----------


## Eduardo-

> I will try to do that later when I have a bit more time. The issue is not fatal as all works once the user click an item in the list. It just doesn't get selected from the preset value assigned by code on load, or refill of list, as intended. So I can live with it for now while I complete other things.


I don't figure something of the SStabEx control that could cause that anyway.
Please, for any future possible bug reports, it must be accompanied by a test project.

----------


## Eduardo-

Updated! 
Some bugs fixed:

2021-01-17 Fixed bug in WM_WINDOWPOSCHANGING message for non-integer DPI settings (when windowed controls' lefts in hidden tabs are set at run-time).
2021-01-16 Fixed bug in ContainedControlLeft property, not it can handle controls from control arrays.
2021-01-16 Fixed bug in default TabSelBackColor and TabSelForeColor when upgrading from a previous version of SSTabEx that didn't have these properties, that happens when the values of TabBackColor/ForeColor properties are not set to their default settings.

----------


## xiaoyao

very good,i need study more days ,thank you

----------


## jedifuk

really really nice sstab replacemnet, i am using this for my application currently working for point of sales,
will add credit to Mr. Eduardo

----------


## Erwin69

Hi Eduardo,

As part of updating my VB6 application to support Unicode, I implemented your SSTabEx work.

In short: smooth, no problems, so **GREA*T* stuff!  (And I have only done the basic conversion at this point.  The ability to change the order of the tabs, or moving all controls from one tab to another would have saved me quite some time in the past...)  Thank you very much to share it with the world!!!

One thing I noticed though:

My app applies a translation to all controls in a form during the load event.  This works perfectly fine with a SSTabEx-control on a form, but I noticed that when a tab contains another SSTabEx-control, the initial display doesn't display the newly assigned TabCaptions.  Moving the mouse over one of the tabs, immediately refreshes the screen, and shows the proper captions.

Note: this is running the application from the IDE.  I haven't been able yet to check if that's also the case with a final compiled exe.

Not a showstopper, but thought to let you know.

Regards,
Erwin

----------


## Eduardo-

Hello, thank you for your comments.

I'm not able to reproduce the issue. Please check the test project that is attached.

If you can recreate the situation, and we see that it is indeed a bug, I'll check to fix it.
If not, or you realize that it might be some other third party control or something interfering with the paint messages, you could try SStabEx.Refresh and see if that helps.

----------


## Erwin69

Hi Eduardo,

Thanks for the quick feedback.

It works fine with the test you sent.  I tried various alternative scenarios, but couldn't reproduce the problem with your test-app, but the problem is consistent with my app.

The only difference is that my app populates some 50 textboxes, comboboxes, and a few pictureboxes after the controls' captions are given their translation.  Not sure how that interferes with the painting, that's way beyond my knowledge...  :Roll Eyes (Sarcastic): 

Anyway, the good news is that adding a Refresh in the form Activate event solves the problem.

Regards,
Erwin

----------


## Eduardo-

Please, test something:

Remove or comment the Refresh in the form Activate (the current workaround).

In the procedure: 'Private Function ISubclass_WindowProc...'
at: 'Case WM_DRAW', comment or delete the line 'mDrawMessagePosted = False"

Please report back if that fixes the issue.

----------


## Erwin69

No, that didn't fix it.

----------


## Eduardo-

OK, one more shot in the dark:

At the end of 'Private Sub UserControl_Show', you can see:



```
    If Not mFirstDraw Then
        Draw
        mFirstDraw = True
    End If
```

Change that to:



```
    If (Not mFirstDraw) Or mDrawMessagePosted Then
        Draw
        mFirstDraw = True
    End If
```

----------


## Erwin69

Yes, that fixed it.

----------


## Eduardo-

OK, I'll issue an update.

----------


## Eduardo-

Updated.

----------


## Tobyy

Hello @ Eduardo,
Great work you gave the world and i am happy about it so much.
However, i have lost 2 days with issues encountered when i added the SSTAB to my project. When i used the SSTAB as a component, it worked fine and i can compile easily. However, when my users downloaded my software, it keeps complaining the Active X control is not registered. Registering the TabExCtl.ocx on each user system is too cumbersome. Besides i tried it, it registered successfully but i still got an error when the form which uses the SSTAB is launched in the software.
So to avoid all that, i decided to add the User Control directly in the project and i added all other files, property files, BAS, Class Modules but since 2 days now, i keep getting the "Out of Memory" Compile error when i compile my EXE. If i remove the SSTAB forms and compile again, i compile successfully, but if i add the SSTAB and compile, its been giving me "Out of Memory" error.
Meanwhile i can run the program successfully and it works fine. The SSTAB works very fine on the forms when i run program, but i cannot compile for 2 days now and it has driven me nuts.
Please Help.

----------


## wqweto

Just an idea: Before compiling you project right click in your code editor and choose Toggle->Break on All Errors menu option.

This way when you try to compile you project the IDE will break when it encounters an error instead of continuing like nothing happened (On Error Resume Next) and so things go awry as a consequence.

I'm pretty sure the problem here is with control arrays -- it's not possible to use Load statement to add more instances while the project is being compiled and this is a bug in the VB6 environment regarding control arrays that has been discussed in these forums before.

cheers,
</wqw>

----------


## Eduardo-

> Hello @ Eduardo,
> Great work you gave the world and i am happy about it so much.


Hello,
Thank you.




> However, i have lost 2 days with issues encountered when i added the SSTAB to my project. When i used the SSTAB as a component, it worked fine and i can compile easily. However, when my users downloaded my software, it keeps complaining the Active X control is not registered. Registering the TabExCtl.ocx on each user system is too cumbersome. Besides i tried it, it registered successfully but i still got an error when the form which uses the SSTAB is launched in the software.


It is the same with any OCX, it needs to be registered.

From many years to date, I use Side-by-side assemblies (SxS). No registration is required, but it is required a manifest file.




> So to avoid all that, i decided to add the User Control directly in the project and i added all other files, property files, BAS, Class Modules but since 2 days now, i keep getting the "Out of Memory" Compile error when i compile my EXE. If i remove the SSTAB forms and compile again, i compile successfully, but if i add the SSTAB and compile, its been giving me "Out of Memory" error.
> Meanwhile i can run the program successfully and it works fine. The SSTAB works very fine on the forms when i run program, but i cannot compile for 2 days now and it has driven me nuts.
> Please Help.


I'm not able to reproduce the problem. I'm attaching a very simple test program, it compiles fine.
One note: I experienced that if the form designer is open, the IDE hangs when compiling, so the forms need to be be closed.
I didn't investigate it, but it might be (perhaps) because the control is subclassed in the IDE (to enable several features, like the tabs click).
But I don't get the 'out of memory' error.

When you get the out of memory error, can you click on the 'Debug' button and check on what code line it happens?

----------


## yokesee

It works perfectly on Windows 10.
I've been using it for a long time.
Do not try it with a lot of controls or Tabs

regards

----------


## xiaoyao

Can you set the background to be transparent

----------


## Eduardo-

> Can you set the background to be transparent


I added the BackStyle property in the attached project.
Not sure whether to update with this feature in the "official" version.

To set the transparency:
Set VisualStyles property to False.
Set BackStyle property to Opaque.
Change the TabBackColor property to some other color (otherwise the tabs are hard to click if they are transparent, you need to click on their caption texts, because transparent parts do not receive clicks).

Edit: updated, minor optimization

----------


## jedifuk

> I added the BackStyle property in the attached project.
> Not sure whether to update with this feature in the "official" version.
> 
> To set the transparency:
> Set VisualStyles property to False.
> Set BackStyle property to Opaque.
> Change the TabBackColor property to some other color (otherwise the tabs are hard to click if they are transparent, you need to click on their caption texts, because transparent parts do not receive clicks).
> 
> Edit: updated, minor optimization


really nice your sstab, even better than commercial one.

----------


## Tobyy

> Hello,
> Thank you.
> 
> 
> 
> It is the same with any OCX, it needs to be registered.
> 
> From many years to date, I use Side-by-side assemblies (SxS). No registration is required, but it is required a manifest file.
> 
> ...


Thank you so so much.

I had to go back to the documentation, read it again word by word, and added the User Control to my Project directly. Then i had to remove the component used before, pick up the user control afresh and created controls all over again. 

It was tedious but well worth it. Now i can compile fine without any issues again.

Your documentation saved my life.

Thanks !

----------


## xiaoyao

> I added the BackStyle property in the attached project.
> Not sure whether to update with this feature in the "official" version.
> 
> To set the transparency:
> Set VisualStyles property to False.
> Set BackStyle property to Opaque.
> Change the TabBackColor property to some other color (otherwise the tabs are hard to click if they are transparent, you need to click on their caption texts, because transparent parts do not receive clicks).
> 
> Edit: updated, minor optimization


This is too simple, just take a screenshot of the background image or the corresponding area of the whole screen once.
The display image behind the control as a background, simulation of the effect of transparency.

https://www.vbforums.com/showthread....ontrol-For-VB6

Simple transparent button control For VB6
https://www.vbforums.com/showthread....ontrol-For-VB6

----------


## Eduardo-

> really nice your sstab, even better than commercial one.


Thank you.




> Thank you so so much.
> 
> I had to go back to the documentation, read it again word by word, and added the User Control to my Project directly. Then i had to remove the component used before, pick up the user control afresh and created controls all over again. 
> 
> It was tedious but well worth it. Now i can compile fine without any issues again.
> 
> Your documentation saved my life.
> 
> Thanks !


Glad that you could fix the issue.

Your feedback is important (both), it encourages me to keep working on further improvements.

----------


## xiaoyao

The transparent part does not accept mouse click events.If we draw a 99% transparent PNG picture mask on it, it will be transparent to our eyes, but it is not really transparent, so it can be clicked.
I once made a list box transparent to it.And the button is transparent to him.Set the button's background color to transparent.As a result, it is very difficult for me to click on the button, and I must click on the text on the button accurately.If the form is simple, there are no overlapping controls.In fact, when you click on this transparent control, it has already clicked on the form.You just need to calculate whether the area of the form is a button, and then you can trigger the button click event.

----------


## Eduardo-

Update released:

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.
2021-04-02 Now property SoftEdges defaults to True, and ShowFocusRect to False.
2021-04-02 Bug fix in TabMinWidth property.
2021-04-01 *Added BackStyle property*.
2021-02-21 Error message in 'Property Let Tabs' procedure was duplicated.
2021-02-18 Change in positioning tab caption when it does not fit in height

----------


## softv

> Update released:
> 
> 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).
> ...


Dear Eduardo, 


*Thanks a TON* for your fabulous SSTabEx control. Amazing! Amazing! *Amazing!* Actually, I have written to you some 15 years back itself and have successfully used your Unicode RichTextBox of those times. 


Actually, I got info about your SSTabEx control only a few days back, thanks to Erwin69 who wrote about it here -  https://www.vbforums.com/showthread....=1#post5518580. Thank GOD I happened to see it.


I have been using Krool's marvellous controls since 4 years or so. Now, I have started using your SSTabEx control too. Thanks a ton ever to Krool and you. 


Kind Regards.

----------


## Eduardo-

> Dear Eduardo, 
> 
> 
> *Thanks a TON* for your fabulous SSTabEx control. Amazing! Amazing! *Amazing!* Actually, I have written to you some 15 years back itself and have successfully used your Unicode RichTextBox of those times. 
> 
> 
> Actually, I got info about your SSTabEx control only a few days back, thanks to Erwin69 who wrote about it here -  https://www.vbforums.com/showthread....=1#post5518580. Thank GOD I happened to see it.
> 
> 
> ...


Thanks for your comments.
But about the Unicode RichTextBox I think you are confusing me with someone else.

----------


## softv

Dear Eduardo,

*Thanks a TON* once again for your supreme SSTabEx control. I have no issues even with nested Coolbar controls (with multiple bands) inside one of your tabs. So far I have populated only one tab but it is all working supremely. I just wanted to give you this feedback since you have worked so hard on this control and would like to know in what all scenarios it works PERFECTLY and benefits users. 

Well, 2 things I noticed which I wish to bring to your notice. Please see attached image below.

1. You can see *two dots* (which I have highlighted in yellow color) in the tab with caption "Tab 5". You can see one dot each in the two edges of the tab. *This happens during* 'mouse hover' over the tab; when the BackColor is set to a dark color; and the 'VisualStyles' is off. In the attached screenshot, the BackColor is set to Black. Kindly let me know if by any way I can avoid the two dots from appearing. The two dots appear when I do 'mouse hover' over the tabs "Label" and "Theme" also but not on the other tabs. In my own project, I tried your SSTabEx with multiple tabs and the two dots appeared in all the tabs at some point of time. As of now, the two dots always appear in the last tab alone, not on other tabs. Of course, these 2 dots appear in the situation I explained above only. i.e. during 'mouse hover' over the tab; when the BackColor is set to a dark color; and the 'VisualStyles' is off. Kindly let me know if by any way I can avoid the two dots from appearing in the situation I have explained.

2. The thickness of the tab separator is lean and elegant between 'Tab 5' and 'Tab 6' but not between 'Label and 'Tab 5'. The tab separator between 'Theme' and 'Frame' is also not lean and elegant. Can all the tab separators be made to look lean and elegant (as the one between 'Tab 5' and 'Tab 6') so that one can have a uniform look.

Attachment 181725

I once again thank you for your SSTabEx control. Absolutely marvellous control with sooo many options. I can keep on thanking you.

Kind regards.

----------


## Eduardo-

Hello, the forum has some issues with attached images, could you please re attach the image? Thanks.

----------


## softv

If I click on *Attachment 181725* (in my earlier post), it does open and the image does get displayed in a separate window. I attach the same hereunder again (the forum names it as 'Attachment 181726'), anyway. In case it is not getting displayed for you at your end, what shall I do? What is the alternative? It is a JPG image, by the way. 

And, by the way, the screenshot the image carries is from your "Group1.vbg" demo application only (supplied in your "SSTabEx-main.zip" file). So, in case you are not able to view the image I have attached, you may kindly just start your "Group1.vbg", change BackColor for the 'SSTabEx1' control in the form 'frmTest' to Black. Make 'VisualStyles' off and mouse hover 'Tab 5' tab or 'Label' tab. You can get to see two dots in Black color at either edge of the 'Tab 5' tab. Hope this helps.  

*Attachment 181726*

Kind Regards.

----------


## Eduardo-

No, it doesn't work for me, "invalid attachment" says (any of the links)




> In case it is not getting displayed for you at your end, what shall I do?


When I upload images (in my posts) from the "insert image" icon that is in the post editor toolbar and go to advanced mode and then post the message, the first time I get the error. Then I have to edit the message, remove the image code, and upload the image again, then save the changes to the post. That works.




> And, by the way, the screenshot the image carries is from your "Group1.vbg" demo application only (supplied in your "SSTabEx-main.zip" file). So, in case you are not able to view the image I have attached, you may kindly just start your "Group1.vbg", change BackColor for the 'SSTabEx1' control in the form 'frmTest' to Black. Make 'VisualStyles' off and mouse hover 'Tab 5' tab or 'Label' tab. You can get to see two dots in Black color at either edge of the 'Tab 5' tab. Hope this helps.


I don't notice any issue here:

----------


## softv

> ... .. .
> When I upload images (in my posts) from the "insert image" icon that is in the post editor toolbar and go to advanced mode and then post the message, the first time I get the error. Then I have to edit the message, remove the image code, and upload the image again, then save the changes to the post. That works.
> 
> I don't notice any issue here:


The issue persists in my case. Well, I will try to upload my image hereunder in the way you have suggested. And, coming to the 2nd point, is there any way to make *all the tab separator lines to appear uniform in appearance*?



I see that my image is appearing correctly now, above (i.e. as part of this message itself. No need to click a link). By the by, I am on "Windows 10 Home". Any other details you might need from my end?

*One more thing*. In my own project (which uses lots of controls [manually added; I don't use the OCX version] from Krool's, the *cDlg.cls* of yours has public constants which are same as some of the constants used by Krool. So, VB6 complains of ambiguity. So, I needed to remove that cls and the "*ptpSSTabExTabs*" page file, for the time being. What is the best workaround so that I can have both these files and thus the 'Tabs' tab in your control's 'Properties' sheet (which is extremely useful)?

Kind regards.

----------


## Eduardo-

Update released.

All three issues fixed.

----------


## softv

> Update released.
> 
> All three issues fixed.


Thank you, thank you, thank you. *Thank you sooo much*. Very sorry for the delay in response. Because of certain things, I could see your recent message only just a while ago. Immediately after seeing your quoted message, I am replying. *Thanks a TON once again*, from the bottom of my heart. After working with your latest release, I shall write back again.

Kind regards.

----------


## softv

> Update released.
> 
> All three issues fixed.


Dear Eduardo,

Thanks again. I worked with the new release.

1. The 2 dots do not appear. Thanks a lot.
2. The *tab separators* are uniform. Thanks a lot. But, they look thick when VisualStyles is OFF. Only when VisualStyles is ON, they look *thin and elegant*. Is it possible to make them look thin&elegant when VisualStyles is OFF too?
3. no ambiguity issue due to 'cDlg.cls' constants. Thanks.

However, one thing I noticed in the new release in your demo application. The tab separators are not visible when TabsPerRow = 4 alone (with Tabs Count = 7). Please see screenshot at the end of this message. Is that correct? Or, am I missing something? Anyway, in my own project, I don't have this issue when VisualStyles is ON. But, *when VisualStyles is OFF and TabsPerRow < Tabs Count*, then for some cases of TabsPerRow (for e.g. TabsPerRow=3 and Tabs Count = 7), the *bottom lines of one or two tabs do not appear*. For other cases, the bottom lines appear properly. I dont know why. 

By the by, *I need one additional option*, if at all possible. Even when TabOrientation is left or right (i.e. vertical orientation), I should have the additional# option to have the tab captions appear horizontally itself, instead of being tilted 90 degrees. In other words, if "ant", "best best best", "cat", "dog", "egg" are my tab captions for 5 tabs, I should have the additional option to make them appear horizontally itself, even when TabOrientation is left or right. And, "best best best" should be able to wrap in 2 lines (when wrapping is on and width of tab is less to hold "best best best"). 

(#) the present default case of the captions appearing tilted 90 degrees also I need. The feature I am requesting is an additional option so that using it one can have the captions appear horizontally also. 

Kind regards.

*Screenshot:*

----------


## Eduardo-

> Dear Eduardo,
> 
> Thanks again. I worked with the new release.
> 
> 1. The 2 dots do not appear. Thanks a lot.
> 2. The *tab separators* are uniform. Thanks a lot. But, they look thick when VisualStyles is OFF. Only when VisualStyles is ON, they look *thin and elegant*. Is it possible to make them look thin&elegant when VisualStyles is OFF too?
> 3. no ambiguity issue due to 'cDlg.cls' constants. Thanks.
> 
> However, one thing I noticed in the new release in your demo application. The tab separators are not visible when TabsPerRow = 4 alone (with Tabs Count = 7). Please see screenshot at the end of this message. Is that correct? Or, am I missing something? Anyway, in my own project, I don't have this issue when VisualStyles is ON. But, *when VisualStyles is OFF and TabsPerRow < Tabs Count*, then for some cases of TabsPerRow (for e.g. TabsPerRow=3 and Tabs Count = 7), the *bottom lines of one or two tabs do not appear*. For other cases, the bottom lines appear properly. I dont know why.


Thanks for your reports, they are very helpful!
Please test now, the issues should be fixed.




> By the by, *I need one additional option*, if at all possible. Even when TabOrientation is left or right (i.e. vertical orientation), I should have the additional# option to have the tab captions appear horizontally itself, instead of being tilted 90 degrees. In other words, if "ant", "best best best", "cat", "dog", "egg" are my tab captions for 5 tabs, I should have the additional option to make them appear horizontally itself, even when TabOrientation is left or right. And, "best best best" should be able to wrap in 2 lines (when wrapping is on and width of tab is less to hold "best best best"). 
> 
> (#) the present default case of the captions appearing tilted 90 degrees also I need. The feature I am requesting is an additional option so that using it one can have the captions appear horizontally also. 
> 
> Kind regards.


Yes, I know. But that would take some important work, to add that option and make everything to work right on this already complex control.

I made it this way because I copied exactly what the original SSTab did, but I agree that having the captions rotated is not a good idea.

I don't know if I will ever add that, because in my VB6 projects I never needed it so far.

You could try this control for that.

----------


## softv

> Thanks for your reports, they are very helpful!
> Please test now, the issues should be fixed.


I am quite glad to know that my observations were very helpful. Yes, the issues are fixed and *I feel elated. Everything looks supremely wonderful*. Just one observation alone which I have explained after all my replies.




> I copied exactly what the original SSTab did, but I agree that having the captions rotated is not a good idea.
> I don't know if I will ever add that, because in my VB6 projects I never needed it so far.
> You could try this control for that.


Yes, when controls are based on the original, I understand the difficulties involved. That's why I wrote "if at all possible" in my earlier message. Thanks for the link to vertical tab by Olaf. Will try it and see.




> that would take some important work, to add that option and make everything to work right on this *already complex control*.


yes, I am always aware of the extreme and immense complexity involved. that's why I keep marvelling at your control and work. Stupendous. Really.

Well, the *attributes* set for the tabs' font (name, size, bold, italic, underline, etc.) and the "TabSelFontBold and TabSelForeColor" *properties* set for the tabs *do not get carried forward* when the Tabs' orientation is changed from Top to Bottom. Changing to Right or Left orientations preserve the attributes and TabSelForeColor chosen. This is what is happening in my own project. As far as your demo project is concerned, the "TabSelForeColor" property alone is not getting preserved in bottom orientation. Please see screenshots below. Thanks. 

*Screenshot 1* (top orientation):


*Screenshot 2* (bottom orientation):


Kind regards.

----------


## Eduardo-

Thank you again for your report.
The issue should be fixed now.

----------


## softv

> Thank you again for your report.
> The issue should be fixed now.


*Wow!* Lightning-quick update from you.  :Smilie: . Wow! 
Well, as far as I have quickly worked with your new release, its all looking great. *Supremely great*.  :Smilie: 

*Thanks a TON*, once again.  :Smilie: 

Kind regards.

----------


## Eduardo-

> *Thanks a TON*, once again. 
> 
> Kind regards.


You are welcome!

----------


## Eduardo-

Update released!

2021-10-23 improvements regarding disabled state (Enabled = False).

----------


## Eduardo-

Update released.

2021-10-27 bug fix in TabVisible property when no visible tab is left, and after that a tab is made visible.

----------


## DiveLoop

Oh this is great! I got really excited when I saw this pop up on the forum this morning. I do a lot of work in VBA and use the MultiPage control often. This is a great option for projects in VB6. --Thank you!

I was wondering if it would be possible to also modify the tab Orientation to Vertical and Horizontal, like this:
Attachment 182790
Attachment 182791

I know it's an unusual request and takes up a lot of screen real estate, but it would be helpful for my project.

Thank you again

----------


## Eduardo-

Hello, the images are not displayed due to a forum bug, but if you edit the post and upload the images again they will (hopefully) work.

----------


## DiveLoop

I don't seem to have the option to edit the post. But I'll try this instead:
https://i.imgur.com/JdVAGeB.png
https://i.imgur.com/qKXDJaJ.png

----------


## Eduardo-

OK, it is because you are new to the forum.
BTW, welcome to the forum.




> I don't seem to have the option to edit the post. But I'll try this instead:
> https://i.imgur.com/JdVAGeB.png


I don't see much value on that option because vertical text is hard to read.
The advantage is that you can place many tabs in just one row.




> https://i.imgur.com/qKXDJaJ.png


Here there is another control that does that.

I'll keep in mind your requests, but I don't think I'll do that anytime soon (most probably never).

----------


## Eduardo-

Update released:
2021-11-16 important bug fix in TabVisible property

This bug was introduced on July 1, 2021.
All people that downloaded the control from July 1, 2021 to November 16, 2021, should update, specially if the use the TabVisible property on their projects.

----------


## KenHorse

Moving to Win11 but have problem with SSTabEx property showing as picturebox. Of course this breaks my tab strip!

This is only happening within the IDE but if I move the .exe that was compiled under Win10 to the Win11 (running in a VM), the compiled .exe runs fine

----------


## Eduardo-

> Moving to Win11 but have problem with SSTabEx property showing as picturebox. Of course this breaks my tab strip!
> 
> This is only happening within the IDE but if I move the .exe that was compiled under Win10 to the Win11 (running in a VM), the compiled .exe runs fine


I suppose the issue must be that you need to register the OCX file on Windows 11.

----------


## KenHorse

> I suppose the issue must be that you need to register the OCX file on Windows 11.




It is registered, as demonstrated by the application that uses it, runs properly as an .exe, no?

----------


## KenHorse

Just to be certain, I used regsvr32 to register TabExCtl.ocx from the same directory it is called from within the VB6 IDE (it was successful) and still the same problem - it shows under Properties as a PictureBox not as SSTabEx. In fact, when I load the midi form that uses it, the error log reports

Line 2: Could not create reference: '{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.1#0'.
Line 59: Class TabDlg.SSTabEx2 of control SSTabEx2 was not a loaded control class.
Line 65: The property name _ExtentX in SSTabEx2 is invalid.
Line 66: The property name _ExtentY in SSTabEx2 is invalid.
Line 67: The property name _Version in SSTabEx2 is invalid.
Line 68: The property name Style in SSTabEx2 is invalid.
Line 69: The property name Tabs in SSTabEx2 is invalid.
Line 70: The property name TabsPerRow in SSTabEx2 is invalid.
Line 71: The property name TabHeight in SSTabEx2 is invalid.
Line 72: The property name WordWrap in SSTabEx2 is invalid.
Line 83: The property name TabCaption(0) in SSTabEx2 is invalid.
Line 84: The property name TabPicture(0) in SSTabEx2 is invalid.
Line 85: The property name Tab(0).ControlEnabled in SSTabEx2 is invalid.
Line 86: The property name Tab(0).ControlCount in SSTabEx2 is invalid.
Line 87: The property name TabCaption(1) in SSTabEx2 is invalid.
Line 88: The property name TabPicture(1) in SSTabEx2 is invalid.
Line 89: The property name Tab(1).ControlEnabled in SSTabEx2 is invalid.
Line 90: The property name Tab(1).ControlCount in SSTabEx2 is invalid.
Line 91: The property name TabCaption(2) in SSTabEx2 is invalid.
Line 92: The property name TabPicture(2) in SSTabEx2 is invalid.
Line 93: The property name Tab(2).ControlEnabled in SSTabEx2 is invalid.
Line 94: The property name Tab(2).ControlCount in SSTabEx2 is invalid.
Line 95: The property name TabCaption(3) in SSTabEx2 is invalid.
Line 96: The property name TabPicture(3) in SSTabEx2 is invalid.
Line 97: The property name Tab(3).ControlEnabled in SSTabEx2 is invalid.
Line 98: The property name Tab(3).ControlCount in SSTabEx2 is invalid.
Line 99: The property name TabCaption(4) in SSTabEx2 is invalid.
Line 100: The property name TabPicture(4) in SSTabEx2 is invalid.
Line 101: The property name Tab(4).ControlEnabled in SSTabEx2 is invalid.
Line 102: The property name Tab(4).ControlCount in SSTabEx2 is invalid.
Line 103: The property name TabCaption(5) in SSTabEx2 is invalid.
Line 104: The property name TabPicture(5) in SSTabEx2 is invalid.
Line 105: The property name Tab(5).ControlEnabled in SSTabEx2 is invalid.
Line 106: The property name Tab(5).ControlCount in SSTabEx2 is invalid.
Line 107: The property name TabCaption(6) in SSTabEx2 is invalid.
Line 108: The property name TabPicture(6) in SSTabEx2 is invalid.
Line 109: The property name Tab(6).ControlEnabled in SSTabEx2 is invalid.
Line 110: The property name Tab(6).ControlCount in SSTabEx2 is invalid.
Line 111: The property name TabCaption(7) in SSTabEx2 is invalid.
Line 112: The property name TabPicture(7) in SSTabEx2 is invalid.
Line 113: The property name Tab(7).ControlEnabled in SSTabEx2 is invalid.
Line 114: The property name Tab(7).ControlCount in SSTabEx2 is invalid.
Line 115: The property name TabCaption(8) in SSTabEx2 is invalid.
Line 116: The property name TabPicture(8) in SSTabEx2 is invalid.
Line 117: The property name Tab(8).ControlEnabled in SSTabEx2 is invalid.
Line 118: The property name Tab(8).ControlCount in SSTabEx2 is invalid.
Line 119: The property name TabCaption(9) in SSTabEx2 is invalid.
Line 120: The property name TabPicture(9) in SSTabEx2 is invalid.
Line 121: The property name Tab(9).ControlEnabled in SSTabEx2 is invalid.
Line 122: The property name Tab(9).ControlCount in SSTabEx2 is invalid.
Line 123: The property name TabCaption(10) in SSTabEx2 is invalid.
Line 124: The property name TabPicture(10) in SSTabEx2 is invalid.
Line 125: The property name Tab(10).ControlEnabled in SSTabEx2 is invalid.
Line 126: The property name Tab(10).ControlCount in SSTabEx2 is invalid.

----------


## Eduardo-

> It is registered, as demonstrated by the application that uses it, runs properly as an .exe, no?


Then you used one ocx compilation for your exe and later another ocx (possibly another version) in the project.
I believe that you compiled your ocx yourself some time ago, so you are not using the compiled version that is on GitHub...




> Line 2: Could not create reference: '{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.1#0'.


As a first attempt, open the *.vbp file with Notepad, and replace:



```
{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#2.1
```

with.



```
{831FDD16-0C5C-11D2-A9FC-0000F8754DA1}#1.0
```

Save the file, and try to open it in the IDE.

If it didn't work, then:

Open VB6 IDE, start a new project, go to menu Project, Components and select the SSTabEx, add a SSTabEx control to Form1, save the project, and open the Project1.vbp with Notepad, and copy the line that is referencing the ocx, for example:



```
Object={EA478B61-D9EC-47F6-BB21-95A533AF2251}#1.0#0; TabExC01.ocx
```

Then open with Notepad your project's vbp file (first make a backup copy) and replace the line that is referencing the old ocx with the new, save.

Do the same with the form (each form that is using the control), first copy the line from Form1 of the new project, and replace the line referencing the ocx in your project form files, for example:



```
Object = "{EA478B61-D9EC-47F6-BB21-95A533AF2251}#1.0#0"; "TabExC01.ocx"
```

Also, on each form replace the control type information with the correct one (also with Notepad), for example:



```
Begin TabExCtl.SSTabEx SSTabEx1
```

That's it, save and open your project in the IDE.

----------


## Eduardo-

> Just to be certain, I used regsvr32 to register TabExCtl.ocx from the same directory it is called from within the VB6 IDE (it was successful) and still the same problem - it shows under Properties as a PictureBox not as SSTabEx. In fact, when I load the midi form that uses it, the error log reports


If you first made your own ocx compilation, and later you want to use my "official" ocx compilation, then for VB6 they are two different controls.

To fix that, do the steps outlined in the second part of my previous message.

----------


## KenHorse

Nope, still not working.

Again, I am running Win11 in a virtual machine (Oracle VirtualBox)

----------


## Eduardo-

The solution is what is outlined on post #118 in the second part, from the line "If it didn't work, then:"

Anyway I still don't know if that "SSTabEX - SSTab Replacement" that is listed on your Components dialog is one that you compiled yourself or the one that can be downloaded from GitHub.

If you want, send me privately that ocx that is registered in your Windows (ensure that you are sending the correct one file), the *.vbp file of the non-working project, and the form(s) file(s) that use the SSTabEx control, and I'll modify them for you.

----------


## Eduardo-

PS: thinking about it, I guess that you compiled a new ocx in Windows 11. That's an error, if you want to compile the control again, you need to do that with binary compatibility to the previous version (that is the one that your vbp project is already using).

----------


## Eduardo-

> 


If you uncheck the "Selected Items Only" box, you'll see that there is another "SSTabEx - SSTab Replacement" registered on your Windows, that is the one that is using your compiled exe that it working (as you said).

----------


## softv

Dear Eduardo,

Warm Greetings! *Thanks* a TON once again for your wonderful SSTabEx. 

Well, I have some ListBoxes contained in your SSTabEx in a form. 

Whenever I resize the form, I resize the SSTabEx. 

And whenever I *resize the SSTabEx*, all the *ListBoxes* in the SSTabEx* flicker* heavily. 

May be there is an option or a simple way to stop that flickering which I don't know right now. If so, kindly let me know that simple method.

If no such simple method exists, then what are all the available not-so-simple techniques? What is the best one among them, which can work bullet proof all the time? If possible, can you kindly provide me a sample code of the best technique (in a sample project with several ListBoxes inside your SSTabEx)? I would be much grateful. 

Thanks in advance.

Kind Regards.

N.B.: I did read some 2 threads (related to flickering in SSTab and not yours; for instance https://www.vbforums.com/showthread.php?614694-Stop-flicker-during-RESIZE)

Update-1: As of now, LockWindowUpdate seems to be working. The flickering is minute, if ever any. I hope LockWindowUpdate does not give rise to some other problems. I will keep observing and if any problems, will write again. Thanks.

----------


## Eduardo-

It is a problem of the VB.ListBox, not the SSTabEx or SSTab.
You can use Krool's ListBoxW instead, it seems to flicker only the selected item (not all items like the VB.ListBox does) but maybe you can ask Krool to fix that minor issue too.

----------


## softv

Dear Eduardo,

Thanks a lot for suggesting to use ListBoxW. Will use the same hereafter. 

By the by, while resizing sstabex at runtime, I  noticed that at some values of widths, *slight gaps* were existing between one or more pairs of tabs. The following screenshot will make it clear. You can see gaps between tabs 1&2, 3&4, etc. This happens in both cases (VisualStyles on and off)

Attachment 184247

I noted down the values of such widths and replicated them at design time. For some values, at design time also, the same gaps (as seen in the screenshot above) were existing. I don't know whether I am doing any mistake or it needs your attention. If the former, kindly let me know what mistake I am doing. Thanks.

Kind regards.

----------


## softv

One more thing, dear Eduardo.

As you can see in the screenshot below, Tab9 (that *last tab*) is not aligned with the right edge of the SSTabEx control. This issue also happens at random values of widths, either without the abovementioned gaps problem OR along with the gaps problem (as is the case in the screenshot below). I don't know whether I am doing any mistake which causes this misalignment of the last tab. If not any mistake of mine, then if the alignment of the last tab cannot be done with the right edge for certain widths (even while maintaining equal widths for all tabs), then is it possible to increase the width of the last tab alone so that it aligns with the right edge? Thanks.



Kind Regards.

----------


## Eduardo-

Could you please make a test project to see the issue (and possibly fix it)?

Also I want to know the DPI setting (Screen scale %) you are testing on.

----------


## Eduardo-

> One more thing, dear Eduardo.
> 
> As you can see in the screenshot below, Tab9 (that *last tab*) is not aligned with the right edge of the SSTabEx control. This issue also happens at random values of widths, either without the abovementioned gaps problem OR along with the gaps problem (as is the case in the screenshot below).


Now I don't remember the reason but I think I recall that was on purpose when you use visual styles.
They are tabs, in my opinion they don't need to be aligned to the end. Leaving some space make the last one look more like a tab.
But of course that's is a matter of taste.

If you set visual styles off, that doesn't happen.

----------


## Eduardo-

About the spaces between tabs, are you using the latest version that is posted?

Because I remember that I already fixed that problem like a year ago.

----------


## Eduardo-

> They are tabs, in my opinion they don't need to be aligned to the end. Leaving some space make the last one look more like a tab.
> But of course that's is a matter of taste.


I'll keep this request in mind, but right now I'm working in something else and these issues are not simple, so I don't want to do it right now.

PS: thanks for your feedback.

----------


## softv

Dear Eduardo,*

1. Regarding* 'gap after the last tab'

I agree with you. I myself already felt that a slight gap after the last tab looks nice too. So, it would be good to have an option (*Extend last tab* to align with right edge) in the 'Property Pages' windows so that according to one's choice (or based on what is best for a particular tabbed interface), one can avail this option or not. This option can be provided for 'Visual Styles' off case also, in my opinion. 

Quoting you:
// If you set visual styles off, that doesn't happen. //
Actually, when *'Visual Styles' is off also*, the *misalignment* issue arises, if the 'TabAppearance' is ssTAPropertyPageRounded or *ssTAPropertyPage*. It is a slight misalignment, either slightly pulled in (i.e. slight gap between last tab and right edge) or slightly pushed out. 'Pulled in' - perhaps may be by design it is so (for PropertyPage appearance)? But, 'Pushed out', I don't know. Well, you are the best person to let me know the right info on both the cases. Await the same. Well, just now I observed that when 'Style' is set to '*ssStylePropertyPage*' also, same issue arises (even when TabAppearance is still ssTATabbedDialog only). In fact, at some widths, the last tab's caption is slightly getting cut (please see screenshot below), when it is the case of the last tab being 'pushed out'.





And, thanks, as always, Eduardo, for taking up the above task for your consideration. I understand your time constraints. So, will surely wait until you get time to put in your invaluable efforts on the above task, which would be of benefit to us all, as ever.

Note that I had my 'TabSelFontBold' as 'Yes' during most of my observations. Anyway, I observed the case of the "last tab's caption slightly being cut" even when I set 'TabSelFontBold' to 'No'.

*2. Regarding* 'gap between tabs'

a) With respect to dpi, I am working on 1366x768 resolution at 100% scaling, with an external monitor (having a wider screen than the laptop screen) connected to the laptop.

b) With respect to SSTabEx version I am working with, yes, its the latest version. Actually, if I remember right, after last year's June/July updates also I noticed the 'gaps between tabs' with VisualStyles ON but with VisualStyles OFF, all seemed to work well. So, for that time being, I did not write back to you immediately. Plus, I think I thought I will give some time interval before writing to you again. But thereafter, since September 2021 or so I did not get to use SSTabEx in my new project screens and so I just postponed writing to you. Now, having come back to working with SSTabEx again with full focus on it, I have been sharing what all I noticed with you. 

c) As of now, with VisualStyles Off (and with my present preferred 'TabAppearance' of 'ssTAPropertyPageRounded' and 'Style' of 'ssStyleTabbedDialog'), gaps do not appear between tabs at any time when the final ".exe" is run. The only issue during final .exe execution is the slight 'pushing in' and 'pushing out' I have mentioned in Point 1. 
Note: With above setting, in IDE runtime, gaps do appear sometimes but if and when the gaps appear, they do appear between "all" tabs at same width. Anyway, it is in IDE runtime only. So, not an issue except that new users who see the gaps might get to presume that they will appear in final .exe also.

d) And, as of now, with VisualStyles On also, the same above behaviour can be replicated, if 'Style' is set to '*ssStylePropertyPage*' (along with 'TabAppearance' of 'ssTAPropertyPageRounded'). I notice no gaps between tabs but only 'push-pull' problem. 
Note: With above setting, when VisualStyles is Off also, same behaviour seen. I notice no gaps between tabs but only 'push-pull' problem. 

*Sorry*, due to my time constraints, I am unable to put all my above observations together in a sample project and send to you, right now. Actually, it has taken a few hours to try out the above and correctly document my observations to you (as above) itself. May be I can try to make a sample project after some days but I very much doubt whether I will get the time. *Sorry* about it. I am not able to put the above in a tabulated form too. Sorry again. But, I am sure you got all the points, anyway. And, I hope all or at least some of my observations are correct. Sorry, if not. Kindly please bear with me in that case. *The thing is that* different combinations of the properties have to be set in the 'Property Pages' sheet and each one tried out for gap between tabs, gap after last tab, last tab pushing out, etc. 

Thanks once again for all your stupendous efforts with regard to fabulous SSTabEx control. *God Bless you! God Bless all!*

Kind Regards.

----------


## Eduardo-

At least part of the issue of the last tab gap, is because Windows themes has different images for the first and last tab, so it is normal, at least in part, to se a little gap when the control is themed. The same happens in the first tab (when it is not selected).
You can observe that look also in Windows screens, go to somewhere that is a tab, for example Net properties.

Regarding the other issue (of the gaps between tabs), and any issue, I need to be able to reproduce the issue here, so I need a sample project where I can see it.
Making a sample project could take some time, I know, but it can take like 1/20 (or less) of the time that I will need to fix it.

So, unless the issue is easily reproducible following some clear steps from zero, I will always need a sample project.

Of course if there is something wrong I would like to fix it, but I''m using the control in many projects without seeing any current issue.
I believe you, nevertheless. But I repeat: I need to see the problem.

----------


## softv

Dear Eduardo,

I fully understand your situation. So, will try to make a sample project at some point of time, if and when possible, for you to reproduce the issues at your end. 

Now, coming to ListBoxW, I observed that the 'flicker in highlighted item alone' is not present when LockWindowUpdate is used. But, using LockWindowUpdate introduces a mild flicker of some or all the items of the ListBoxW once in a while, when I randomly keep resizing. Well, that's what happens, as far as my system in concerned.

Coming to a more important thing, I observed since day-before-yesterday that some of my SSTabEx tabs' contents were not showing up during IDE runtime as well as when I ran them as .exe executables. In design time, all the tabs' contents were showing up correctly. Getting no clue as to why for a long time, I finally found out yesterday that the issue *seems to be* to do with having a coolbar (krool's) inside another coolbar in any one of the SSTabEx tabs. I don't know whether the problem is with Krool's coolbar or SSTabEx or some mistake on my part. 

Well, these are my *preliminary findings only*. I will come back with more details on the above after some time. I am posting my preliminary findings itself here so that if ever the mistake is only on my side OR you know already that coolbar-inside-coolbar in an SSTabEx tab is an issue and how that can be easily solved, then you can quickly share the same with me so that I need not spend time further exploring the abovesaid issue. That's the only reason I am posting my preliminary finding itself. So, kindly wait for more details from me. Kindly do not test out the abovesaid issue noticed by me, by yourself. I know your time is invaluable for both you and us.

Kind regards.

----------


## softv

By the by, I am using the ocx version (latest) of sstabex and in that only, I noticed the gap issues. I have not tested with the std-exe version of sstabex yet. 

The abovementioned coolbar-inside-coolbar issue (not yet fully confirmed by me) is also while using the ocx versions of vbccr17 (latest) and sstabex (latest).

I keep forgetting to mention that I am using the ocx version. Lest I forget again, I quickly came here to share just that info alone.

Kind Regards.

----------


## Eduardo-

OK, I also use the latest compiled ocx.

And no, I don't use coolbars. I would try with .Refresh (I'm not sure whether that control has that method, though).

I'm already a bit intrigued what is that issue of the gaps.

----------


## Eduardo-

About the coolbar inside another coolbar that is on an SSTabEx, try putting them inside a PictureBox instead, and see what happens. In the same program with the same code.
If the problems happens too, it has nothing to do with the SStabEx.
I think anyway that most probably it is a problem of that control, but... everything need to be tested and checked.

PS: the flicker of the ListBox is a hard issue, I recall at some point (some years ago) I had spent some time with that and found no solution.
At the end I think I recall I did it with a timer, for no resizing it so many times.

----------


## softv

> OK, I also use the latest compiled ocx.
> 
> And no, I don't use coolbars. I would try with .Refresh (I'm not sure whether that control has that method, though).
> 
> I'm already a bit intrigued what is that issue of the gaps.


// I'm already a bit intrigued what is that issue of the gaps //
Sorry. this is the not anything new. This is just the earlier 'gap between tabs' issue I had written about. 

// I would try with .Refresh //
tried .Refresh with both coolbars and sstabex. that did not help. will post next message with details soon. Thanks Eduardo for your quick suggestion though.

----------


## Eduardo-

> // I'm already a bit intrigued what is that issue of the gaps //
> Sorry. this is the not anything new. This is just the earlier 'gap between tabs' issue I had written about.


But I remember I fixed that.

OK, this control has many options/configurations.
Maybe it happens in one that I didn't test.

If you cannot make a sample project at least I need to know the exact steps to reproduce it.

----------


## Eduardo-

About the Coolbar painting, if the sst is themed I now think it could be that it is not handling well the theming (because it handles the background colors of contained controls).
I'll check it (later).

----------


## softv

> But I remember I fixed that.
> 
> OK, this control has many options/configurations.
> Maybe it happens in one that I didn't test.
> 
> If you cannot make a sample project at least I need to know the exact steps to reproduce it.


//  at least I need to know the exact steps //
yes, I am generating the steps only, right now

----------


## softv

Dear Eduardo,


Here are the steps for a *sample test*. To be sure they are fully correct, I did this same test in 3 separate new projects. Confirmed that the results are the same every time. Hoping still that I have not gone wrong anywhere and committed any mistake anywhere. If so, kindly bear with me.


*Note*: using sst and cbr as short for SSTabEx and Coolbar, resp., in the following steps. Have used sstabex (latest ocx) and krool's coolbar (from latest vbccr17.ocx) for the following basic test. 


- open a new project (with default form, Form1). 
- in Form1: 
- have one sst with 3 tabs. UNTICK 'ChangeControlsBackcolor' in 'Property Pages'.
- in all 3 tabs, have a cbr (say cbr1, cbr2, cbr3)
- in the form also (i.e. outside of the sstabex), have a cbr (cbr100)


- keep the 2nd tab of sst highlighted. 
- save the project, create an exe and run
- all 4 cbrs get displayed normally


- come back to the form. 
- have one cbr (cbr11) inside cbr1, in cbr1's first band. i.e by opening the 'Property Pages' of cbr1, *ensure* that cbr11 has been selected as the child in band1
- have one cbr (cbr33) inside cbr3, in cbr3's first band. i.e by opening the 'Property Pages' of cbr3, *ensure* that cbr33 has been selected as the child in band1
- have one cbr (cbr101) inside cbr100 in cbr100's first band. ensure the same.


- keep the 2nd tab of sst highlighted. 
- save the project, create an exe and run
- cbr100 gets displayed correctly, along with cbr101 inside it
- cbr2 gets displayed normally in tab2 
- but if you change focus to tab1 or tab3, *nothing gets displayed*


- come back to the form. 


- keep the 1st tab of sst highlighted. 
- save the project, create an exe and run
- cbr100 gets displayed correctly, along with cbr101 inside it
- cbr2 gets displayed normally in tab2 
- cbr1 gets displayed correctly, along with cbr11 inside it
- but, if you change focus to tab3, nothing gets displayed


- come back to the form. 


- keep the 3rd tab of sst highlighted. 
- save the project, create an exe and run
- cbr100 gets displayed correctly, along with cbr101 inside it
- cbr2 gets displayed normally in tab2 
- cbr3 gets displayed correctly, along with cbr33 inside it
- but, if you change focus to tab1, nothing gets displayed


- come back to the form. 
- change TabSelBackColor to white color (i.e. 'Highlight Text' color)


- keep the 2nd tab of sst highlighted. 
- save the project, create an exe and run
- cbr100 gets displayed correctly, along with cbr101 inside it
- cbr2 gets displayed normally in tab2 
- but if you change focus to tab1, a *plain rectangular box* (in gray color; i.e. 'Button Face' color) *gets displayed* in place of cbr1
- similarly, if you change focus to tab3, a plain rectangular box (in gray color; i.e. 'Button Face' color) gets displayed in place of cbr3


Kind Regards.


*N.B.* the 'ChangeControlsBackcolor' in 'Property Pages' of sst is ticked by default. Any special reason that it is kept ticked by default? If no special reason, can it be kept unticked by default, please? Thanks.

----------


## softv

> About the coolbar inside another coolbar that is on an SSTabEx, try putting them inside a PictureBox instead, and see what happens. In the same program with the same code.
> If the problems happens too, it has nothing to do with the SStabEx.
> I think anyway that most probably it is a problem of that control, but... everything need to be tested and checked.
> 
> PS: the flicker of the ListBox is a hard issue, I recall at some point (some years ago) I had spent some time with that and found no solution.
> At the end I think I recall I did it with a timer, for no resizing it so many times.


//  try putting them inside a PictureBox instead //
sorry, I missed seeing this message earlier as I started concentrating on creating the steps for the sample test. Just a few minutes back only I saw it and I tested. It seems to be working in my preliminary testing. Thanks a TONNNN.  :Smilie:  . But anyway, I shall work more with this setup and let you know whether all is well this way. Thank you so much again. 

Kind regards.

----------


## Eduardo-

Thanks, but I thought you were going to say the steps to reproduce the issue of the gaps...

----------


## softv

> Thanks, but I thought you were going to say the steps to reproduce the issue of the gaps...


Oh... sorry that I misunderstood that you asked the steps for the 'coolbar within coolbar' issue.

well, anyway, any straight solution to the abovesaid issue? Because, just a while ago, I had *only one coolbar* inside my SSTabEx. But still the coolbar did not show up when running the app. But this time, I deduced the reason for it quickly. The reason was there was a frame in the 1st band of the coolbar. 

So, the issue is not 'coolbar inside coolbar', as such. Even if a frame (may be a picturebox too) is inside a coolbar, the coolbar will not appear in the tab during runtime unless I enclose the coolbar inside a picturebox (or a frame) first. Well, not a big thing enclosing every coolbar in a picturebox first (since the case of having a frame inside a coolbar can arise any time, even if I don't have one initially). But, can this restriction be done away with, in case it is to do with SSTabEx? If you feel that the issue is not due to SSTabEx at all and due to Coolbar only, I need to write to Krool then? Can you kindly confirm the same?

Kind regards.

----------


## Eduardo-

Does it happen in the IDE or compiled?
Does it happen when the sst is themed or not? (is your IDE themed?)




> I need to write to Krool then?


I would not do that unless you can reproduce the problem without the sst.
That was the idea of suggesting using a PictureBox, to test without the sst (sst = SSTabEx), but you understood something else and by chance it seems it somewhat worked as a solution... or sort of.

BTW: for the coolbar issue please make a simple sample project.

----------


## Eduardo-

Example of describing the issue of the gaps:

"I use the IDE themed and with DPI awareness.
The screen DPI is set to 125% (120 DPI).
Add a new sst control to a form, Style property set to its default TabDialog.
Set the Tabs property to 7.
The width of the sst is 2000.
Keep the VisualStyles to it default that is True.
Run"

(That was an example explanation).

For the coolbars, just start a new project, reference the sst ocx, the krool CCR ocx, add an sst, add a coolbar, add another coolbar inside it, set all properties to whatever causes the problem and please post it here.

----------


## softv

> Dear Eduardo,
> 
> 
> Here are the steps for a *sample test*. To be sure they are fully correct, I did this same test in 3 separate new projects. Confirmed that the results are the same every time. Hoping still that I have not gone wrong anywhere and committed any mistake anywhere. If so, kindly bear with me.
> 
> 
> *Note*: using sst and cbr as short for SSTabEx and Coolbar, resp., in the following steps. Have used sstabex (latest ocx) and krool's coolbar (from latest vbccr17.ocx) for the following basic test. 
> 
> 
> ...


a) You mean, Eduardo, the above detailed steps are not enough? hmm... I spent quite a time creating it.  :Smilie: 

b) Well, the steps already include a coolbar outside the sst. Since you have instructed me now to test it inside a picturebox, I have done that too. I have enclosed a coolbar within a picturebox (no sst involved) and it appears normally and correctly. No issues in such a coolbar's display, even if one more coolbar is present inside it.

c) by the by, I have already used the same short name 'sst' in my steps, thanks to you.  :Smilie: 

d) As far as i can remember, I tried the above steps with all the 3 options of themes in your 'Property Pages'. Also, with VisualStyles Off and On too. The issue persists. 

e) My VB6.exe has Comctl32 ref. embedded in it, if that is what you mean by IDE being themed. 

By the by, the *issue*, as such, *is very simple now*. 

- It is not coolbar inside coolbar issue any more. 
- Even if it is a frame or richtextbox present inside a coolbar's band, the coolbar is not displayed in sst tabs.
- However, if I enclose the coolbar inside a picturebox or frame, it readily and normally gets displayed in sst tabs.
- So, all that you need now to see the issue is just to have a coolbar (with a frame in its band1) in an sst tab (say T2). Select the first tab (say T1) at design time. Press F5. Select T2 now. The coolbar will not display.

Kind regards.

----------


## softv

> Example of describing the issue of the gaps:
> 
> "I use the IDE themed and with DPI awareness.
> The screen DPI is set to 125% (120 DPI).
> Add a new sst control to a form, Style property set to its default TabDialog.
> Set the Tabs property to 7.
> The width of the sst is 2000.
> Keep the VisualStyles to it default that is True.
> Run"
> ...


I have just now seen this message of yours. As written earlier, it is not coolbar inside coolbar any more. And, reg. properties, no properties need to be changed in a newly added sst or coolbar. 

Kind regards.

----------


## softv

// 'ChangeControlsBackcolor' in 'Property Pages' of sst //
me writing about this property has nothing to do with the coolbar issue. I always UNTICK this property in my SSTs because if I remember right, if it is TICKED, it shows certain controls' background in black. Coolbar is one such control. I dont remember the other controls as of now. So, that is the only reason for unticking it. It has nothing to do with the coolbar issue, as such.

Kind regards.

----------


## Eduardo-

> Since you have instructed me now to test it inside a picturebox, I have done that too. I have enclosed a coolbar within a picturebox (no sst involved) and it appears normally and correctly. No issues in such a coolbar's display, even if one more coolbar is present inside it.


I repeat once more: that was intended to test whether the coolbar had the problem without the stt, the idea was to replace the sst with another container, a PictureBox.
You misunderstood it and luckily, by chance, found a solution.




> d) As far as i can remember, I tried the above steps with all the 3 options of themes in your 'Property Pages'. Also, with VisualStyles Off and On too. The issue persists.


I never know whether you are talking about the gaps problem of the coolbar problem.




> e) My VB6.exe has Comctl32 ref. embedded in it, if that is what you mean by IDE being themed.


I don't know what "Comctl32 ref. embedded in it" means, I have the IDE themed with a manifest file embed in it (and it is also declared DPI aware in the same manifest). But I can test in whatever other setting that is causing the problem, in case those setting have anything to do with it anyway.




> By the by, the *issue*, as such, *is very simple now*.


For the coolbar please send a sample test project, if it is easy to do it then the better.
I don't want to spend time figuring how to add bands and such with a control I seldom used.

PS: please make things simple to me, I'm currently very busy (and having headaches with other things).

----------


## softv

// I don't want to spend time figuring how to add bands and such with a control I seldom used. //
Oh okay eduardo. I fully understand your situation. You have not used coolbar at all and you are too busy right now.

Well, the resolving of these issues is not urgent for me since I have a solution in hand for the coolbar issue. Even otherwise, it is not urgent. I just reported the coolbar issue for your information. That's all. The gaps problem is also a minor issue for me since with VisualStyles off, its just to do with the slight space after the last tab. Not a big thing for me. 

So, I will read through your messages again and write back after some days, since I am also very much running short of time with my own work schedules. Also, I do not have prior knowledge of posting any sample project in this forum. Will learn about it. So, will write back after some days. Happy continuation with our work for both of us.  :Smilie: 

Kind regards.

----------


## Eduardo-

OK, thanks.
To post a test project, you need to zip the files without any exe, dll or ocx, and clcik the Go Advanced button, the click manage attachment, then browse to where the file is and attach to the post.

----------


## Albey

Hi Eduardo, 
SStabEx is fantastic as a replacement of SSTab!
Unfortunately I use widely Janus Gridex2000 which doesn't repaint correctly when you choose a tab where it is. 
The same not happens with Janus Gridex 1.6 whic is the previous version of the control. 
Can you check why? if you need other info let me know 
Thanks in advance

----------


## Eduardo-

Hello! Welcome to the forum.

Try with .Refresh on the Gridex in the TabSelChange event of the SStabEx (not tested, just a shot in the dark).

----------


## Albey

> Hello! Welcome to the forum.
> 
> Try with .Refresh on the Gridex in the TabSelChange event of the SStabEx (not tested, just a shot in the dark).


I had already tried .Refresh without success ... but it seems that I solved it by putting the .Rebind instead of the refresh in the event... 
Thanks!

----------


## Albey

> I had already tried .Refresh without success ... but it seems that I solved it by putting the .Rebind instead of the refresh in the event... 
> Thanks!


More Info: when the Gridex is in Unbound mode (.datamode=99) you have to use the .Rebind method... when in Ado mode (.datamode=1) you have to use .Refresh (instead you get an odbc error)...

----------


## softv

Dear Eduardo,

*Warm Greetings!* Happy to be writing to you again, though I am still under time constraints only.

As suggested by you, I have made a *small project (a test app)* to highlight an issue which I encountered while using Krool's command button control (kcb, for short) inside SST control. I have attached the same ("1. Buttons Inside Tabs - Test App.zip") in this post.

A screenshot of the test app below, just after starting it.


A screenshot of the test app below, after clicking the button captioned 'Resize CmdNormal and CmdKrools', immediately after starting the app. The *caption for Krool's command button has disappeared*, as you can see.


I felt I will post the abovementioned 'test app' (for the issue with kcb) first, rather than the one for the coolbar control, since I thought perhaps solving this issue with the kcb will solve the issue for the coolbar control too.

*Note-1*: Please do read the comments in my code, wherever they appear. Those comments are very important, as far as this 'test app' is concerned.

*Note-2*: In case the caption for 'kcb' does not disappear at your end and its all working correctly, then kindly bear with me and kindly let me know what could be the mistake I am doing at my end which makes the caption disappear.

*Note-3*: You have written in your post no. 151 as follows:
--
I have the IDE themed with a manifest file embed in it (and it is also declared DPI aware in the same manifest)
--
As far as I can say, my vb6 IDE is themed too. But, I am not sure about that 'DPI aware' part. I don't exactly remember what all my manifest file contained when I added it to the VB6 executable, few years ago. And, as stated in some of my past replies, my OS is Windows10, 64-bit. Screen resolution is 1920*1080. Under 'Scale and Layout' in Display settings, it shows '100% (Recommended)'.

*Note-4*: If the above-explained issue occurs at your end too, and *if it is not due to 'Sst'*, then kindly let me know as to what I should do further. As of now, the PictureBox is solving the issue for me in my projects. But then, for every tab, I need to necessarily have a PictureBox (to hold the 'kcb's).

*Note-5*: This is the first time ever I am posting a project (of any kind, 'test app' or otherwise) in our VbForums. So, if any mistake on my part, kindly bear with me and kindly guide me as to how I can post projects in a better manner in the future.

I believe I have kept things simple while explaining the above 'disappearing caption' issue with 'kcb'. Kindly bear with me, if I have not, because, this is the best extent to which 'I' could manage to keep it simple.

Kind regards.

----------


## Eduardo-

Hello, I fixed the issue.

It was that Krool's controls returns one hWnd for the control that is inside and another hWnd from another property (hWndUserControl) for the control-container (the UserControl).

I was working with the generic .hWnd that usually is "the control-container" because there is not control-container at all.

Now it first checks for .hWndUserControl and if it is not found, then tries .hWnd

----------


## softv

> Hello, I fixed the issue.
> 
> It was that Krool's controls returns one hWnd for the control that is inside and another hWnd from another property (hWndUserControl) for the control-container (the UserControl).
> 
> I was working with the generic .hWnd that usually is "the control-container" because there is not control-container at all.
> 
> Now it first checks for .hWndUserControl and if it is not found, then tries .hWnd


As always, thanks a TON, Eduardo. 

Kind regards.

----------


## softv

Dear Eduardo,

Please find attached my *test project for* the '*Gaps between tabs*' issue. Its named "2. Gaps between Tabs.zip"

In my test app, sst1 gets resized whenever the Form_Resize() event happens.

I see that during app startup itself, sst1 gets resized. And, I observe the gaps between tabs immediately, after app startup itself. Please see screenshot below. Gaps are seen between tabs 1&2, tabs 5&6 and tabs 8&9.


You may kindly please try manually resizing my test app's form's width (increase/decrease the width randomly). While doing so, you can observe gaps between tabs appearing, at several random widths of sst1. At some other random widths of sst1, you can observe that there are no gaps (its all perfect). For a sample, I just chose two such random widths (498px - a width at which I see gaps, and 503px - a width at which I don't see any gaps) to be used in the code of my command button cmd1's Click event. Please see screenshots below (sst1 at 498px and 503px, respectively), in this regard. At 498px, gaps are seen between tabs 1&2, tabs 5&6 and tabs 8&9.





*Note-1:*

My VB6 IDE is themed. I am not sure whether it has DPI awareness too.My screen resolution is 1920*1080.Under 'Scale and Layout' in Display settings, it shows "100% (Recommended)" in my system.My test app's SSTabEx (named sst1) has 10 tabs with TabsPerRow set to 10. No other default property of sst1 has been changed, as far as I can say.My test app's form's background color is set to 'Highlight' color (as you can see in the screenshots). The Highlight color's RGB is "0, 128, 215" in my system.

*Note-2*: In case the "gaps between tabs" do not appear at your end and its all working correctly, then kindly bear with me and kindly let me know what could be the mistake I am doing at my end which makes the "gaps between tabs" appear.

*Note-3*: If the "gaps between tabs" do appear at your end too, and *if it is not due to 'Sst'*, then kindly let me know as to what I should do further. 

I take this opportunity to once again thank you, in abundance, for your fabulous sst control.

Kind regards.

----------


## Eduardo-

Please test now.
(And if you can, please test with other configurations, to check they were not affected by the fix/change).

----------


## softv

> Please test now.
> (And if you can, please test with other configurations, to check they were not affected by the fix/change).


*Wowww!* In my initial testing, its all looking great. Excellent! Thank you sooo much!

Yes, will do more testing with different configurations, as and when I can. If any issues, will let you know.

Thanks once again and special thanks for such a quick update!!! 

Kind Regards.

----------


## Eduardo-

Updated.

Sometimes it happens that fixing a bug, another bug is introduced.
It was the case of the update on 08-Jun-2022 (less than a couple of weeks ago).
Changing .hWnd to .hWndUserControl for Krool's controls everywhere, had the side effect that in one place it actually needed the hWnd of the internal control.
Fixed now.

PS: the problem was that the backcolor of Krool's controls were not painted right when themed. They were painted with the normal backcolor and not with the backcolor of the tab.

----------


## softv

> Updated.
> 
> Sometimes it happens that fixing a bug, another bug is introduced.
> It was the case of the update on 08-Jun-2022 (less than a couple of weeks ago).
> Changing .hWnd to .hWndUserControl for Krool's controls everywhere, had the side effect that in one place it actually needed the hWnd of the internal control.
> Fixed now.
> 
> PS: the problem was that the backcolor of Krool's controls were not painted right when themed. They were painted with the normal backcolor and not with the backcolor of the tab.


Thanks, as always, dear Eduardo.

Kind Regards.

----------


## softv

Dear Eduardo,

Once again, *thanks a TON* for your truly wonderful control. 

This post is regarding the display of *run-time error* (please see screenshot below) while filling up certain values in the 'Property Pages' sheet. So, I am not attaching any sample project. I am just explaining the errors alone.


Well, in a new form, 
1) Add an sst control.
2) Allow it to be in its default values itself. 
3) Now, right click the control, click on 'Properties' to display the 'Property Pages' sheet. 
4) Try to change the values of certain properties in it. 
5) For some (not all) values, run-time error gets displayed. When that happens, the sst control appears with slanted lines across it so that when you right click the sst control, no more the 'Properties' menu item shows up.

The above happens in the following cases, as far as I have observed. May be there are some more cases too.
--
TabMaxWidth: a value of 150 and below results in run-time error.


TabMinWidth: a high value (say, 7000) results in run-time error.


TabSeparation: a value of 21 and above results in run-time error.


TabHeight: a high value (say, 5000) results in run-time error.


TabsPerRow: a value of 66 and above results in run-time error.


TabCount: It allows its box to be empty and if you click 'Apply' button when it is empty, it results in run-time error.


TabCount: If the value is '0', it results in run-time error.


TabsPerRow: It allows its box to be empty and if you click 'Apply' when it is empty,  it results in run-time error.


TabsPerRow: If the value is '0', it results in run-time error.
--

'May be' the above values I have mentioned are related to my system resolution and hence may vary in your system if your resolution is not same as mine (1920*1080).

I do observe that in some cases of the values, the right message '*Invalid property value*' gets displayed. *If such a message gets displayed* for all invalid values instead of a run-time error, that would suffice, I believe. Anyway, you are the best judge.

Please note that the TabsPerRow error (the value of '0' resulting in runtime error) is the one about which I actually wanted to inform you but before letting you know about the same, I just thought I will test it more and test the other input boxes as well and thus noticed the additional errors I have mentioned above.

I had faced the TabsPerRow error when I started using the control for the first time itself and thereafter becoming careful while entering the value in its input box. So, I don't remember exactly what made me enter '0' in it but I think the following might have happened.
--
Even today, when I try to place the mouse cursor after the value (say 12) present in the input box of TabsPerRow, in order to change the value (say, to 10), the whole value (12) gets selected and highlighted (please see sample screenshot below - for the default value of 3). So, habitually, if I press the backspace key to erase the '2' in 12 and type '0' to make it '10' and then press the 'Enter' key immediately, what actually happens is that the whole value (12) gets deleted (since it is fully selected already) and '0' gets typed. So, when I eventually press 'Enter', it results in error, since only '0' is there and not '10'.
--


I request you to do the needful, if and when possible, so that when I place the cursor in the input box of any property, the cursor stays at the far right of the value. This is the behaviour when I place the cursor in the input box of the '*TabHeight*' property alone. The value in the input box does not get selected fully and the cursor stays at the far right of the value (please see screenshot below). If this is the behaviour for other input boxes as well, I would be happy.



*One more issue* to inform (as follows). I have tried my best in explaining the following issue but if you still feel that I am not clear enough, then sorry about it. That is the best extent to which I am able to explain the following issue, as of now.
--
1. Try to fully select the value in an input box (other than that of TabHeight's) by placing the mouse cursor at the far right of the value and dragging the mouse to the left with the left-mouse-button pressed.
2. The cursor goes to the far left of the value instead of selecting the whole value. 
3. The thing is that the value is already selected fully as soon as the cursor is placed at the far right and me dragging the mouse takes the cursor to the far left only.
4. In the case of 'TabHeight' alone, the behaviour is normal. The whole value gets selected as it should (while carrying out the mouse movements as explained above). If this is the behaviour for other input boxes as well, I would be happy.
--

In case the above errors and/or issues do not happen in your system at all, then, kindly bear with me and kindly let me know what mistake I could be doing at my end and guide me further.

Thanks and Kind Regards.

----------


## Eduardo-

Thanks for your detailed report.
Updated, please check if everything is working as expected now.

----------


## softv

> Thanks for your detailed report.
> Updated, please check if everything is working as expected now.


Thanks a TON, as always, Eduardo.

I tested to a good extent.

As for mouse actions, all perfect and working as expected.
As for run-time error, all working as expected except in the following case.

1. Add an sst in a form.
2. Open the 'Property Pages' sheet to show up in its 'General' tab.
3. Type '0' for 'TabsPerRow'. i.e change the default value of '3' to '0'. It will get accepted.
4. Type '4' for 'Tab Count'. i.e. change the default value of '3' to '4'.
5. Click 'Apply'. 
6. Run-time error gets displayed.

I was able to produce run-time error in one other case also but it was happening only very rarely and very randomly if I kept repeatedly giving a high value for TabSelExtraHeight. For all practical purposes, nobody is going to do this. So, not to bother about this but I still thought of mentioning it since you asked me to check. That's all.

Thanks a TON, once again, dear Eduardo, for your fabulous control.

Kind regards.

----------


## Eduardo-

Thank you softv, I added the validation so TabsPerRow can't be 0 now.

About TabSelExtraHeight, I think it is not possible to have a problem with its values because they are limited to max the TabHeight, can't be more than that. It means that the active tab can't be taller than twice the other tabs.

Thank you!

----------


## Eduardo-

This control has been superseded by NewTab.

----------

