Results 1 to 15 of 15

Thread: [RESOLVED] Manifest application styling (a few question)

  1. #1

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    149

    Resolved [RESOLVED] Manifest application styling (a few question)

    Hi there,

    I'm using Manifest application styling method found on this forum:

    - added a manifest file to RES file
    - made a module and then calling InitComCtls

    Resource file content:
    Code:
    #define CREATEPROCESS_MANIFEST_RESOURCE_ID 1
    #define RT_MANIFEST 24
    
    CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "RDWRC.exe.manifest"
    Module content:

    Code:
    Option Explicit
    
    Private Const ICC_STANDARD_CLASSES As Long = &H4000&
    
    Private Type tagINITCOMMONCONTROLSEX
     dwSize  As Long
     dwICC   As Long
    End Type
    
    Private Declare Function InitShell Lib "shell32" Alias "IsUserAnAdmin" () As Long
    Private Declare Function InitCommonControls Lib "comctl32.dll" () As Long
    Private Declare Function InitCommonControlsEx Lib "comctl32.dll" (iccex As Any) As Boolean
    
    
    Public Sub InitComCtls()
     On Error Resume Next
     
     Dim lgRet As Long
     
     Dim ICC As tagINITCOMMONCONTROLSEX
    
     With ICC
      .dwSize = Len(ICC)
      .dwICC = ICC_STANDARD_CLASSES
     End With
    
     Call InitShell
     
     lgRet = InitCommonControlsEx(ICC)
    
     If lgRet = 0 Or Err.Number <> 0 Then
      Call InitCommonControls ' 9x version
     End If
        
     Exit Sub
    End Sub
    Call procedure:

    Code:
    Private Sub Form_Initialize()
     On Error Resume Next
     
     Call InitComCtls
     
     Exit Sub
    End Sub
    The thing is that, how I see, the code above does not have any effect/function, it's working without the code is called.
    Any thoughts about it?

    But my real questions are:

    After implementing the Manifest styling, I can't change the forecolor of any object, I'm talking here especially about Frame forecolor (can't change from blue to black, shown on image bellow).

    And a second thing is that, my Command buttons located in a Frame got black framed arround, but I don't know why.

    These weird things are only shown on Windows XP, but on Windows 7 and Windows 10 are showing up just great.

    Name:  manifest_style.png
Views: 698
Size:  18.3 KB

    Any help would be appreciated!

    Thank you!

  2. #2
    Addicted Member
    Join Date
    Jun 2018
    Posts
    189

    Re: Manifest application styling (a few question)

    Quote Originally Posted by beic View Post

    my Command buttons located in a Frame got black framed arround, but I don't know why.

    These weird things are only shown on Windows XP, but on Windows 7 and Windows 10 are showing up just great.
    Thank you!
    In Windows XP, this happens if you put Command buttons, checkboxes, radiobuttons, ect. in a Frame Control directly. As a workaround, in the frame control, you just put a PictureBox and put command buttons inside the PictureBox and set PictureBox's BorderStyle to None and set its BackColor to the BackColor of the Frame.
    Last edited by PGBSoft; Oct 7th, 2018 at 12:52 PM.

  3. #3

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    149

    Re: Manifest application styling (a few question)

    Quote Originally Posted by PGBSoft View Post
    This happens if you put Command buttons, checkboxes, radiobuttons, ect. in a Frame Control directly. As a workaround, in the frame control, you just put command buttons inside a picturebox and set PictureBox's BorderStyle to None and set BackColor to the BackColor of the Frame.
    Thank you for your fast response and for the workaround suggestion.

    But, is there any advanced solution like API calls or something like that?

  4. #4
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Manifest application styling (a few question)

    The reason to call IsUserAnAdmin and InitCommonControls before any VB6 Forms or controls load is to ensure that the proper versions of the two libraries containing these entrypoints get loaded into the process before the VB6 runtime can screw things up.

    You could just as easily do a LoadLibrary on both shell32 and comctl32 instead, but by rights you should hang onto the handles returned and call FreeLibrary on them before your program exits.

    Both calls are no-ops as far as our programs are concerned. They are just easy tricks to cause the two libraries to be loaded and freed without a lot of fiddling.

    People who call InitCommonControlsEx are just cargo-culting. There is nothing to be gained here if you are using normal VB6 intrinsic controls and OCX controls, since they'll take care of any InitCommonControlsEx calls required by themselves. Sure, you can do it instead of calling InitCommonControls by why jump through the extra hoops? Doing both is just silly.

    Either way you go, these calls are best done in a Sub Main and not deferred until a Form_Initialize event even though you might get away with that most of the time... Right up until it doesn't and then you have a lot of head-scratching to do. Just do it right, do it first thing in Sub Main.


    The UxTheme varies from version to version of Windows but in many places it does take priority over the old-style color attributes of controls. This is intentional. The whole idea of the theming is to give applications a consistent look.


    As far as your "black frame around buttons in a Frame" goes, it is probably an artifact of rendering Win32-based controls like a Command button within the Frame, which is a lightweight ActiveX container control. OLE2 and Win32 GDI sort of "battle it out" over rendering in that scenario. It might look better on a later OS where the Win32 control has changed a bit, but probably not due to any concessions made for the VB6 Frame. It is probably more luck than anything else.

  5. #5
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Manifest application styling (a few question)

    Seriously, this is a forum and not UseNet. There is nothing to be gained by-requoting an entire post in order to reply to it.

  6. #6
    PowerPoster
    Join Date
    Jun 2012
    Posts
    2,371

    Re: Manifest application styling (a few question)

    http://www.vbforums.com/showthread.p...es)&highlight=

    This module will fix the issue with black backgrounds on Frame control in WinXP.

  7. #7

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    149

    Re: Manifest application styling (a few question)

    Quote Originally Posted by dilettante View Post
    The reason to call IsUserAnAdmin and InitCommonControls before any VB6 Forms or controls load is to ensure that the proper versions of the two libraries containing these entrypoints get loaded into the process before the VB6 runtime can screw things up.

    You could just as easily do a LoadLibrary on both shell32 and comctl32 instead, but by rights you should hang onto the handles returned and call FreeLibrary on them before your program exits.

    Both calls are no-ops as far as our programs are concerned. They are just easy tricks to cause the two libraries to be loaded and freed without a lot of fiddling.

    People who call InitCommonControlsEx are just cargo-culting. There is nothing to be gained here if you are using normal VB6 intrinsic controls and OCX controls, since they'll take care of any InitCommonControlsEx calls required by themselves. Sure, you can do it instead of calling InitCommonControls by why jump through the extra hoops? Doing both is just silly.

    Either way you go, these calls are best done in a Sub Main and not deferred until a Form_Initialize event even though you might get away with that most of the time... Right up until it doesn't and then you have a lot of head-scratching to do. Just do it right, do it first thing in Sub Main.
    Okay dilettante,

    Do you maybe have some working example by your side regarding LoadLibrary, shell32, comctl32 and FreeLibrary (copy n' paste)?

    Quote Originally Posted by dilettante View Post
    The UxTheme varies from version to version of Windows but in many places it does take priority over the old-style color attributes of controls. This is intentional. The whole idea of the theming is to give applications a consistent look.
    Any suggestion how can I change the already themed controls color property then?

    Quote Originally Posted by dilettante View Post
    As far as your "black frame around buttons in a Frame" goes, it is probably an artifact of rendering Win32-based controls like a Command button within the Frame, which is a lightweight ActiveX container control. OLE2 and Win32 GDI sort of "battle it out" over rendering in that scenario. It might look better on a later OS where the Win32 control has changed a bit, but probably not due to any concessions made for the VB6 Frame. It is probably more luck than anything else.
    I could use the picturebox workaround, but is there any better solution for that?

    And as I mentioned before on other Windows like 7 and 10 it's showing perfectly.

    on Windows 7 64-bit:
    Name:  manifest_style_win7.png
Views: 578
Size:  24.7 KB

    on Windows 10 64-bit:
    Name:  manifest_style_win10.png
Views: 513
Size:  18.0 KB

    Thank you for your time and for your support!

  8. #8
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Manifest application styling (a few question)

    If you call IsUserAnAdmin and then InitCommonControls ignoring the returned result you get the libraries loaded just fine, and they'll be freed by the VB6 runtime when your program completes.

    I don't bother playing reindeer games with LoadLibrary and FreeLibrary because they offer no advantages over just making the two calls above. If you want to then go right ahead, but I don't have any snippets handy to post here. There just isn't much to it except that you have no reliable point you can call FreeLibrary from.


    The VB6 Frame is a windowless control. As such it doesn't not expose an hWnd property which makes it hard to simply call SetWindowTheme to override the theming it gets.


    No, I have no idea what you can do about changing how controls are rendered within a Frame control. Since the PictureBox is one of the few non-top-level container types we have people use that a lot. The only other alternative that comes to mind is to use UserControls.

    Name:  sshot1.png
Views: 527
Size:  3.4 KB

    Code:
    Option Explicit
    
    Private Enum HRESULT
        S_OK = 0
    End Enum
    
    Private Declare Function SetWindowTheme Lib "UxTheme" ( _
        ByVal hWnd As Long, _
        ByVal pszSubAppName As Long, _
        ByVal pszSubIdList As Long) As HRESULT
    
    Private Sub Form_Initialize()
        SetWindowTheme Command1.hWnd, StrPtr(" "), StrPtr(" ")
        SetWindowTheme Command3.hWnd, StrPtr(" "), StrPtr(" ")
    End Sub
    This code overrides theming on two of the Command buttons.

    We can't do that on a Frame, but we could use our own "UCFrame" container instead which has no default theming of its own. It can be tricky to get its Shape1's border color correct though, which should be done at runtime by fetching it via additional UxTheme.dll calls such as GetThemeSysColor. The colors change with each OS version.

    Name:  sshot2.png
Views: 475
Size:  2.1 KB

    I have no idea what this looks like on Windows XP.


    All of this seems like a lot of work just to have a skinned UI. Why not just avoid fighting Windows and stick with the conventions enforced by the UxTheme system?
    Attached Files Attached Files

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

    Re: Manifest application styling (a few question)

    Krool already posted this --> http://www.vbforums.com/showthread.p...es)&highlight=

    But in case you missed it - his code seems to addresses all of VB6s themeing quirks.

  10. #10

    Thread Starter
    Addicted Member beic's Avatar
    Join Date
    Jun 2012
    Posts
    149

    Re: Manifest application styling (a few question)

    Quote Originally Posted by Krool View Post
    http://www.vbforums.com/showthread.p...es)&highlight=
    This module will fix the issue with black backgrounds on Frame control in WinXP.
    Quote Originally Posted by DEXWERX View Post
    Krool already posted this --> http://www.vbforums.com/showthread.p...es)&highlight=
    But in case you missed it - his code seems to addresses all of VB6s themeing quirks.
    Yes, thank you for that!
    I did not missed it, I already saw that one, but for me, it's just to complicated and a lot of code are involved.
    I like the simpler solution provided by dilettante's UCFrame example in this case.

    Quote Originally Posted by dilettante View Post
    We can't do that on a Frame, but we could use our own "UCFrame" container instead which has no default theming of its own. It can be tricky to get its Shape1's border color correct though, which should be done at runtime by fetching it via additional UxTheme.dll calls such as GetThemeSysColor. The colors change with each OS version.
    I like your UCFrame a lot, but I'm missing the Font properties from it, it's just working fine on Windows XP!

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

    Re: Manifest application styling (a few question)

    You asked for an "advanced solution using API"

    UCFrame is as simple as any custom "skin" which is not aware of themeing.
    Basically it will always look the same on each OS, no matter what version, themeing enabled or not.
    (dillettante did mention this)

    You could easily improve UCFrame by using DrawThemeBackground or DrawFrameControl (when themeing is not available).
    That way at least it will match the OS, and it won't be as complicated as Krool's all in one fixups, that hack the original VB controls.

  12. #12
    PowerPoster
    Join Date
    Feb 2006
    Posts
    24,482

    Re: Manifest application styling (a few question)

    Yeah, it all depends on your needs and how much baggage you are willing to tweak until viable and try to maintain over time.

    A simple-minded "UCFrame" control could be enhanced to have a Font and Caption property, maybe a few more such as an Enabled property... and it might be good enough for many applications. If DrawFrameControl and a few more calls can clean it up further (making it adapt to the OS) those may be worthwhile additions.

    Or you can go a lot further, even to the point of doing up a whole API-based control.

    It is up to you to judge.

    But it seems like a long way to go just to be able to set the color that the caption text gets rendered with.


    Imagine you make it blue, then a user has one of the low-vision accessibilty themes selected where ButtonFace is black. Now your caption becomes hard to read until it is a light shade of blue. If ButtonFace becomes blue then it may become invisible.

    You can get to a point very quickly where a skinned look becomes impractical.

    When selecting system colors, match but don’t mix touches on this briefly.

  13. #13
    PowerPoster wqweto's Avatar
    Join Date
    May 2011
    Location
    Sofia, Bulgaria
    Posts
    5,094

    Re: Manifest application styling (a few question)

    Btw, Krool's code is complicated by Style=Graphical support for various built-in controls.

    If you don't need buttons w/ pictures or have another solution for these (e.g. BS_ICON support in recent OS versions) the "hack" is 50-60 lines in total.

    Edit: Here is a minimal impl of a similar fix for built-in frame control.

    Basicly you need to subclass WM_PRINTCLIENT msg on the frames and don't let VB draw the black backgrounds on buttons etc. child controls and in the meantime prevent WM_MOUSELEAVE reaching original wndproc too, just to reduce the annoying flicker on mouse movement (the frame control redrawing windowless child controls like labels etc.)

    cheers,
    </wqw>

  14. #14
    Hyperactive Member
    Join Date
    Aug 2017
    Posts
    380

    Re: Manifest application styling (a few question)

    Quote Originally Posted by dilettante View Post
    The VB6 Frame is a windowless control. As such it doesn't not expose an hWnd property ...
    You're probably just misremembering, but the intrinsic VB.Frame control does have an hWnd.

    Quote Originally Posted by DEXWERX View Post
    You could easily improve UCFrame by using DrawThemeBackground ...
    Here's an alternative implementation that uses that API: XPFrame User Control.


  15. #15
    PowerPoster
    Join Date
    Jul 2010
    Location
    NYC
    Posts
    5,625

    Re: Manifest application styling (a few question)

    Yeah I was confused by the Frame not having an hWnd comment too. It has an hWnd and is a full fledged window; I routinely use all sorts of APIs on it, set it as a parent, even subclass it. So the SetWindowTheme call should work like any other windowed control then no? IIRC frames drawn with the theme API like Krools are in fact windowless though.

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
  •  



Click Here to Expand Forum to Full Width