dcsimg
Results 1 to 31 of 31

Thread: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in Windows 10?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Oct 2014
    Posts
    80

    Resolved [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in Windows 10?

    I have been using the vb6.exe.manifest file for years since the days of Windows XP to enable visual styles and other cool ComCtl v6 features like 32-bit images with transparency in image lists in VB6 IDE. But it seems, this thing no longer works in Windows 10. At least, here is the picture I see when I upload 32-bit images with transparency into vbAccelerator ImageList control in my Windows 10:

    Name:  2017-06-07_17h40_46.jpg
Views: 2769
Size:  56.4 KB

    This approach definitely worked in the previous versions of the OS like Windows 7. Have I missed something when I switched to Windows 10?

  2. #2
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    3,820

    Re: Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in Windows 10

    Do you use an external manifest file?
    I believe dilettante posted somewhere that for manifest files to work on W10 they need to be embedded in the application.

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Oct 2014
    Posts
    80

    Re: Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in Windows 10

    Oh, yes, I needed to mention this explicitly - I am using an external manifest file. Can anybody point me in the right direction - how to embed this manifest into VB6.exe an easy and correct way?

  4. #4
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    3,820

    Re: Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in Windows 10

    On my W7 machine I had a modified VB6.EXE, but on W10 I just use the original version.
    Don't care how it looks in the IDE and when my own applications are compiled I do embed a manifest in the EXE.

    You can use mt.exe to update an executable with a manifest file.
    https://stackoverflow.com/questions/...e-using-mt-exe
    Last edited by Arnoutdv; Jun 8th, 2017 at 03:00 AM.

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Oct 2014
    Posts
    80

    Re: Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in Windows 10

    Tons of thanks!! The following cmd helped me to enable visual styles in VB6 IDE in Windows 10:

    "C:\Program Files (x86)\Windows Kits\10\bin\x86\mt.exe" -nologo -manifest "D:\Development\Manifests\vb6.exe.manifest" -outputresource:"C:\Program Files (x86)\Microsoft Visual Studio\VB98\VB6.EXE;#1"
    The interface items and images in my image list mentioned above look as expected now:

    Name:  2017-06-08_11h33_42.jpg
Views: 2361
Size:  52.5 KB

  6. #6
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    External manifest can still be used, though they have been strongly discouraged for over a decade. Embedded manifests take priority over them unless a registry hack is done to reverse the change in policy since the XP days.

    Most likely they are working for you, but you have run into the caching that Windows does. If you compile and run a program without a manifest, subsequently plopping one alongside the EXE will not take effect immediately.


    If you want to embed manifests in VB6 it is a fairly trivial process.

    Create the manifest file as either an ANSI text file that carefully avoid any non-ASCII characters OR an actual BOM-less UTF-8 file. It is worth the effort to pad the file with spaces to an exact multiple of 4 bytes, just in case you run into DWORD padding woes when you embed it.

    Then add this file as a Custom resource using the IDE Resource Editor add-in. Rename it as Type #24 and ID #1 and then save the .res file.

    When you compile your program, voila!

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Oct 2014
    Posts
    80

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Generally I produce res files with the ComCtl v6 manifest and other useful stuff like 48x48 modern app icons using an .rc template like this:

    #define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
    #define RT_MANIFEST 24
    #define CONTROL_PANEL_RESOURCE_ID 123

    // Icons for this application
    AppIcon ICON MOVEABLE PRELOAD App.ico

    // Visual styles manifest
    CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "XpStyles.exe.manifest"
    I feed it to rc.exe:

    "C:\Program Files\Microsoft Visual Studio\VB98\Wizards\RC.EXE" /r /fo App.res App.rc
    An yes, it seems external manifests still work - even for compiled VB6 executables.

    Quote Originally Posted by dilettante View Post
    Most likely they are working for you, but you have run into the caching that Windows does. If you compile and run a program without a manifest, subsequently plopping one alongside the EXE will not take effect immediately.
    Do you know how to clear this cache to force Windows to use the external manifest file if it is provided?

    And if you can answer, one more related question. As I understand, the 2010 and 2016 versions of MS Access are linked to ComCtl32 v6 using the custom resource with ID 3:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    <assemblyIdentity processorArchitecture="X86" type="win32" name="msaccess" version="14.0.7162.5001"/>
    <description>Microsoft� Office Access</description>
    <dependency optional="yes">
    <dependentAssembly>
    <assemblyIdentity type="win32" name="Microsoft.Windows.Common-Controls" version="6.0.1.0" publicKeyToken="6595b64144ccf1df" language="*" processorArchitecture="*"/>
    </dependentAssembly>
    </dependency>
    </assembly>
    However, the behavior of vbAccelerator ImageList differs in these versions. We can't use images with transparency in Access 2010, though in Access 2016 all works as expected (the property page of the ImageList OCX is also rendered correctly with visual styles in Access 2016 too). Do you know a way how to force Access 2010 to use ComCtl32 v6 in ActiveX's?
    Last edited by wisekat; Jun 9th, 2017 at 04:04 AM.

  8. #8

    Thread Starter
    Lively Member
    Join Date
    Oct 2014
    Posts
    80

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Quote Originally Posted by dilettante View Post
    If you want to embed manifests in VB6 it is a fairly trivial process.

    Create the manifest file as either an ANSI text file that carefully avoid any non-ASCII characters OR an actual BOM-less UTF-8 file. It is worth the effort to pad the file with spaces to an exact multiple of 4 bytes, just in case you run into DWORD padding woes when you embed it.
    Oh, one more question regarding this. Don't we need to also call InitCommonControlsEx in addition to this, as it is stated in the article at vbAccelerator.com I referred in my very first post?

  9. #9
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Quote Originally Posted by wisekat View Post
    Oh, one more question regarding this. Don't we need to also call InitCommonControlsEx in addition to this, as it is stated in the article at vbAccelerator.com I referred in my very first post?
    Yes, you need to
    1) start your app using Sub Main
    2) load shell32 prior to comctl32 (I use dil's method of calling IsUserAnAdmin to force the runtime to manage loading it)
    3) call InitCommonControlsEx or InitCommonControls

    Code:
    Private Declare Function InitShell Lib "shell32" Alias "IsUserAnAdmin" () As Long
    Private Declare Sub InitCommonControls Lib "comctl32" ()
    
    Public Sub Main()
        InitShell
        InitCommonControls
        Form1.Show
    End Sub
    Last edited by DEXWERX; Jun 9th, 2017 at 06:40 AM.

  10. #10
    Member Dragokas's Avatar
    Join Date
    Aug 2015
    Location
    Ukraine
    Posts
    570

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    1) start your app using Sub Main
    or place it inside Form_Initialize().

    Also, use Ex-version, otherwise your program will crash on XP in certain circumstances.
    Code:
    Private Type tagINITCOMMONCONTROLSEX
        dwSize  As Long
        dwICC   As Long
    End Type
    
    Private Declare Function InitShell Lib "shell32" Alias "IsUserAnAdmin" () As Long
    Private Declare Sub InitCommonControls Lib "comctl32" ()
    Private Declare Function InitCommonControlsEx Lib "comctl32.dll" (iccex As Any) As Boolean
    
    Private Const ICC_STANDARD_CLASSES As Long = &H4000&
    
    Private Sub Form_Initialize()
        On Error Resume Next
        
        Dim ICC As tagINITCOMMONCONTROLSEX
    
        With ICC
            .dwSize = Len(ICC)
            .dwICC = ICC_STANDARD_CLASSES
        End With
    
        InitShell
        lr = InitCommonControlsEx(ICC)
    
        If lr = 0 Or Err.Number <> 0 Then
            InitCommonControls ' 9x version
        End If
    end sub

  11. #11

    Thread Starter
    Lively Member
    Join Date
    Oct 2014
    Posts
    80

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    I've looked into my code I have been using for years since the days of WinXP:

    Code:
    Private Sub Form_Initialize()
    ' Initialize Common Control in order to turn on
    ' Windows XP visual styles (if possible).
    ' Use only this approach in VB6 as other approaches may crash your
    ' compiled app which uses UserControls when you terminate the app!
       m_hMod = LoadLibrary("shell32.dll")
       InitCommonControls
    End Sub
    
    Private Sub Form_Unload(Cancel As Integer)
       ' unload shell32.dll - used only to turn on using visual styles
       FreeLibrary m_hMod
    End Sub
    I do not use the *Ex version of InitCommonControls. Is it bad?
    Last edited by wisekat; Jun 9th, 2017 at 10:20 AM. Reason: Placed actual version of my code

  12. #12
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    InitCommonControls() literally does nothing. It is a no-op and has been for a very long time. Calling it via VB's Declare Function causes the DLL to be loaded, something you want to have occur before anything in the runtime or an OCX tries to.

    InitCommonControlsEx() does do something, but unless you are creating controls yourself by pure API calls you don't need it. The VB runtime and any OCXs for use with VB already do that themselves as required.

    It is just a matter of getting the correct DLL assemblies loaded into your process.

  13. #13
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    The manifest cache is cleared every reboot, and as space fills up over time during a Windows run.

    Something that changed in Windows 10 was an enhancement that makes shutdown/startup use a hibernate process in most cases. So restarting a hibernated Windows 10 might possibly leave stuff cached.

  14. #14
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    It's good to know Form_Initialize works because it gets called before any controls are loaded.

    Also I've never seen a crash from not calling InitCommonControlsEx vs InitCommonControls?
    Also if it's just a nop can we just forgo calling either?

  15. #15
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    The purpose is to force loading the correct assembly. You could also just make use of an explicit LoadLibrary call.

    If your code ends up linking to a DLL that loaded the older assembly your process will use that old assembly. The idea is for you to get linked to the newer CC6 DLLs before linking to any other UI DLLs.

  16. #16
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Quote Originally Posted by dilettante View Post
    The purpose is to force loading the correct assembly. You could also just make use of an explicit LoadLibrary call.

    If your code ends up linking to a DLL that loaded the older assembly your process will use that old assembly. The idea is for you to get linked to the newer CC6 DLLs before linking to any other UI DLLs.
    right, so i'm figuring if you trigger the loading if shell32 first, that's all that needs to happen? (I don't actually know I haven't tested this)
    The controls each call InitCommonControlsEx before loading.

  17. #17
    Member Dragokas's Avatar
    Join Date
    Aug 2015
    Location
    Ukraine
    Posts
    570

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    I definitely had a problem with crash on XP with some versions of my programs due to the InitCommonControls preference.
    For some unknown reasons I cannot reproduce it now.

  18. #18
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    As far as I can determine you need to cause shell32.dll to load first, then comctl32.dll, and then you are ok on any version of Windows (er, from XP to present).

    There have always been cases where skipping one or both DLL loads would work... until suddenly the same program just crashes. it probably has to do with what has already been loaded by other processes in the system. DLLs are shared unless isolated through one technique or another.

  19. #19
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    There is a link within my post here:

    http://www.vbforums.com/showthread.p...=1#post5177519

    It has some additional background that may help explain why those DLLs need to get loaded early, for example:

    Also note, that historically some controls used to be implemented in USER32.DLL (window classes like, for example, BUTTON or EDIT), while others (known as common controls) resided in COMCTL32.DLL. This has changed with the introduction of COMCTL32.DLL version 6, and now all theming-aware controls live there.

    Gotcha: The old (unthemed) implementation of standard controls is still available in USER32.DLL. If you instruct the linker to link your application with COMCTL32.DLL, it may silently omit it if the application never calls any function from it. Hence I recommend you to call InitCommonControls() when initializing the application. Otherwise, the app may be just unthemed instead of not working, using the old controls, masking perfectly the root cause of the problem.

  20. #20
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Quote Originally Posted by dilettante View Post
    There is a link within my post here:

    http://www.vbforums.com/showthread.p...=1#post5177519

    It has some additional background that may help explain why those DLLs need to get loaded early, for example:
    Interesting, Thanks for the info. Basically if any control is loaded that doesn't call InitCommonControls/Ex the app may end up using an older (unthemed) control.
    Knowing the history - It's much better being safe than sorry.

  21. #21
    Member Dragokas's Avatar
    Join Date
    Aug 2015
    Location
    Ukraine
    Posts
    570

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Basically if any control is loaded that doesn't call InitCommonControls/Ex the app may end up using an older (unthemed) control.
    You can also manage "themed" of each control
    Code:
    Private Declare Function SetWindowTheme Lib "UxTheme.dll" (ByVal hWnd As Long, ByVal pszSubAppName As Long, ByVal pszSubIdList As Long) As Long
    ...
    ' OFF
    SetWindowTheme Command1.hWnd, StrPtr(" "), StrPtr(" ")
    ...
    ' ON
    SetWindowTheme Command1.hWnd, StrPtr("Explorer"), 0&
    E.g., usefull in XP, where some controls is visually bugged (on frames e.t.c.).
    Attached Files Attached Files

  22. #22

    Thread Starter
    Lively Member
    Join Date
    Oct 2014
    Posts
    80

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Quote Originally Posted by dilettante View Post
    If you want to embed manifests in VB6 it is a fairly trivial process.

    Create the manifest file as either an ANSI text file that carefully avoid any non-ASCII characters OR an actual BOM-less UTF-8 file. It is worth the effort to pad the file with spaces to an exact multiple of 4 bytes, just in case you run into DWORD padding woes when you embed it.

    Then add this file as a Custom resource using the IDE Resource Editor add-in. Rename it as Type #24 and ID #1 and then save the .res file.
    I tried to do this for the sake of interest - to see whether I can complete this task using only VB IDE. And know what? I could not specify the type 24 AS NUMBER for the custom resource with the manifest. Can you tell me the secret how to do that? I always get a string "24" but not 24 as a number if I use the Properties dialog for that:

    Name:  2017-06-15_11h53_46.jpg
