NSIS Directory Page without changeable Field - nsis

In the directory page of the NSIS installer I want to show the installation path but without changing it.
I makes in the Directory.nsh EnableWindow for the fields:
;Get control handles
FindWindow $mui.DirectoryPage "#32770" "" $HWNDPARENT
GetDlgItem $mui.DirectoryPage.Text $mui.DirectoryPage 1006
GetDlgItem $mui.DirectoryPage.DirectoryBox $mui.DirectoryPage 1020
GetDlgItem $mui.DirectoryPage.Directory $mui.DirectoryPage 1019
GetDlgItem $mui.DirectoryPage.BrowseButton $mui.DirectoryPage 1001
GetDlgItem $mui.DirectoryPage.SpaceRequired $mui.DirectoryPage 1023
GetDlgItem $mui.DirectoryPage.SpaceAvailable $mui.DirectoryPage 1024
EnableWindow $mui.DirectoryPage.Directory 0
EnableWindow $mui.DirectoryPage.BrowseButton 0
Now the fields are gray and blocked:
But that's not what I want:
the button should disappear
The directory field should be larger and with normal brightness, i.e. a normal field
How do I do it?

As stated in the comments, this is a bad idea. The user can also set a different $InstDir with /D on the command line.
You can make the edit field read-only instead of disabling it, this way the user can at least select/copy the text. The control might still be grayed out, it depends on the active Windows visual style/theme.
You can use MUI_UI and a custom UI file or resize the control at run-time:
InstallDir "$Temp\Whatever"
!include WinMessages.nsh
!include MUI2.nsh
!define MUI_PAGE_CUSTOMFUNCTION_SHOW LockDirPage
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE English
Function LockDirPage
EnableWindow $mui.DirectoryPage.BrowseButton 0
ShowWindow $mui.DirectoryPage.BrowseButton 0
SendMessage $mui.DirectoryPage.Directory ${EM_SETREADONLY} 1 ""
System::Call 'USER32::GetWindowRect(p$mui.DirectoryPage.Directory,#r1)'
System::Call 'USER32::GetWindowRect(p$mui.DirectoryPage.BrowseButton,#r2)'
System::Call *$2(i,i,i.r2)
System::Call *$1(i.r3,i.r4,i,i.r6)
IntOp $3 $2 - $3 ; Width
IntOp $4 $6 - $4 ; Height
System::Call 'USER32::SetWindowPos(p$mui.DirectoryPage.Directory,p0,i0,i0,ir3,ir4,i0x16)'
FunctionEnd

this is my custom page
showing the install path

Related

Remove button pane at the bottom in NSIS installer

I'm using NSIS to create an installer which will only have custom pages.
The custom page shouldn't have the default buttons (back, next or cancel), but only 1 button in the center of the page.
Is there any way I can remove the full bottom pane, as I have highlighted in the image attached ?
I have hid the buttons, but I would like to remove the separator line and the section below it as well.
This is code I have:
;--------------------------------
;Include Modern UI
!include "MUI2.nsh"
;--------------------------------
;General
;Name and file
Name "Custom Test"
OutFile "custom_installer.exe"
;Default installation folder
InstallDir "$LOCALAPPDATA\Custom Test"
;Remove default branding text of Nullsoft
BrandingText " "
;--------------------------------
;Interface Settings
!define MUI_LICENSEPAGE_BGCOLOR "814EFA"
!define MUI_ABORTWARNING
!define MUI_BGCOLOR "000000"
;--------------------------------
;Functions
Function Start
nsDialogs::Create 1044
Pop $0
SetCtlColors $0 222425 FBFBFB
${NSD_CreateButton} 20 170 90% 15u INSTALL
GetDlgItem $0 $HWNDPARENT 3 ; Back Button
GetDlgItem $1 $HWNDPARENT 1 ; Next/Close Button
GetDlgItem $2 $HWNDPARENT 2 ; Cancel Button
ShowWindow $0 ${SW_HIDE}
ShowWindow $1 ${SW_HIDE}
ShowWindow $2 ${SW_HIDE}
nsDialogs::Show
FunctionEnd
;--------------------------------
;Pages
Page custom Start
!insertmacro MUI_PAGE_COMPONENTS
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
Section "Dummy Section" SecDummy
SetOutPath "$INSTDIR"
SectionEnd
And this is how the installer page looks like now:
What about using SetBrandingText " " to hide the horizontal line and coloring the bottom area with SetCtlColors $0 222425 FBFBFB so it will look like the rest of the dialog?
Is that acceptable for you or you want to make the dialog smaller (lower its height)?

