Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Changing colour of vb6 tab control

967 views
Skip to first unread message

Mojo

unread,
Sep 2, 2009, 5:53:53 PM9/2/09
to
Hi All

I've used the Microsoft Tabbed Dialog control on a test project and although
it's great and being able to position controls on each tab in design time
you don't seem to be able to change the actual controls colour.

If I change the background colour it only changes the tiny corners in the
top left and right of the tab control not the actual tab background.

This all means that I have to change the overall look of my app to the usual
robot style grey bg of old apps when I really want the tabs to haev a white
background.

Is it possible to change the control's BG from boring grey to white??

Thanks


Timo Kunze

unread,
Sep 2, 2009, 6:03:18 PM9/2/09
to
Why not follow the system design and use the system colors? If the user
doesn't like the system colors he or she may change them.
Have you thought about customers of your app that prefer the grey over
white? Or people that prefer apps that match the system's overall design
over apps that don't?

Timo
--
www.TimoSoft-Software.de - Unicode controls for VB6
"Those who sacrifice freedom for safety deserve neither."
"Demokratie ist per Definition unsicher. Ihr Schutz entsteht aus der
Überzeugung, dass die demokratischen Kräfte überwiegen und sich – auf
demokratischem Wege – durchsetzen."

MikeD

unread,
Sep 2, 2009, 9:15:31 PM9/2/09
to

"Timo Kunze" <TKunz...@gmx.de> wrote in message
news:%23rZ$ukBLKH...@TK2MSFTNGP05.phx.gbl...

> Why not follow the system design and use the system colors? If the user
> doesn't like the system colors he or she may change them.
> Have you thought about customers of your app that prefer the grey over
> white? Or people that prefer apps that match the system's overall design
> over apps that don't?
>


While I agree with you 100% regarding system colors, the Tabbed Dialog
doesn't use them for the "pages". Drop one on a form and you'll see. You
*might* be thinking of the TabStrip rather than the Tabbed Dialog. However,
the TabStrip presents a whole other problem.

--
Mike


MikeD

unread,
Sep 2, 2009, 11:05:35 PM9/2/09
to

"Mojo" <ple...@dont.spam.com> wrote in message
news:ejVjzfBL...@TK2MSFTNGP04.phx.gbl...


The answer to your question is no, AFAIK. But keep reading.

As Timo said, you should be sticking with system colors. On your system,
the system color used for tab pages might be whitish (probably not true
white). If you make it white, it might look really bad on other systems
using a different color scheme than you are. Unfortunately, there's no
*easy* way to get this particular system color, but there is a way, which
I'll show you in a bit.

Before that however, I want to comment that you should probably be using the
TabStrip control instead. Most people that use the Tabbed Dialog do so
because it's a container and the TabStrip is not. But even with the Tabbed
Dialog, you should be using PictureBoxes or other container for each tab
because the Tabbed Dialog has a bug/defect where controls may appear on the
wrong tab or not at all (well documented in the newsgroups at least; search
google). This defect is solved by using containers for each tab, just like
you'd do with the TabStrip. And since the TabStrip is a Windows Common
Controls, its appearance is, well, what a tab control should look like.

The problem with the TabStrip is that since you have to use container
controls for each tab (and just like you *should* do with the Tabbed
Dialog), each tab's "page" color is going be that of the container AND the
TabStrip doesn't have a BackColor property (which would make setting each
container's BackColor to match the TabStrip very easy). Furthermore, if you
use a manifest file and the TabStrip from the VB5 Common Controls OCX, your
tabs will look even better under WinXP and later (they'll look like they
really should). But again, there's the problem of getting the tab page
system color to use for the container control of each tab. Under Win2000 and
earlier, this usually isn't a problem if your sticking to system colors
because the TabStrip uses the Button Face system color. However, this is
not so for WinXP and later, so you have to use API functions from
UXTHEME.DLL (and since this DLL only exists in XP and later, you have to be
careful not to call functions from it if running on Win2000 or earlier) to
get the tab control's color. There's also other controls you'll need to set
the BackColor for besides the container. For example, the backcolors of
checkboxes, option buttons, frames, and perhaps other controls should be the
same as the tab's IF those controls are on a tab.

Here's the function (actually, it's a Sub) and API declarations you need:

-----BEGIN CODE

'Constants to retrieve backcolor of TabStrip control when visual styles are
in use
Public Const TMT_FILLCOLORHINT As Long = 3821 'this is the property
Public Const TABP_PANE As Long = 9 'this is the part
Public Const TIS_NORMAL As Long = 1 'this is the state

Public Declare Function GetThemeColor Lib "UxTheme.dll" (ByVal hTheme As
Long, ByVal iPartId As Long, ByVal iStateId As Long, ByVal iPropId As Long,
pColor As Long) As Long
Public Declare Function OpenThemeData Lib "UxTheme.dll" (ByVal hwnd As Long,
ByVal pszClassList As Long) As Long
Public Declare Function IsThemeActive Lib "UxTheme.dll" () As Long
Public Declare Function IsAppThemed Lib "UxTheme.dll" () As Long
Public Declare Function GetWindowTheme Lib "UxTheme.dll" (ByVal hwnd As
Long) As Long
Public Declare Function CloseThemeData Lib "UxTheme.dll" (ByVal hTheme As
Long) As Long