Views: 2103
Size:  26.9 KB

    To compare. Here are the same resource editor windows for the resource file that specifies the manifest as a resource correctly (what I created using rc.exe):

    Name:  2017-06-15_11h57_48.jpg
Views: 2054
Size:  26.5 KB

    As you can see, the Type field is even absent!

    P.S. Sorry for these big screens from an UltraHD monitor
    Last edited by wisekat; Jun 15th, 2017 at 04:00 AM.

  23. #23
    Member Dragokas's Avatar
    Join Date
    Aug 2015
    Location
    Ukraine
    Posts
    570

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Use #24, not 24.

  24. #24
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    It is sort of like the confusion produced by implicit type coercion in source code expressions.

    For a Custom resource the Type and Id are always String values. But because every so often you need them to be "Int Resource" format as produced by the MAKEINTRESOURCE macro, the VB Resource Editor add-in accepts a "#" prefix to tell it what to do with the numeric String following it.

    In a way it is like the difference between "1/1/1990" and #1/1/1990# in VB source code.

  25. #25
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,993

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    When you see 24 (not "24") then more than likely the resource file was created with a tool like my Manifest Creator, RC.exe, etc. As mentioned in previous two posts, if adding it with the VB resource editor, then prefix with the # sign.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  26. #26
    VB-aholic & Lovin' It LaVolpe's Avatar
    Join Date
    Oct 2007
    Location
    Beside Waldo
    Posts
    18,993

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Quote Originally Posted by wisekat
    Do you know how to clear this cache to force Windows to use the external manifest file if it is provided?
    See my notes in post #3 here.
    Insomnia is just a byproduct of, "It can't be done"

    Classics Enthusiast? Here's my 1969 Mustang Mach I Fastback. Her sister '67 Coupe has been adopted

    Newbie? Novice? Bored? Spend a few minutes browsing the FAQ section of the forum.
    Read the HitchHiker's Guide to Getting Help on the Forums.
    Here is the list of TAGs you can use to format your posts
    Here are VB6 Help Files online


    {Alpha Image Control} {Memory Leak FAQ} {Unicode Open/Save Dialog} {Resource Image Viewer/Extractor}
    {VB and DPI Tutorial} {Manifest Creator} {UserControl Button Template} {stdPicture Render Usage}

  27. #27
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    The 24 is a MANIFEST resource type, and the VB6 add-in doesn't support adding them. The trick is to use a CUSTOM resource with ID #24, and when it saves as .RES it retains that... but by the time the EXE is created these become MANIFEST (24) type resources.

    You can use ResHacker, etc. to open your compiled EXE and see that.

  28. #28
    PowerPoster
    Join Date
    Feb 2006
    Posts
    20,958

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Windows Vista Sxs Activation Context Cache may have helpful info:

    3. Life time of the cache

    The cache is only stored in memory. The first time CreateActCtx is called, it adds an entry to the cache. Next time when the same CreateActCtx is called, the result is returned from the cache immediately, saving the expensive probing and xml parsing. The cache is lost when the machine reboots.
    5. Cache Key

    The activation context stores the parsed content of all manifests in the full assembly binding closure. Ideally, the cache key should be the path of all the manifests, and their last modified time.

    However, if Sxs uses that as the key to the cache, it means Sxs will have to do all the expensive probing, parsing, which makes the cache useless.

    To make a compromise, Sxs chooses the path of the entry manifest of CreateActCtx and its last modified time as the key. This means, if one of its dependent assemblies has changed, it is necessary to “touch” (i.e. change the last modified time of) the entry manifest for Sxs to see the change.

    Here is an example. You may have a manifest myapp.exe.manifest depending on VC80, and you decides to deploy vc80 privately. So you have a private Microsoft.VC80.CRT.manifest. In Vista, when you change Microsoft.VC80.CRT.manifest, in order for Sxs to see the change in this manifest, you need to change the last modified time of myapp.exe.manifest.

  29. #29

    Thread Starter
    Lively Member
    Join Date
    Oct 2014
    Posts
    80

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    Quote Originally Posted by dilettante View Post
    The 24 is a MANIFEST resource type, and the VB6 add-in doesn't support adding them. The trick is to use a CUSTOM resource with ID #24, and when it saves as .RES it retains that... but by the time the EXE is created these become MANIFEST (24) type resources.

    You can use ResHacker, etc. to open your compiled EXE and see that.
    Yes, you are right. It still looks like "#24" in the native VB6 resource editor:

    Name:  2017-06-16_18h22_10.jpg
Views: 1973
Size:  27.5 KB

    But when I open this exe say in VS 2017 to see its resources, I see this:

    Name:  2017-06-16_18h25_24.jpg
Views: 2040
Size:  30.2 KB

    A miracle

  30. #30
    PowerPoster
    Join Date
    Jun 2015
    Posts
    2,224

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    It's similar to how the Declare statement can be used to Alias a DLL Export by ordinal.

    Code:
    Private Declare Function SetWindowSubclass Lib "comctl32" Alias "#410" (ByVal hWnd As Long, ByVal pfnSubclass As Long, ByVal uIdSubclass As ISubclass, ByVal dwRefData As Long) As Long

  31. #31
    Addicted Member
    Join Date
    Jan 2015
    Posts
    223

    Re: [RESOLVED] Enabling ComCtl 6 in VB6 IDE with the manifest file no longer works in

    sorry, reply to wront thread
    Last edited by loquat; Mar 23rd, 2020 at 07:38 AM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width