-
2 Attachment(s)
Fix Visual Styles Issues (Themes)
Hello,
this function will fix properly following issues with Visual Styles (Themes):
- Frame control (black background on controls)
- Focus rectangles not shown
- Accelerator keys not shown
- CommandButton, CheckBox and OptionButton with Graphical Style not themed
In order to use this function you first need to create a manifest:
Code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.0.0" language="*" processorArchitecture="*" publicKeyToken="6595b64144ccf1df"/>
</dependentAssembly>
</dependency>
</assembly>
Or just put attached resource fille into your application. That is the same just compiled into a resource.
This need to be put on the Sub Main:
Code:
Private Sub Main()
Call InitVisualStylesFixes
Form.Show vbModeless
End Sub
To put on every Form Load event:
Code:
Private Sub Form_Load()
Call SetupVisualStylesFixes(Me)
End Sub
To put on every Form Unload event: (Optional)
Code:
Private Sub Form_Unload(Cancel As Integer)
Call RemoveVisualStylesFixes(Me)
End Sub
The Code is too long to put directly here. So I have attached it. (see CodeVisualStyles.txt)
-
Re: Fix Visual Styles Issues (Themes)
Awesome code! This is uber-cool! :thumb: Before, I was using Eduardo Morcillo's MakeXPButton and LaVolpe's "Themes - Frames" and Giorgio Brausi's "Frame 'flickering' in Windows XP Goodbye!", but this code does it all!
P.S.
Is there any reason why the Frame, TextBox, ComboBox and ListBox have their Visual Styles removed? I tried running them with their Visual Styles applied, and they worked OK for me.
-
Re: Fix Visual Styles Issues (Themes)
I am running the common controls 6.0 which don't have the visual styles. Therefore I have removed some controls.
But I have re-uploaded the code without these "removings". :)
There was no reason else.
-
5 Attachment(s)
Fix Visual Styles Issues (Themes) Demo Project
Before and After screenshots: :afrog:
EDIT
See Krool's bugfixes above.
-
Re: Fix Visual Styles Issues (Themes)
A quirk perhaps. The face of a command button with Graphical Style, having no Picture does not reflect it's BackColor property; only its border does.
-
Re: Fix Visual Styles Issues (Themes)
@ Magic Ink
On my system (XP), the same quirk is also present on unsubclassed CommandButtons, especially evident when the BackColor contrasts sharply with the current theme color of the button. I guess it's a cosmetic bug on VB's side.
-
Re: Fix Visual Styles Issues (Themes)
Bonnie,
I do not get that. With no manifest a command button with Graphical Style and BackColor = vbred gives me a button with a red face, on Win2k, XP and W7.
-
Re: Fix Visual Styles Issues (Themes)
With a manifest I still get a button with a red face but it has sharp corners rather than the nice curved ones applied to non-graphical buttons. Using the code above I loose the colored face.
-
Re: Fix Visual Styles Issues (Themes)
You need to use the same BackColor for the graphical button as the container. (normally vbButtonFace)
The graphical button will be drawn with the system theme BackColor.
-
Re: Fix Visual Styles Issues (Themes)
@ Magic Ink
As a work-around, you may want to modify the SetupVisualStyles subroutine in order to exclude particular graphical buttons.
-
Re: Fix Visual Styles Issues (Themes)
Public Enum BOOL
FALSE 
TRUE 
End Enum 'To use, type Ctrl+Space to Complete Word
#If False Then
Dim FALSE , TRUE 
#End If
VB IDE report error. How can you use VB Keyword?
-
Re: Fix Visual Styles Issues (Themes)
FALSE and TRUE are both appended with Chr(160) aka (non-breaking space), ALT-0160 on the numeric keypad. By doing it that way, VB won't see them as a reserved keyword.
-
Re: Fix Visual Styles Issues (Themes)
Great code! But there's one more fix I desperately need for my ageing VB6 app: when applying visual styles, textboxes no longer seem to apply the Font.Charset property. This is a major blow to me as the various edit boxes in the app need to display text based on the user's chosen character set.
The problem is easy to reproduce. Add a textbox to a form, add something like "áé" ("a" with acute, "e" with acute) as its text. Then add a button and, in its Click event, change the charset of the textbox to e.g. Greek: Text1.Font.Charset = 161. In the VB IDE, the characters in the text box will change to Greek (or Turkish or Japanese or whatever charset you selected). When running with visual styles enabled in the compiled app, though, no charset changes occur: selecting Greek, Turkish, Polish makes no difference - the text remains as it was (áé).
A quick aside: Oddly enough, unlike in the VB6 IDE/VB app without manifests, the text box *will* display just about any character from any codepage that you paste into it from Character Map. Suddenly it seems to be 100% Unicode (something we all wanted so much all those years ago!).
-
Re: Fix Visual Styles Issues (Themes)
While you can paste Unicode symbols in and they display that way you can't do anything with them, even via Unicode API calls. That's because the underlying control is still a VB6 ThunderTextBox/ThunderRT6TextBox, which are ANSI controls.
If you really want to do this you might try the InkEdit control. This is included in Vista and later, or XP Tablet Edition, and there is a redist that can be used for plain old XP. The control can be used "inklessly" and seems to be fully Unicode enabled, and they're actually Unicode RTBs with ink entry capability.
-
Re: Fix Visual Styles Issues (Themes)
Thanks for the reply, dilettante. Actually, I'm not worried about the lack of Unicode support. As you rightly point out, the textboxes are still plain old VB6 textboxes. What I'd like to know is why, when themed, they no longer respond to changes to their Font.Charset. Listboxes, listviews, etc. still do, but textboxes don't. Is there a workaround for this?
-
Re: Fix Visual Styles Issues (Themes)
I think it is because inside of the VB6 TextBox is a standard ANSI Edit control. The version in Common Controls 6.0 can accept pasted Unicode but apparently hasn't implemented CharSet as you point out.
I'm not sure what testing might show if you tried using the WM_SETFONT message to alter the Charset. VB6's StdFont objects don't expose (even a hidden) Font handle, so you'd have to resort to the CreateFont() API first.
-
Re: Fix Visual Styles Issues (Themes)
Using WM_SETFONT with CreateFont() didn't help, I'm afraid. Same result. But thanks for the suggestion.
To come so far and be stopped by what should be such a trivial issue is hugely frustrating. :(
-
Re: Fix Visual Styles Issues (Themes)
Well there is always the InkEdit control or even the regular RTB, which can be used as a Unicode control with a few API calls.
-
Re: Fix Visual Styles Issues (Themes)
Thanks again, dilettante. Still no luck, though.
What I need (in order to be able to add visual styles to my app) is a simple non-Unicode edit control that responds to a Font.Charset change when themed. Neither the standard VB6 textbox/richtextbox nor a user control based on RichEdit20A allows this. I've tried sending all three 1) an EM_SETTEXTMODE message with TM_PLAINTEXT | TM_SINGLECODEPAGE; 2) an EM_SETCHARFORMAT message with dwMask = CFM_CHARSET and CHARFORMAT.bCharSet set to the desired character set; and 3) setting the font using CreateFontIndirect. Nothing works.
As I mentioned in my OP, the theme bug (for want of a better word) is very easy to reproduce:
1. Add a text box to a VB6 project and set its text to "á" (lowercase "a" with acute).
2. Add a button which changes the charset of the text box to e.g. Greek (just an example; any charset can be used): Text1.Font.Charset = 161.
Now:
3. Run the app in a non-themed environment and click the button. The "á" in the textbox changes to Greek lowercase alpha ("α"). This is the standard behaviour of my app when running without visual styles and it's the behaviour the whole app is based on and requires.
And now:
4. Run the app in a themed environment and click the button. The "á" in the textbox does not change, no matter how you tell the edit box to change the charset.
I've searched high and low for mention of this behaviour and the only thing I've found is one small line at http://www.cyberactivex.com/UnicodeTutorialVb.htm - "Warning: If you apply an XP Theme to the TextBox below via an IDE Manifest it will display ANSI instead of DBCS." To which I'd add "And changing the TextBox's Font.Charset property will have no effect, either".
-
Re: Fix Visual Styles Issues (Themes)
How about forgoing Visual Styles on that particular TextBox? After all, themed and unthemed TextBoxes don't look noticeably different from each other. The SetWindowTheme API might help in this case.
Code:
Private Declare Function SetWindowTheme Lib "uxtheme.dll" (ByVal hWnd As Long, ByVal pszSubAppName As Long, ByVal pszSubIdList As Long) As Long
Private Sub Form_Load()
SetWindowTheme Text1.hWnd, StrPtr(" "), StrPtr(" ")
End Sub
' Or
Private Declare Function RemoveTheme Lib "uxtheme.dll" Alias "SetWindowTheme" (ByVal hWnd As Long, Optional ByVal pszSubAppName As String = " ", Optional ByVal pszSubIdList As String = " ") As Long
Private Sub Form_Load()
RemoveTheme Text1.hWnd
End Sub
-
Re: Fix Visual Styles Issues (Themes)
Thanks for the idea, Bonnie. I'd actually already tried this and guess what? It makes no difference.
Creating a textbox with CreateWindowEx after the app has loaded, removing its theme and changing its charset with WM_SETFONT doesn't work, either.
-
Re: Fix Visual Styles Issues (Themes)
Quote:
Originally Posted by
Mark Raishbrook
What I need (in order to be able to add visual styles to my app) is a simple non-Unicode edit control that responds to a Font.Charset change when themed.
Well you probably just aren't going to get that.
Can we back up a little? Why are you doing this and what do you want to get out of it? Perhaps there is another way to accomplish what you're after instead of getting there by exploiting a quirk in the older control.
I'd try approaching things that way and creating a question thread in a more appropriate part of the site (like the VB6 Q&A forum) instead of here in the CodeBank. Kind of stated something like "Here is what I am doing and what is now failing. Is there another way to accomplish this?"
-
Re: Fix Visual Styles Issues (Themes)
Apologies if this was the wrong place to post to. The VB6 application I'd like to add visual styles to is a subtitle editor (http://www.spotsoftware.nl/spot.shtml). This means it has to be able to display text in multiple character sets (Western, Central European, Hebrew, Cyrillic, Turkish, Chinese Traditional, etc.). It does this by switching the character set of its main text editing area (just a simple VB multiline textbox) whenever necessary. So that's what I'm doing. It's worked fine for the last 15 years (yes, it's an old app that's been in development a long time!), but breaks when visual styles are added for the reason mentioned above (I can no longer change character sets) and so that's what's failing. Thanks to everyone for their suggestions.
-
Re: Fix Visual Styles Issues (Themes)
No, you sort of hijacked this thread.
CodeBank threads are primarily archival. You really only want to post comments or questions about the code being offered there. For example bugs, how to use the code, whether a new version exists, and so on.
For general questions the Q&A forum is better. If the question is related to a CodeBank thread you can always add a link to the CodeBank thread in your question thread.
-
Re: Fix Visual Styles Issues (Themes)
Request
Kroll, Can you add to your function SetupVisualStyles, support Unicode for form's title(caption)?
I write in each form's this code, from this thread, and it Works
Code:
Private Const WM_GETTEXT = &HD
Private Const WM_GETTEXTLENGTH = &HE
Private Const WM_SETTEXT = &HC
Private Declare Function DefWindowProc Lib "user32.dll" Alias "DefWindowProcW" (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Public Property Let CaptionW(ByVal NewValue As String)
DefWindowProc Me.hWnd, WM_SETTEXT, 0, ByVal StrPtr(NewValue & vbNullChar)
End Property
Public Property Get CaptionW() As String
Dim strLen As Long
strLen = DefWindowProc(Me.hWnd, WM_GETTEXTLENGTH, 0, ByVal 0)
CaptionW = Space$(strLen)
DefWindowProc Me.hWnd, WM_GETTEXT, Len(CaptionW) + 1, ByVal StrPtr(CaptionW & vbNullChar)
End Property
-
Re: Fix Visual Styles Issues (Themes)
Update released.
Following functions got renamed: (others are untouched)
* InitVisualStyles -> InitVisualStylesFixes
* SetupVisualStyles -> SetupVisualStylesFixes
Included following function to undo 'SetupVisualStylesFixes':
* RemoveVisualStylesFixes
RemoveVisualStylesFixes is optional and not needed in production code. However, it can be of use for IDEStop protection handlers.
-
Re: Fix Visual Styles Issues (Themes)
Hey Krool
VBCCR/ActiveX Control Version/Common/VisualStyles.bas
is a greatly stripped-down version of
VBCCR/Standard EXE Version/Common/VisualStyles.bas
e.g. it has no InitVisualStylesFixes routine.
What is the point of VBCCR/ActiveX Control Version/Common/VisualStyles.bas ?
Are these style-related fixes only a problem for the Standard EXE Version?
If I don't want myself or my users to experience visual style issues, and I use the ActiveX Control Version, do I not need to InitVisualStylesFixes or do any of the things you described in the first post?
-
Re: Fix Visual Styles Issues (Themes)
Quote:
Originally Posted by
OldClock
Hey Krool
VBCCR/ActiveX Control Version/Common/VisualStyles.bas
is a greatly stripped-down version of
VBCCR/Standard EXE Version/Common/VisualStyles.bas
e.g. it has no InitVisualStylesFixes routine.
What is the point of VBCCR/ActiveX Control Version/Common/VisualStyles.bas ?
Are these style-related fixes only a problem for the Standard EXE Version?
If I don't want myself or my users to experience visual style issues, and I use the ActiveX Control Version, do I not need to InitVisualStylesFixes or do any of the things you described in the first post?
This is the endless discussion between OCX and Std-EXE.
A OCX (regardless which OCX) is not obliged to fix any visual styles issues. It can have only a stripped down set of function to know if comctl32.dll 5.8x is applicable (not manifested) or 6.x (manifested).
The Std-EXE needs to fix any visual styles issues and also always needs to manifest. The OCX is just attached to the Std-EXE later on and runs in the same process.
-
Re: Fix Visual Styles Issues (Themes)
Thanks, but due to the language barrier (not sure what you mean by "not obliged") and due to my unfamiliarity with OCX I'm still not clear on the situation.
1. The Std-EXE version is susceptible to some visual style bugs. Do these visual style bugs also affect programs using the OCX version?
2. Does using InitVisualStylesFixes/SetupVisualStylesFixes(Me) fix anything when using the OCX version, or should I remove that if it does nothing?
-
Re: Fix Visual Styles Issues (Themes)
Quote:
Originally Posted by
OldClock
Thanks, but due to the language barrier (not sure what you mean by "not obliged") and due to my unfamiliarity with OCX I'm still not clear on the situation.
1. The Std-EXE version is susceptible to some visual style bugs. Do these visual style bugs also affect programs using the OCX version?
2. Does using InitVisualStylesFixes/SetupVisualStylesFixes(Me) fix anything when using the OCX version, or should I remove that if it does nothing?
1. Yes.
2. Yes, use the fixes in a Std-exe project that is linked to the OCX.
-
Re: Fix Visual Styles Issues (Themes)