NSIS on HiDPI displays

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
  • mgrand
    Junior Member
    • Jul 2017
    • 8

    NSIS on HiDPI displays

    Hello guys,

    With the growth of HiDPI monitors, I'd like to have my NSIS installer compatible and running to its full potential.
    As suggested by the documentation, I added
    code:
    ManifestDPIAware true
    to my script and it works well for most of the GUI.

    However, I'm running into 2 issues:
    - I provided welcome and header bitmaps at twice the recommended size, and it works on HiDPI displays. But on standard displays, the downsampling applied looks very cheap to me and I would prefer to provide separate bitmaps for each scale factor, is that possible?
    - The checkboxes used in components page are not rescaled on HiDPI (they appear very small). Is there a way to use native Windows checkboxes instead of bitmaps?

    Thanks for the help
  • JasonFriday13
    Major Dude
    • May 2005
    • 930

    #2
    For the checkboxes, I had a quick look at the code and the image list seems to be hardcoded to 16x16.

    I guess if the scaled size of the treeview can be retrieved, then the check bitmap could be resized in memory and then applied to the treeview. This also depends on how old the OS is as to how well this would work.
    "Only a MouseHelmet will save you from a MouseTrap" -Jason Ross (Me)
    NSIS 3 POSIX Ninja
    Wiki Profile

    Comment

    • Anders
      Moderator
      • Jun 2002
      • 5643

      #3
      I tried to create a "native" checkbox plug-in years ago but I never finished it because the theme API does not really support flat checkboxes IIRC.
      IntOp $PostCount $PostCount + 1

      Comment

      • mgrand
        Junior Member
        • Jul 2017
        • 8

        #4
        It would be a nice addition to have flat checkboxes support. Looks like the only missing piece to a fully native-looking GUI.

        Any ideas about welcome & header bitmaps? What's the proper way to have those bitmaps compatible with HiDPI diplays?

        Comment

        • Anders
          Moderator
          • Jun 2002
          • 5643

          #5
          There are some stretch options for the bitmap IIRC but it is never going to look great. You could have images of multiple sizes and extract in .onInit I guess.
          IntOp $PostCount $PostCount + 1

          Comment

          • Anders
            Moderator
            • Jun 2002
            • 5643

            #6
            PHP Code:
            !include LogicLib.nsh
            System
            ::Call USER32::GetDpiForSystem()i.r0
            ${If} $0 U<= 0
                System
            ::Call USER32::GetDC(i0)i.r1
                System
            ::Call GDI32::GetDeviceCaps(ir1,i88)i.r0
                System
            ::Call USER32::ReleaseDC(i0,ir1)
            ${EndIf}
            MessageBox mb_ok SysDpi=$
            and extract with a size based on https://msdn.microsoft.com/en-us/lib...px#CLOSEST_FIT
            int iSourceImageDPIToUse = 96; // We will assume 96 by default.

            if (gDPI > 144)
            iSourceImageDPIToUse = 192;
            else if (gDPI > 120)
            iSourceImageDPIToUse = 144;
            else if (gDPI > 96)
            iSourceImageDPIToUse = 120;
            IntOp $PostCount $PostCount + 1

            Comment

            • mgrand
              Junior Member
              • Jul 2017
              • 8

              #7
              Thanks! I will try that

              Comment

              • Anders
                Moderator
                • Jun 2002
                • 5643

                #8
                I looked at what it takes to create this plug-in again and even before I get to the theme stuff I see that the classic DrawFrameControl function does not know how to draw read-only checkboxes so some post paint tweaking will be required.
                IntOp $PostCount $PostCount + 1

                Comment

                • mgrand
                  Junior Member
                  • Jul 2017
                  • 8

                  #9
                  If anybody interested, here is the piece of code I used to show different bitmaps according to the DPI setting

                  PHP Code:
                  ManifestDPIAware true

                  !define MUI_PAGE_CUSTOMFUNCTION_SHOW showHiDpi
                  !insertmacro MUI_PAGE_WELCOME
                  !insertmacro MUI_PAGE_LICENSE "Resource\license.rtf"
                  !insertmacro MUI_PAGE_COMPONENTS
                  !insertmacro MUI_PAGE_INSTFILES
                  !define MUI_PAGE_CUSTOMFUNCTION_SHOW showHiDpi
                  !insertmacro MUI_PAGE_FINISH

                  Function .onInit
                      File 
                  /oname=$PLUGINSDIR\welcome96.bmp Resource\welcome96.bmp
                      File 
                  /oname=$PLUGINSDIR\welcome120.bmp Resource\welcome120.bmp
                      File 
                  /oname=$PLUGINSDIR\welcome144.bmp Resource\welcome144.bmp
                      File 
                  /oname=$PLUGINSDIR\welcome192.bmp Resource\welcome192.bmp

                      File 
                  /oname=$PLUGINSDIR\header96.bmp Resource\header96.bmp
                      File 
                  /oname=$PLUGINSDIR\header120.bmp Resource\header120.bmp
                      File 
                  /oname=$PLUGINSDIR\header144.bmp Resource\header144.bmp
                      File 
                  /oname=$PLUGINSDIR\header192.bmp Resource\header192.bmp
                  FunctionEnd

                  Function showHiDpi
                      System
                  ::Call USER32::GetDpiForSystem()i.r0 
                      
                  ${If} $0 U<= 
                          System
                  ::Call USER32::GetDC(i0)i.r1 
                          System
                  ::Call GDI32::GetDeviceCaps(ir1,i88)i.r0 
                          System
                  ::Call USER32::ReleaseDC(i0,ir1
                      ${EndIf} 

                      ${
                  Unless} $== 120
                      
                  ${AndUnless} $== 144
                      
                  ${AndUnless} $== 192
                          StrCpy 
                  $0 96
                      
                  ${EndIf}

                      ${
                  NSD_SetImage$mui.WelcomePage.Image $PLUGINSDIR\welcome$0.bmp $mui.WelcomePage.Image.Bitmap
                      
                  ${NSD_SetImage$mui.FinishPage.Image $PLUGINSDIR\welcome$0.bmp $mui.FinishPage.Image.Bitmap
                      SetBrandingImage 
                  /IMGID=1046 "$PLUGINSDIR\header$0.bmp"
                  FunctionEnd 
                  Also, it's important to note that HiDPI bitmaps size is not exactly the standard size multiplied by the scaling factor. Here are the values I used to fit perfectly (at least on Windows 10):

                  Header bitmap:
                  96dpi: 150x57
                  120dpi: 175x70
                  144dpi: 225x83
                  192dpi: 300x109


                  Welcome/Finish bitmap:
                  96dpi: 164x314
                  120dpi: 191x386
                  144dpi: 245x458
                  192dpi: 327x603

                  Comment

                  • Anders
                    Moderator
                    • Jun 2002
                    • 5643

                    #10
                    I would strongly recommend that you use the algorithm I posted, use >=, not == and pick the largest image you can fit.
                    IntOp $PostCount $PostCount + 1

                    Comment

                    • Anders
                      Moderator
                      • Jun 2002
                      • 5643

                      #11
                      Here is a very basic attempt to do native checkboxes, only classic style for now, will investigate themes later.

                      XPStyle on
                      ManifestDPIAware true

                      Page Components "" OnCompShow
                      Page InstFiles


                      Function OnCompShow
                      SysCompImg::ApplyFlat
                      FunctionEnd

                      Section Normal
                      SectionEnd
                      SectionGroup /e Group
                      Section /o UnChecked
                      SectionEnd
                      Section Checked
                      SectionEnd
                      SectionGroupEnd
                      Section /o RO:U
                      SectionIn RO
                      SectionEnd
                      Section RO:C
                      SectionIn RO
                      SectionEnd
                      Let me know how this looks
                      Attached Files
                      IntOp $PostCount $PostCount + 1

                      Comment

                      • mgrand
                        Junior Member
                        • Jul 2017
                        • 8

                        #12
                        It looks good! Checkboxes scale correctly with the DPI.
                        Are they native Windows controls or custom drawing?


                        Originally Posted by Anders View Post
                        I would strongly recommend that you use the algorithm I posted, use >=, not == and pick the largest image you can fit.
                        Right, thanks
                        Attached Files

                        Comment

                        • Anders
                          Moderator
                          • Jun 2002
                          • 5643

                          #13
                          It uses the DrawFrameControl API to draw on a custom imagelist. It is probably the same API used by the classic theme.
                          IntOp $PostCount $PostCount + 1

                          Comment

                          • Anders
                            Moderator
                            • Jun 2002
                            • 5643

                            #14
                            On the theme side of things, on Vista+ the TVS_EX_PARTIALCHECKBOXES style would be usable but TVS_EX_DIMMEDCHECKBOXES cannot be used for the read-only image so there is no way to get native flat themed checkboxes. Next step is to try to use the theme API to draw 3d checkboxes.
                            IntOp $PostCount $PostCount + 1

                            Comment

                            • mgrand
                              Junior Member
                              • Jul 2017
                              • 8

                              #15
                              Thanks for investigating

                              I'm not familiar with neither Windows API nor NSIS internal programming, but wouldn't it make more sense to use native checkbox controls instead, like nsDialogs?

                              Comment

                              Working...
                              X