NSIS Installer button skinning not working in custom page

I'm creating a custom page for my installer which I have the default buttons (back, next and cancel) hidden and only a custom button (install) is shown.
Problem is that, I'm not able to set the background color of the custom button using skinned controls plugin.
If I show the default buttons, I see the background color applied to them via the bitmap.
This means the skinning is getting applied for the default buttons, but not on the custom button.
Any pointers on what I would be missing ?
Here is the code:
!include "logiclib.nsh"
;--------------------------------
;Include Modern UI
!include "MUI2.nsh"
!include "InstallOptions.nsh"
;--------------------------------
;General
;Name and file
Name "Custom App"
OutFile "custom_installer.exe"
;Default installation folder
InstallDir "$LOCALAPPDATA\Custom Test"
RequestExecutionLevel user
;Remove default branding text of Nullsoft
;BrandingText " "
var title
var description
var button
Var ImageCtrl
Var BmpHandle
;--------------------------------
;Interface Settings
!define MUI_ABORTWARNING
!define Black "814EFA"
!define LightRed "FFFFFF"
!define MUI_CUSTOMFUNCTION_GUIINIT myGUIInit
XPStyle off
;--------------------------------
;Functions
Function .onInit
InitPluginsDir
; Extract bitmaps for buttons
File "/oname=$PLUGINSDIR\button.bmp" "${NSISDIR}\Contrib\SkinnedControls\skins\button_background.bmp"
FunctionEnd
Function myGUIInit
DetailPrint "myGUIInit"
; start the plugin
; the /disabledtextcolor, /selectedtextcolor and /textcolor parameters are optionnal
SkinnedControls::skinit /NOUNLOAD \
/disabledtextcolor=808080 \
/selectedtextcolor=000080 \
/textcolor=000000 \
"/button=$PLUGINSDIR\button.bmp"
FunctionEnd
Function Start
nsDialogs::Create 1044
Pop $0
SetCtlColors $0 222425 FBFBFB
SetCtlColors $HWNDPARENT 222425 FBFBFB
${NSD_CreateLabel} 0 150 100% 24u "Welcome to Custom App"
pop $title
SetCtlColors $title 0x000000 0xFBFBFB
${NSD_AddStyle} $title ${SS_CENTER}
CreateFont $0 "Arial" 24
SendMessage $title ${WM_SETFONT} $0 1
${NSD_CreateLabel} 0 190 100% 28u "By clicking install you agree to the terms of the End $\r$\n User License Agreement"
pop $description
SetCtlColors $description 0x000000 0xFBFBFB
${NSD_AddStyle} $description ${SS_CENTER}
CreateFont $0 "Arial" 14
SendMessage $description ${WM_SETFONT} $0 1
${NSD_CreateButton} 25 250 90% 15u INSTALL
pop $button
;SetCtlColors $button 0x000000 0x0FFFFF
${NSD_AddStyle} $button ${SS_CENTER}
GetDlgItem $0 $HWNDPARENT 3 ; Back Button
GetDlgItem $1 $HWNDPARENT 1 ; Next/Close Button
GetDlgItem $2 $HWNDPARENT 2 ; Cancel Button
;ShowWindow $0 ${SW_HIDE}
;ShowWindow $1 ${SW_HIDE}
;ShowWindow $2 ${SW_HIDE}
GetDlgItem $0 $HWNDPARENT 1035
ShowWindow $0 ${SW_HIDE}
GetDlgItem $0 $HWNDPARENT 1036
ShowWindow $0 ${SW_HIDE}
GetDlgItem $0 $HWNDPARENT 1045
ShowWindow $0 ${SW_HIDE}
GetDlgItem $0 $HWNDPARENT 1028
ShowWindow $0 ${SW_HIDE}
GetDlgItem $0 $HWNDPARENT 1256
ShowWindow $0 ${SW_HIDE}
nsDialogs::Show
${NSD_FreeBitmap} $BmpHandle
FunctionEnd
;--------------------------------
;Pages
Page custom Start
!insertmacro MUI_PAGE_COMPONENTS
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
Section "Dummy Section" SecDummy
SetOutPath "$INSTDIR"
SectionEnd
And here is the current UI (which clearly shows default buttons skinned):
This is a bug in Skinned Control plug-in you use, you need to fix it.
There is a chance some older version had this issue fixed, but your script is not working for me with older version for unknown reasons and I do not remember the details/versions exactly.
I am developer of Graphical Installer (http://www.graphical-installer.com/) mentioned in the Wiki page of that plug-in and I worked on the SkinnedControls plugin some time ago and fixed some issues. But that was almost 10 years ago.
As far as I remember there were some issues with this plug-in because
we wanted to use it in Graphical Installer (tool that allows to skin the whole installer).
However we could not solve all issues so we ended writing custom plugin where the buttons are working fine:
When I have time I will look at this plug-in, meanwhile you can open the project (it is Visual Studio 2008 C++ project I suppose) and debug it. The plugin should enumerate all controls, detect all Buttons (this is probably a problem) and skin them.

Add link to Abort page

As a follow-up to this answer, I'm trying to add the link after issuing Abort command, but for some reason it does not appear, no trace of it when viewed in Spy++.
The idea is to add the link above the progress bar, but somehow the macro does not work. Is there a reason for this that I'm missing and is it possible to add that link after calling Abort? I've read somewhere that Abort command can have different effect so I'm guessing this is one of it.
I've tried to make this sample script as concise as best I can and would greatly appreciate any help as I'm still learning NSIS.
!include "MUI2.nsh"
;--------------------------------
;General
ShowInstDetails hide
SetCompressor /SOLID lzma
;Request application privileges for Windows Vista
RequestExecutionLevel user
;--------------------------------
;Interface Configuration
!define MUI_ABORTWARNING
!define MANUAL_DOWNLOAD_TEXT "Automatic download not working? Click here to download manually."
;--------------------------------
;Macros
!macro AddDownloadLink yCoord
FindWindow $0 "#32770" "" $HWNDPARENT ; Find the inner dialog
System::Call 'USER32::CreateWindowEx(i0, t "STATIC", t "${MANUAL_DOWNLOAD_TEXT}", i${WS_CHILD}|${WS_VISIBLE}|${SS_NOTIFY}, i 1, i ${yCoord}, i 500, i 50, p $0, i 0x666, p 0, p 0)p.s'
Pop $0
SetCtlColors $0 0000ff transparent
CreateFont $1 "$(^Font)" "$(^FontSize)" "400" /UNDERLINE
SendMessage $0 ${WM_SETFONT} $1 1
GetFunctionAddress $1 fnLinkClicked
ButtonEvent::AddEventHandler 0x666 $1
!macroend
;--------------------------------
;Pages
!insertmacro MUI_PAGE_INSTFILES
;--------------------------------
;Languages
!insertmacro MUI_LANGUAGE "English"
;--------------------------------
;Installer Sections
Section
Var /global Filename
StrCpy $Filename "test100Mb.db"
Var /global DownloadUrl
StrCpy $DownloadUrl "http://speedtest.ftp.otenet.gr/files/$Filename"
!insertmacro AddDownloadLink 70
inetc::get /caption "Downloading package" $DownloadUrl "$Filename" /end
Pop $R0 ;Get the return value
StrCmp $R0 "OK" 0 dlfailed
Goto quit
dlfailed:
DetailPrint "Download failed: $R0 $DownloadUrl"
SetDetailsView show
Abort
!insertmacro AddDownloadLink 1
quit:
Quit
SectionEnd
Function fnLinkClicked
ExecShell "open" "$DownloadUrl"
FunctionEnd
Abort stops executing the section(s) code, you must do whatever you need to do before calling Abort.
Adding controls in a section can be problematic because it executes on a different thread and windows are tied to the thread that created them. If you need the window to stick around longer than the install thread you can create it as a hidden window in the instfiles page show callback and simply call ShowWindow in the section when you need to display it...

Custom font on finish page not working

I have code like this
!define MUI_FINISHPAGE_TITLE_3LINES
!define MUI_PAGE_CUSTOMFUNCTION_SHOW WelcomeAndFinishPageShow
!insertmacro MUI_PAGE_FINISH
Function WelcomeAndFinishPageShow
FindWindow $1 "#32770" "" $HWNDPARENT
GetDlgItem $R0 $1 1201
CreateFont $R1 $(^Font) 10 600
SendMessage $R0 ${WM_SETFONT} $R1 0
FunctionEnd
But some how on finish page I am not seeing the changed font size.
Any ideas where I am doing wrong?
First thing you should do is check $R0, if it is 0 then GetDlgItem did not find the label (Those IDs might not be totally stable, different MUI settings might change the order in which controls are created)
If you are using MUI2 there are some (under-documented) variables you can use:
Function WelcomeAndFinishPageShow
CreateFont $R1 "Comic Sans MS" 10 600
SendMessage $mui.WelcomePage.Title ${WM_SETFONT} $R1 0
SendMessage $mui.FinishPage.Title ${WM_SETFONT} $R1 0
FunctionEnd

How can I get a finish button after a nsDialogs page

I'm trying to create a post install configuration page in my nsis script using nsDialogs. My script for gathering the input and executing the configuration works however I'm never presented with a finish/close/exit button after I'm done. Currently my pages declaration looks like:
Page directory
Page instfiles
Page custom nsDialogsPage nsDialogsPageLeave
How can I get a finish/exit/done button to show after nsDialogsPageLeave executes?
The classic NSIS UI does not have a finish page, the instfiles page is usually the last page and it will show a "finish button" after all the sections have executed. You can set the text of any button to the same string with SendMessage $hwndButton ${WM_SETTEXT} 0 "STR:$(^CloseBtn)" if you want to provide your own finish page.
Most installers request the required information before the instfiles page, if you cannot do this then you might want to use the Modern UI, it will provide a finish page for you:
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
Page custom nsDialogsPage nsDialogsPageLeave
!insertmacro MUI_PAGE_FINISH
It was a little unclear to me if you wanted two pages; a input page and then a finish page or a combined input/finish page. A combined page is a little weird but it is possible:
!define AppName "Test"
Name "${AppName}"
Outfile "${AppName} setup.exe"
InstallDir $temp
!include LogicLib.nsh
!include WinMessages.nsh
!include nsDialogs.nsh
Var MyEndConfigPageStage
Page Directory
Page InstFiles
Page Custom MyEndConfigPageCreate MyEndConfigPageLeave /EnableCancel
Function MyEndConfigPageCreate
StrCpy $MyEndConfigPageStage 0
GetDlgItem $0 $hwndparent 1
SendMessage $0 ${WM_SETTEXT} 0 "STR:&Apply"
nsDialogs::Create 1018
Pop $0
${NSD_CreateCheckBox} 0 13u 100% -13u "FooBar"
Pop $1
nsDialogs::Show
FunctionEnd
Function MyEndConfigPageLeave
${If} $MyEndConfigPageStage > 0
Return
${EndIf}
${NSD_GetState} $1 $2
ClearErrors
WriteIniStr "$instdir\settings.ini" Dummy "FooBar" $2
${If} ${Errors}
MessageBox mb_iconstop "Unable to apply settings!"
Abort
${EndIf}
IntOp $MyEndConfigPageStage $MyEndConfigPageStage + 1
GetDlgItem $0 $hwndparent 1
SendMessage $0 ${WM_SETTEXT} 0 "STR:$(^CloseBtn)"
GetDlgItem $0 $hwndparent 2
EnableWindow $0 0 ;Disable cancel
EnableWindow $1 0 ;Disable the checkbox
Abort
FunctionEnd
Section
SectionEnd

Resources