Public Const WM_THEMECHANGED As Long = &H31A&
Public Const S_OK As Long = 0

Private Sub SetTabBackColors()

Dim lTabStripBackColor As Long
Dim hTheme As Long
Dim sClassList As String
Dim oControl As Object

'Get backcolor of TabStrip control. This is more involved than it
should be.
lTabStripBackColor = vbButtonFace 'set default
If IsWinXP Then
If IsAppThemed > 0 Then
sClassList = "TAB"
hTheme = OpenThemeData(Me.hwnd, StrPtr(sClassList))
If hTheme Then
If GetThemeColor(hTheme, TABP_PANE, TIS_NORMAL,
TMT_FILLCOLORHINT, lTabStripBackColor) <> S_OK Then
'The value assigned to lTabStripBackColor gets changed
in the above call, so need to set it
'back to default if function call failed
lTabStripBackColor = vbButtonFace
End If
CloseThemeData hTheme
End If
End If
End If

For Each oControl In Me
Select Case LCase$(TypeName(oControl))
Case "picturebox"
If LCase$(oControl.Name) <> "picservicecallidbutton" Then
oControl.BackColor = lTabStripBackColor
End If
Case "checkbox", "optionbutton", "ctldoc"
'This check is for these controls types on the form but are
not part of a tab page
If TypeOf oControl.Container Is PictureBox Then
oControl.BackColor = lTabStripBackColor
End If
Case "frame"
oControl.BackColor = lTabStripBackColor
End Select
Next

End Sub

----END CODE

This function should be added to each form in your project that has a tab
control. You can call it in Form_Load or anytime after the form is loaded
but not yet shown (I usually have a Public function in each form named Setup
in which I set the size of the form, assign default values to controls, and
do other initialization things and so I call SetTabBackColors in that).

Notice that because the loop goes though every control on the form, the code
includes some exceptions (controls that should not have their backcolor
changed to match the tab control). You'll have to change what these
exceptions are for your own app(s) and chances are they'll be different for
every app and even for different forms in a single app. I always use
PictureBoxes for the container control of each tab and this code reflects
that. Note that there's an exception for a particular PictureBox control.
This is because that PictureBox isn't part of a tab (and it just happens
that on the picservicecallidbutton picturebox, no checkboxes or option
buttons or ctldoc [a usercontrol I created for the app I copied this code
from] were used, so I didn't have to check for these control types being on
that particular picturebox). Depending on your app, it might be easier to
just assign the backcolor to the necessary controls rather than looping
through all controls and writing code for exceptions. You need to decide
that.

The WM_THEMECHANGED constant is a message that Windows sends when the user
changes anything about a theme, which might include the color used for tabs.
If you subclass the form, you can handle this message by calling
SetTabBackColors to reset colors.

Even if you don't want to switch to the TabStrip control, you should still
be able to make use of this. But you would have to use containers for your
tabs (but as I said, that's a good idea anyway). Oh, you'll also need to
write your own IsWinXP function, which should return True for WinXP or later
(IOW, return True for Vista, Win7, Server 2003, and Server 2008).

--
Mike

P.S. If anybody knows an easier or better way to have the proper color for
controls on a TabStrip, I'd love to hear it.

Kevin Provance

unread,
Sep 3, 2009, 12:07:19 AM9/3/09
to

| P.S. If anybody knows an easier or better way to have the proper color for
| controls on a TabStrip, I'd love to hear it.

Subclassing. The same method used to change colours for the status bar,
slider, etc.

I did it for the status bar and once for the tab strip, I just never used
them in production.


Timo Kunze

unread,
Sep 3, 2009, 3:35:35 AM9/3/09
to
Hello Mike,

themed TabStrips don't necessarily use a solid color for the tab pages.
The Luna theme of Windows XP uses a color gradient for instance. You
won't see this on cheap LCD displays, but you will see it on CRT screens
and more expensive LCD displays. Also making a screenshot and analyzing
the RGB colors with a graphics program will reveal the gradient.

I've a TabStrip control on my website which fully supports themes (and
Unicode). It's a container, but not like the Tabbed Dialog control. It
has 1 container for all tab pages, so you still need a frame with an
invisible border for each tab page. On my website there's also a control
library called "ButtonControls" which contains a command button, a check
box, an option button and a frame. All those controls get a transparent
background when placed inside my TabStrip control (that's why the
TabStrip is a container).

Dave O.

unread,
Sep 3, 2009, 8:55:44 AM9/3/09
to

"MikeD" <nob...@nowhere.edu> wrote in message
news:epCqqNEL...@TK2MSFTNGP05.phx.gbl...

>
> "Mojo" <ple...@dont.spam.com> wrote in message
> news:ejVjzfBL...@TK2MSFTNGP04.phx.gbl...

> Mike


>
> P.S. If anybody knows an easier or better way to have the proper color for
> controls on a TabStrip, I'd love to hear it.

Well. you know where the tab control is, so when the form is loading select
the first tab have the caption as a few spaces then get the colours of a
single pixel on the tab then return the caption.
It may not be "better" but I suspect it'll be easier.

I'm not advocating such an approach but it might be worth trying out as it
should work regardless of OS or theme. The only problem I see also affects
your routine and that is that the Tab control is often coloured with a
gradient but this is not apparent on the actual tabs so if your container
covers all the tab pane then the gradient will never be visible.

Regards
Dave O.


0 new messages