Old 18th July 2017, 09:37   #1
mgrand
Junior Member
 
Join Date: Jul 2017
Posts: 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
mgrand is offline   Reply With Quote
Old 18th July 2017, 10:25   #2
JasonFriday13
Major Dude
 
JasonFriday13's Avatar
 
Join Date: May 2005
Location: New Zealand
Posts: 853
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
JasonFriday13 is offline   Reply With Quote
Old 18th July 2017, 11:25   #3
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
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
Anders is offline   Reply With Quote
Old 29th July 2017, 13:57   #4
mgrand
Junior Member
 
Join Date: Jul 2017
Posts: 8
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?
mgrand is offline   Reply With Quote
Old 29th July 2017, 19:15   #5
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
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
Anders is offline   Reply With Quote
Old 31st July 2017, 15:52   #6
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
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
Quote:
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
Anders is offline   Reply With Quote
Old 3rd August 2017, 12:53   #7
mgrand
Junior Member
 
Join Date: Jul 2017
Posts: 8
Thanks! I will try that
mgrand is offline   Reply With Quote
Old 5th August 2017, 18:11   #8
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
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
Anders is offline   Reply With Quote
Old 6th August 2017, 13:32   #9
mgrand
Junior Member
 
Join Date: Jul 2017
Posts: 8
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
mgrand is offline   Reply With Quote
Old 6th August 2017, 13:57   #10
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
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
Anders is offline   Reply With Quote
Old 6th August 2017, 14:16   #11
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
Here is a very basic attempt to do native checkboxes, only classic style for now, will investigate themes later.

Quote:
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
File Type: zip SysCompImg.zip (1.4 KB, 36 views)

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 6th August 2017, 17:58   #12
mgrand
Junior Member
 
Join Date: Jul 2017
Posts: 8
It looks good! Checkboxes scale correctly with the DPI.
Are they native Windows controls or custom drawing?


Quote:
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 Thumbnails
Click image for larger version

Name:	96.PNG
Views:	71
Size:	9.1 KB
ID:	53464   Click image for larger version

Name:	192.PNG
Views:	73
Size:	22.5 KB
ID:	53465  
mgrand is offline   Reply With Quote
Old 6th August 2017, 18:57   #13
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
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
Anders is offline   Reply With Quote
Old 9th August 2017, 19:36   #14
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
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
Anders is offline   Reply With Quote
Old 16th August 2017, 10:02   #15
mgrand
Junior Member
 
Join Date: Jul 2017
Posts: 8
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?
mgrand is offline   Reply With Quote
Old 25th August 2017, 13:14   #16
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
New version.

SetClassic: Classic flat look
SetFlat: Same as classic for now
SetThemed: Themed on XP+, same as SetFlat on <= 2000
GetSysDpi: System DPI in $0
Attached Files
File Type: zip SysCompImg.zip (1.8 KB, 22 views)

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 26th August 2017, 09:06   #17
mgrand
Junior Member
 
Join Date: Jul 2017
Posts: 8
Awesome! The checkboxes now really look consistent with the rest of the GUI
mgrand is offline   Reply With Quote
Old 27th August 2017, 17:26   #18
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
New version, added Unicode and 64-bit builds.

Support for custom bitmaps:

Quote:
Function OnCompShow
SysCompImg::GetSysDpi
${If} $0 > 144
File "/oname=$PluginsDir\check.bmp" "${NSISDIR}\Contrib\Graphics\Checks\big.bmp" ; 192
${ElseIf} $0 > 120
File "/oname=$PluginsDir\check.bmp" "${NSISDIR}\Contrib\Graphics\Checks\red-round.bmp" ; 144
${ElseIf} $0 > 96
File "/oname=$PluginsDir\check.bmp" "${NSISDIR}\Contrib\Graphics\Checks\grey.bmp" ; 120
${Else}
File "/oname=$PluginsDir\check.bmp" "${NSISDIR}\Contrib\Graphics\Checks\simple.bmp" ; 96
${EndIf}
SysCompImg::SetCustom "$PluginsDir\check.bmp"
FunctionEnd
Attached Files
File Type: zip SysCompImg.zip (6.3 KB, 32 views)

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Old 11th September 2017, 17:15   #19
mgrand
Junior Member
 
Join Date: Jul 2017
Posts: 8
Really cool Will this be merged into NSIS?
mgrand is offline   Reply With Quote
Old 11th September 2017, 22:10   #20
Nutzzz
Junior Member
 
Join Date: May 2007
Location: Orange County, CA, U.S.A.
Posts: 11
Yes, thanks for this, @Anders !

I've experimented with this a bit, and another issue is the scrollbars (for, e.g., the License Agreement) are very small.
Nutzzz is offline   Reply With Quote
Old 12th September 2017, 11:39   #21
Anders
Moderator
 
Anders's Avatar
 
Join Date: Jun 2002
Location: ${NSISDIR}
Posts: 4,588
Windows is drawing the scrollbars, not us. There is EnableNonClientDpiScaling but I don't think we can use it. I will investigate PerMonitorAwareV2, we might be able to support that.

IntOp $PostCount $PostCount + 1
Anders is offline   Reply With Quote
Reply
Go Back   Winamp & SHOUTcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump