Skip to content
⌘ NSIS Forum Archive

[nsdialogs] How to make icon bigger

21 posts

Pawel#

[nsdialogs] How to make icon bigger

Hi,
I want to use in my nsdialogs custom page, few icons.
I choose to display icons, because they are transparent.
So, here is the code I create icon and display it. Unfortunatelly, the size of icon is default, I think 32x32 (but i am not sure, maybe 16x16). The icon I use, has 128x128 size inside... How to force it to use bigger size?

    Var /Global My_Icon    
    File /oname=$PLUGINSDIR\\My_Icon.ico "test\\My_Icon.ico"
; Icon
    ${NSD_CreateIcon} 15u 40u 100% 100% ""
    Pop $My_Icon
    ${NSD_SetIcon} $My_Icon $PLUGINSDIR\\My_Icon.ico $My_Icon_Handle
...
    ${NSD_FreeIcon} $My_Icon_Handle 
I also tried to add some style, but no success...What am I doing wrong?
    ${NSD_AddStyle} $My_Icon ${SS_REALSIZEIMAGE} 
-Pawel
Pawel#
After I talked with Anders (thanks) I think I found some solutions. I will paste it here,
maybe someone of you need it too...

So,
To display icon with big size, for example 128x128, I prepared such icon and use this code:

File /oname=$PLUGINSDIR\test.ico "test.ico"  ; Hmm, how to display slash here?
File /oname=$PLUGINSDIR\test.bmp "test.bmp"
Var /Global IMAGECTL
Var /Global IMAGE 
; Loading transparent icon with big size!
    nsDialogs::CreateControl STATIC ${WS_VISIBLE}|${WS_CHILD}|${WS_CLIPSIBLINGS}|${SS_ICON} 0 120u 0 100% 100% ""
    Pop $IMAGECTL
    StrCpy $0 $PLUGINSDIR\\test.ico
    System::Call 'user32::LoadImage(i 0, t r0, i ${IMAGE_ICON}, i 0, i 0, i ${LR_LOADFROMFILE}) i.s'
    Pop $IMAGE
    SendMessage $IMAGECTL ${STM_SETIMAGE} ${IMAGE_ICON} $IMAGE 
And, I guess we need to free the resources...
System::Call 'gdi32:DeleteObject(i $IMAGE)' 
We can also use another method. We can use "transparent bitmap". This will display bitmap
with transparent background. Here is an example. You must use 8bpp bitmap.

; Loading Bitmap with transparent background. 8bpp only.
    nsDialogs::CreateControl STATIC ${WS_VISIBLE}|${WS_CHILD}|${WS_CLIPSIBLINGS}|${SS_BITMAP} 0 100u 20u 109u 193u ""
    Pop $IMAGECTL
    StrCpy $0 $PLUGINSDIR\\test.bmp
    System::Call 'user32::LoadImage(i 0, t r0, i ${IMAGE_BITMAP}, i 0, i 0, i ${LR_LOADFROMFILE}|${LR_LOADTRANSPARENT}|${LR_LOADMAP3DCOLORS}) i.s'
    Pop $IMAGE
    SendMessage $IMAGECTL ${STM_SETIMAGE} ${IMAGE_BITMAP} $IMAGE
System::Call 'gdi32:DeleteObject(i $IMAGE)' 
Try it.
If someone think it could be done another way, please share your knowledge.
-Pawel
jiake#
You can delete icons of all size except the 128x128 one by software such as Axialis IconWorkshop, try it.
Pawel#
What do you mean "Delete".
The problem is not how to delete icons, but how to display it on NSIS custom page.
-Pawel

Edit: I think I know what you mean. And it seems it work. Thanks.
ZmAn3#
ive been trying to use the nsdialogs code to load a icon over a background image but the icon doesnt load transparent anyone have any ideas as to why?
code for icon
 nsDialogs::CreateControl STATIC ${WS_VISIBLE}|${WS_CHILD}|${WS_CLIPSIBLINGS}|${SS_ICON} 0 10 0 100% 100% ""
    Pop $IMAGECTL
    StrCpy $0 $PLUGINSDIR\warn.ico
    System::Call 'user32::LoadImage(i 0, t r0, i ${IMAGE_ICON}, i 0, i 0, i ${LR_LOADFROMFILE}) i.s'
    Pop $IMAGE
    SendMessage $IMAGECTL ${STM_SETIMAGE} ${IMAGE_ICON} $IMAGE 
then later i load the background image before nsDialogs::Show
${NSD_CreateBitmap} 0 0 100% 100% "" 
Pop $IMAGECTL
StrCpy $0 $PLUGINSDIR\background.bmp
System::Call 'user32::LoadImage(i 0, t r0, i ${IMAGE_BITMAP}, i 0, i 0, i ${LR_LOADFROMFILE}) i.s'
Pop $IMAGE
SendMessage $IMAGECTL ${STM_SETIMAGE} ${IMAGE_BITMAP} $IMAGE
   ShowWindow $IMAGECTL ${SW_HIDE}
    ShowWindow $IMAGECTL ${SW_SHOW} 
TrifonovS#
Hi!
I don't know is this thread is suitable for my question... However, I need to show an icon in my dialog. The original icon has size 128x128. I want to show it smaller (for example 16x16) and I played with the code, shown above, but the icon is always with the same size. I also got an icon with size 16x16, but it is shown with the same size as the other one. I tried everything, but without success.
I expect that a code like this will work too:

${NSD_CreateIcon} 0 "$1u" 30% 30% ""
Pop $Image1
${NSD_AddStyle} $Image1 ${SS_REALSIZECONTROL}
${NSD_SetIcon} $Image1 ".\Resources\Graphics&UIs\CheckWrong.ico" $ImageHandle1

... but it also doesn't work. Is there anybody who can give me advice how to solve my problem?
Pawel#
Have you tried this (only example, you need to modify):
nsDialogs::CreateControl STATIC ${WS_VISIBLE}|${WS_CHILD}|${WS_CLIPSIBLINGS}|${SS_ICON} 0 120u 0 100% 100% "" 
    Pop $IMAGECTL 
    StrCpy $0 $PLUGINSDIR\\test.ico 
    System::Call 'user32::LoadImage(i 0, t r0, i ${IMAGE_ICON}, i 0, i 0, i ${LR_LOADFROMFILE}) i.s' 
    Pop $IMAGE 
    SendMessage $IMAGECTL ${STM_SETIMAGE} ${IMAGE_ICON} $IMAGE 
...
System::Call 'gdi32:DeleteObject(i $IMAGE)' 
TrifonovS#
Thank you for the reply. I tried it. The size is always the same. I changed the 100% in the nsDialogs::CreateControl to 30% and I also changed the parameters of the function LoadImage (cxDesired and cyDesired according to the MSDN documentation). There is no change. But maybe I miss something?
Pawel#
Maybe you should add to your icon other sizes: You said it is 128x128.
Maybe add desired size to Icon (for example 16x16) and then display it in way as showed in first posts.
TrifonovS#
I made this try too. I used a small icon with size 16x16. When I open it with a graphocal editor I see a small image. But when I compile the installer and start it, I see again bigger image...
jpderuiter#
I think you should use 16 as cxDesired and cyDesired instead of 0 in LoadImage:
Pawel#
I made a quick example:


This example script presents nsdialogs page, that displays 3 icons.
I use here 2 methods. One displays Icon in desired size (so, Icon with only 16x16 image size) will be displayed as 16x16, 32x32 Icon image size will be displayed as 32x32, etc). This is showed for 2 icons in example script.

Second method uses icon that has few image sizes (in this example: 16x16, 32x32, 48x48, 96x96, 128x128, 256x256). You can display icon in whatever size you want.
Check it. I hope this is what you was looking for (and I hope I didnt't make any bug, as I made it quite fast)

Ps: And more info on MSDN, as jpderuiter wrote.

-Pawel
TrifonovS#
I think you should use 16 as cxDesired and cyDesired instead of 0 in LoadImage:
http://msdn.microsoft.com/en-us/libr...(v=vs.85).aspx
I already tried this, but no success.

I made a quick example:


This example script presents nsdialogs page, that displays 3 icons.
I use here 2 methods. One displays Icon in desired size (so, Icon with only 16x16 image size) will be displayed as 16x16, 32x32 Icon image size will be displayed as 32x32, etc). This is showed for 2 icons in example script.

Second method uses icon that has few image sizes (in this example: 16x16, 32x32, 48x48, 96x96, 128x128, 256x256). You can display icon in whatever size you want.
Check it. I hope this is what you was looking for (and I hope I didn't make any bug, as I made it quite fast)

Ps: And more info on MSDN, as jpderuiter wrote.
Thanks a lot. I will check the example immediately and I will publish the result.
TrifonovS#
The test project worked correct. I used some code from it (for the second method) and now it works in my installer too. Thanks a lot for the help from Pawel.
TrifonovS#
I have additional question... I show an icon when the dialog is created. But I also need (depending on a condition that can be fulfilled later) to change the icon after the creation of the dialog. Can I do this?... Or probably the right question is how?
Anders#
Function MyPageCreate
nsDialogs::Create 1018
Pop $0

; Stretch a 32x32+16x16 icon to 128x128:
${NSD_CreateIcon} 0 0 128 128 ""
Pop $0
${NSD_AddStyle} $0 ${SS_REALSIZECONTROL}

${NSD_CreateIcon} 150 0 128 128 ""
Pop $1
${NSD_AddStyle} $1 ${SS_REALSIZECONTROL}

!define NSD_LoadSizedIconFromFileAndSet '!insertmacro NSD_LoadSizedIconFromFileAndSet '
!macro NSD_LoadSizedIconFromFileAndSet hwnd icopath w h icohandle
System::Call 'user32::LoadImage(p0,t"${icopath}",i${IMAGE_ICON},i${w},i${h},i${LR_LOADFROMFILE})i.s'
Pop ${icohandle}
SendMessage ${hwnd} ${STM_SETIMAGE} ${IMAGE_ICON} ${icohandle}
!macroend

${NSD_LoadSizedIconFromFileAndSet} $0 "${NSISDIR}\Contrib\Graphics\Icons\box-install.ico" 128 128 $R0 ; Should select a 128x128 icon if it exists
${NSD_LoadSizedIconFromFileAndSet} $1 "${NSISDIR}\Contrib\Graphics\Icons\box-install.ico" 16 16 $R1 ; Not a good idea when stretching but as a example, use the 16x16 image

nsDialogs::Show
${NSD_FreeIcon} $R0
${NSD_FreeIcon} $R1
FunctionEnd
...and to change the icon you can probably do something like this:

!define NSD_ChangeIcon '!insertmacro NSD_ChangeIcon '
!macro NSD_ChangeIcon hwnd newico tempvar
SendMessage ${hwnd} ${STM_SETIMAGE} ${IMAGE_ICON} ${newico} ${tempvar}
${NSD_FreeIcon} ${tempvar}
!macroend

${NSD_ChangeIcon} $hwndico $icohandle $dummy
StrCpy $oldiconhandletodestroyafterdialog $icohandle
TrifonovS#
Thanks Anders. All these things work perfect. Just to clear something... When I want to change the icon, you suggest to destroy the handle after the exit from the dialog. Actually I make it slightly different, like this:

${NSD_ChangeIcon} $hwndico $icohandle $dummy
${NSD_FreeIcon} $icohandle

I mean that I destroy the handle immediately after SendMessage. It seems that it work well, but do you see a problem with it?
Anders#
Yes there is a problem with doing that. First of all, just because it seems to still draw the icon does not mean that it is actually working. Try minimizing the window, DWM on/off, Themes on/off etc.

LoadImage will sometimes return a special shared handle and calling Free on it has no effect, this should not happen when you load from a external file but who knows, it could still maybe happen.

The STM_SETIMAGE implementation is also free to make a internal copy and use that to draw (It will do that with 32bpp bitmaps) so just because it seems to work does not mean that it is correct or will work on all Windows versions...