Manifests: Make the VB IDE use Windows Vista Styles
|Posted:||Sunday September 07, 2008|
|Updated:||Monday December 26, 2011|
|Applies to:||VB5, VB6|
|Developed with:||VB6, Windows Vista|
|OS restrictions:||Windows Vista (technique may also work with Windows XP - see below)|
Updated Sept 19/08
NOTE: I was contacted by a dev who couldn't achieve Vista themed controls using the info provided below. After some testing it appears that the compiled resource info on this page is correct, but with this caveat:
If you right-click vb6.exe there is a 'compatibility' tab. If compatibility is ticked and set to XP SP2, AND you have a text manifest file in the vb6.exe folder (vb6.exe.manifest, which contains the same text as used in step 4 below or is the same text file used to make the styles appear in the IDE under XP), then in VB6 the controls will appear with the XP/Vista style WITHOUT requiring the compiled resource method described below. That's all you need.
... BUT ...
... if you want to run vb6.exe WITHOUT compatibility mode on, you have to have BOTH the modified vb6.exe with the compiled resource as outlined below, AS WELL AS the plain text manifest file in the vb6.exe folder (the file created in step 4) .
My error comes from not realizing during development of this routine that I had a vb6.exe.manifest file in the vb6.exe folder, and since I don't run vb6.exe in compatibility mode, I thought that performing the steps below was all it took to make vb6 display Vista themes. But it was the combination of both the compiled resource AND the text manifest (though why both are required, I have no idea).
So without compatibility mode turned on, missing either the text manifest file or the compiled manifest resource will cause vb6.exe NOT to display themed controls. Sorry for any confusion.
You run vb6.exe in XP SP2 compatibility mode:
You run vb6.exe without any compatibility set (as I do):
Anyone who has tried Manifests: Make the VB IDE use Windows XP Styles knows how easy it was under XP to get the VB6 IDE to show XP-styled controls (or at least most; VB6 common controls don't use comctl32.dll so they always look like VB controls regardless.) A downside, thought, was under XP, VB forms looked like VB forms.
Under Vista, the simple drop-a-vb6.exe.mainfest-file-in-the-vb6.exe-folder-and-go doesn't work (for those who don't use pre-Vista compatibility per above).
There are two comctl32.dll files in Vista, a version 5 file for backwards compatibility, and a version 6 file with all Vista's bells and whistles. Version 5 lives in \system32 as usual; version 6 is buried under an assembly folder that can't be referenced directly. By default, unless an application has a resource specifying that the version 6 control should be used, the application will use the version 5 control by default. The instructions here show how to get vb6.exe to use comctl32.dll v.6.
The following may seem complicated, so just follow each step carefully. Note that this code presumes you are using Visual Studio 6 which includes both the resource compiler application (rc.exe), as well as Visual C 6.0 itself. If you don't have these, you can use this technique if you have access to any other resource compiler and tool that can insert new resources into executable files.
Also, some code under development at VBnet targets functions that are available only on Vista and that reside in comctl32 version 6 (e.g., the API MessageBox / MessageBoxEx replacement, TaskDialog and TaskDialogIndirect). In order for these demos to work properly in the IDE and not throw an error like that below stating the API can not be found in comctl32, the IDE must have this Vista-manifest resource applied.
One big bonus of incorporating a manifest into vb6.exe is that, at least under Vista, VB forms in both the design-time IDE and when the app is tested from the IDE look like other Vista forms, with the titlebar and form edges taking on the Vista trademark appearance.
But a caveat; in order to have your compiled application use Vista styles, just like XP you must provide an external manifest file (appname.exe.manifest) and call InitCommonControls, or InitCommonControlsEx using the ICC_WIN95_CLASSES flag (&HFF). But unlike XP, the call to the Init API MUST be made from Sub Main inside a BAS module. (XP allowed this to be called from the Initialize event of the form; in Vista this is too late.) You can not, as far as I can tell, embed a resource manifest using the method used here and expect the application to use comctl32 version 6. If in doubt, a simple test it to modify the method below with your specific app name in the appropriate places, then try adding the manifest as a resource to a test app that has just Sub Main and a form with a single command button. If comctl32 version 6 is properly recognized, Vista styles will be applied to the command button on the form. If not, the button will appear as a normal VB gray square button.
So, the process to
make vb6.exe comctl32.dll version 6-aware involves 3 primary steps
(well, 17 steps if you break them down as I do below).
I'd wager this same technique would also work for embedding a manifest resource into vb6.exe for use under XP as well, though I no longer have an XP setup with which to try this. But I digress; so here we go...
Creating the compiled resource (.res) file
1) shut down all sessions of vb6.exe, if running.
2) create a working folder (c:\rctemp in this demo)
3) open notepad
4) paste in the following manifest code:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> <assemblyIdentity version="126.96.36.199" processorArchitecture="X86" name="Microsoft.VB6.VBnetStyles" type="win32" /> <description>VBnet Manifest for VB6 IDE</description> <dependency> <dependentAssembly> <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="188.8.131.52" processorArchitecture="X86" publicKeyToken="6595b64144ccf1df" language="*" /> </dependentAssembly> </dependency> </assembly>
5) save that file in the working folder as vb6.exe.manifest (without the .txt extension)
6) clear notepad, and add the following text:
#define CREATEPROCESS_MANIFEST_RESOURCE_ID 1 #define RT_MANIFEST 24 CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "vb6.exe.manifest"
7) save that file in the working folder as vb6res.rc (without the .txt extension)
8) clear notepad, and add paste in the following two lines.
NOTE: change the paths to both rc.exe, and to your working folder in the three blue highlighted areas below. Double check your typing of these paths are accurate:
"c:\program files\vstudio\common\MSDev98\bin\rc.exe" /r /fo "c:\rctemp\vb6.res" "c:\rctemp\vb6res.rc" pause
9) Save that file
as makerc.bat. At this stage your \rctemp folder should
contain three files:
10) Run the .bat file. On Vista a dialog will pop up stating that the program (rc.exe) has “known compatibility issues” when run on Vista. You can check the “don’t show this message again” box and click Run. If you’ve correctly set the proper paths and filenames in the .bat file, the resulting DOS window should show the command executed successfully (no error) waiting with a ‘press any key to close’ message. If errors are encountered, fix and re-run until you get vb6.res successfully created.
11) Now your \rctemp
folder will contain four files:
VB6.res is the file that will be used in the following steps to modify vb6.exe.
Launching Visual C to open vb6.exe in Resource mode
12) Open Explorer and go to your Visual Studio/Visual Basic folder. Make a copy of vb6.exe for safety (e.g., vb6_orig.exe).
13) Follow these steps closely:
Importing the .res to create a manifest-enabled vb6.exe
14) With vb6.exe open in resource mode, you will see a TreeView of resources already in vb6.exe. If you don't see this TreeView something wasn't done properly in the preceding step, so close vb6.exe and try again. (Say no to the 'save workspace' prompt.)
15) In Visual C a dialog will appear in the workspace.
16) Finally, go to File > Save to write the new vb6.exe file to disk.
17) Now close Visual C, and fire up VB to an existing project, or just add a command button to a form. It should appear with the Vista styles.
1) You MUST have a plain-text manifest file named vb6.exe.manifest in the vb6.exe folder
2) Any applications you develop that need to display Vista styles will need an application.exe.manifest file (same as the vb6.exe.manifest file), AS WELL AS requiring a call to InitCommonControls or InitCommonControlEx (specifying ICC_WIN95_CLASSES), and this API MUST be called from Sub Main in a BAS module when running on Vista. (On XP it was sufficient to call this from form_initiate).