Skip to content
⌘ NSIS Forum Archive

Custom Page Checkbox as required

14 posts

ascTim#

Custom Page Checkbox as required

Hey, it's me again.. 😉

I'm sorry to be bothering you again, it seems like I refuse to learn from the NSIS Wiki 😳

1)
I am using a custom page at the end of the installer, including a checkbox.
At the moment, the user can click "Finish" even if the checkbox is not checked and that's what I want to prevent.
How can I do that?

; handle variables
Var hCtl_hinweis
Var hCtl_hinweis_Label1
Var hCtl_hinweis_Label3
Var hCtl_hinweis_CheckBox
Var hCtl_hinweis_Label4
Var hCtl_hinweis_Font1
Var hCtl_hinweis_Font2
; dialog create function
Function fnc_hinweis_Create
  ; custom font definitions
  CreateFont $hCtl_hinweis_Font1 "Microsoft Sans Serif" "9" "400"
  CreateFont $hCtl_hinweis_Font2 "Microsoft Sans Serif" "9" "700"
  ; === hinweis (type: Dialog) ===
  nsDialogs::Create 1018
  Pop $hCtl_hinweis
  ${If} $hCtl_hinweis == error
    Abort
  ${EndIf}
  !insertmacro MUI_HEADER_TEXT "Hinweis" "Bitte beachten Sie - WICHTIG!"
  ; === Label1 (type: Label) ===
  ${NSD_CreateLabel} 8u 10u 280u 68u "Direkt nach diesem Installationschritt MÜSSEN Sie eine Installation auf jedem PC vornehmen, von dem aus ascara-Applikationen aufgerufen werden.$\r$\nFühren Sie dazu das Programm                                               im Verzeichnis ..\ascara\Support\Utilities aus.$\r$\nSofern Sie einen TerminalServer verwenden, müssen die Komponenten auch dort installiert werden!"
  Pop $hCtl_hinweis_Label1
  SendMessage $hCtl_hinweis_Label1 ${WM_SETFONT} $hCtl_hinweis_Font1 0
  ; === Label3 (type: Label) ===
  ${NSD_CreateLabel} 8u 80u 220u 30u "Die Installation dauert nur wenige Augenblicke.$\r$\nBei der Installation handelt es sich um Klassenbibliotheken, Laufzeitumgebungen und das Microsoft .NET Framework."
  Pop $hCtl_hinweis_Label3
  SendMessage $hCtl_hinweis_Label3 ${WM_SETFONT} $hCtl_hinweis_Font1 0
  ; === CheckBox (type: Checkbox) ===
  ${NSD_CreateCheckbox} 8u 115u 111u 14u "Gelesen und akzeptiert"
  Pop $hCtl_hinweis_CheckBox
  GetFunctionAddress $0 OnCheckbox
  nsDialogs::OnClick $hCtl_hinweis_CheckBox $0
  ; === Label4 (type: Label) ===
  ${NSD_CreateLabel} 128u 37u 90u 10u "ascComponents.exe"
  Pop $hCtl_hinweis_Label4
  SendMessage $hCtl_hinweis_Label4 ${WM_SETFONT} $hCtl_hinweis_Font2 0
  
FunctionEnd
; dialog show function
Function fnc_hinweis_Show
  Call fnc_hinweis_Create
  nsDialogs::Show $hCtl_hinweis
FunctionEnd
;Checkbox wird geändert
Function OnCheckbox
         Pop $0
         ${GetTime} "" "L" $0 $1 $2 $3 $4 $5 $6
         DetailPrint "$0/$1/$2 $4:$5:$6 Checkbox 'Gelesen und akzeptiert' bestätigt"
FunctionEnd 
Tell me if you don't need that code so I can remove it to keep the post as short as possible!


2)
I'm writing into the Registry, after that I open up our update.exe file which updates the database of our software if you want to. After writing into Registry, the program skips its actions after pressing the "Yes" or "No" button. If I run the installation a second time it works fine.
So I'm guessing it's the registry which gets updated AFTER the installation is finished.

My question (finally):
Is there any way to refresh the registry while the installation is running?


Thank you very much for your help! 🙂
Anders#
1) Custom pages don't use create+show callbacks, they use a combined createshow so I don't understand why you are trying to fake those. Anyway, to block the user from proceeding you can A) Call abort in the page leave callback or B) Disable the button until the user checks the checkbox by using GetDlgItem+EnableWindow.

2) I don't see any registry code here so it is hard to understand what you are asking about. The NSIS registry functions call RegCloseKey so changes should be flushed pretty quickly, it can however take a couple of seconds according to MSDN. If this is really a problem (investigate with Process Monitor) then you could maybe manually open the key before writing and then call RegFlushKey with the system plugin when you are done but I doubt it will help, see this paragraph on MSDN: "All modifications made to keys are visible to other processes without the need to flush them to disk."...
ascTim#
Originally Posted by Anders View Post
1) Custom pages don't use create+show callbacks, they use a combined createshow so I don't understand why you are trying to fake those. Anyway, to block the user from proceeding you can A) Call abort in the page leave callback or B) Disable the button until the user checks the checkbox by using GetDlgItem+EnableWindow.

2) I don't see any registry code here so it is hard to understand what you are asking about. The NSIS registry functions call RegCloseKey so changes should be flushed pretty quickly, it can however take a couple of seconds according to MSDN. If this is really a problem (investigate with Process Monitor) then you could maybe manually open the key before writing and then call RegFlushKey with the system plugin when you are done but I doubt it will help, see this paragraph on MSDN: "All modifications made to keys are visible to other processes without the need to flush them to disk."...
1) I created this page by using a program called "NSISDialogDesigner". The code you see is what I get when I create the page via this tool. I'm new to custom pages, so I don't really know how to create a custom page by myself.
Should I just use suggestion B) and add "GetDlgItem+EnableWindow" to the function?

2) The installation is running an external program from Gupta, so it's an installation in an installation you could say. I open up that Deploy.exe with "ExecWait"
ExecWait "$INSTDIR\Support\Utilities\Deploy63_TD63_Upd1.exe" 
and then continue by opening up the update.exe. The Deploy.exe writes to the Registry.
Anders#
1)
!include nsDialogs.nsh
Page InstFiles
Page Custom MyPage
Function OnCheckChange
Pop $0
${NSD_GetState} $0 $1
GetDlgItem $2 $hwndparent 1
EnableWindow $2 $1
FunctionEnd
Function MyPage
nsDialogs::Create 1018
Pop $0
${NSD_CreateCheckBox} 0 0 100% 12u "Something important?"
Pop $0
${NSD_OnClick} $0 OnCheckChange
Push $0
Call OnCheckChange ; Generate fake click to initialize the button
nsDialogs::Show
FunctionEnd
2) Are you sure Deploy63_TD63_Upd1.exe is just one process? Sometimes some installers use child processes that they don't wait for, this could explain the registry getting out of sync if you try to run the update right after the ExecWait....
ascTim#
1)
Thank you very much for that code, I'll try it tomorrow. 🙂 🙂

2)
How can I make sure the processes are fully executed? I'm already using ExecWait as you can see.
Anders#
First you need to determine if there are any grandchildren in the first place. If it is too fast to spot in the taskmanager you can use Process Monitor from Microsoft. Pressing Ctrl+T after running the installer should show all processes, even the ones that have exited.

If there is a grandchild process you need to investigate if Deploy63_TD63_Upd1 has any switches to make it wait for children. If it does not you might have to use a NT job object. But even before you get to this point you should add a MessageBox after ExecWait and see if a delay fixes the issue...
ascTim#
Hi Anders,

I've tested your code and it works fine. I've added a Label to that page.
But how can I make my page look like this:
Click image for larger version

Name:	page.PNG
Views:	1
Size:	18.2 KB
ID:	4463656
I want to create a bitmap and "Components.exe" should be bold.
Anders#
Originally Posted by ascTim View Post

But how can I make my page look like this:
[ATTACH]51910[/ATTACH]
I want to create a bitmap and "Components.exe" should be bold.
Creating bold text is hard and I would recommend that you just use a normal label.

If you really must there are at least 3 ways to do it:

1) Create another label on top of the larger label and assign a bold font to it. It is hard to get it in the correct position and bold text might be larger than normal text.

2) Use a web page. http://nsis.sourceforge.net/EmbedHTML_plug-in

3) Use a richedit control to emulate a label. It can probably be done better than my example here.

!include nsDialogs.nsh
!include LogicLib.nsh
!include WinMessages.nsh

!define /math EM_HIDESELECTION ${WM_USER} + 63
!define /math EM_SETBKGNDCOLOR ${WM_USER} + 67
!define ECOOP_SET 1
!define ECO_READONLY 0x00000800
!define /math EM_SETOPTIONS ${WM_USER} + 77
!define /math EM_SETUNDOLIMIT ${WM_USER} + 82
!define /math EM_SETTEXTEX ${WM_USER} + 97

Page Custom MyPage
Page InstFiles

Function MyPage
nsDialogs::Create 1018
Pop $0

nsDialogs::CreateControl "RichEdit20A" ${DEFAULT_STYLES} 0 10u 10u -20u 40u ""
Pop $0
SendMessage $0 ${EM_SETUNDOLIMIT} 0 0
System::Call USER32::GetSysColor(i15)i.r1
SendMessage $0 ${EM_SETBKGNDCOLOR} 0 $1
#SendMessage $0 ${EM_HIDESELECTION} 1 0 ; Does not disable the ability to select text
#EM_SETMARGINS?
#EM_SETEDITSTYLE SES_EXTENDBACKCOLOR|SES_NOIME SES_EXTENDBACKCOLOR|SES_NOIME
#EM_SETLANGOPTIONS IMF_UIFONTS
SendMessage $0 ${EM_SETOPTIONS} ${ECOOP_SET} ${ECO_READONLY}
!if "${NSIS_CHAR_SIZE}" <= 1
System::Call *(i0,i0)i.r1
SendMessage $0 ${EM_SETTEXTEX} $1 "STR:{\rtf1\ansi{\fonttbl\f0\fswiss Helvetica;}\f0\pard$\nThis is some {\b bold} text.$\n\par}" # EM_STREAMIN?
System::Free $1
!endif


File /oname=$PLUGINSDIR\image.bmp "${NSISDIR}\Contrib\Graphics\Header\nsis-r.bmp"
${NSD_CreateBitmap} -99 -55 99 55 ""
Pop $0
${NSD_SetImage} $0 "$PLUGINSDIR\image.bmp" $2

nsDialogs::Show
${NSD_FreeImage} $2
FunctionEnd
ascTim#
Hey there.
I have one (hopefully last) question about the custom pages.

I'm trying to create two Buttons, one of them should start the installed program.
${NSD_CreateButton} 0 0 100% 180u "Start"
${NSD_OnClick} control_HWND function_name 
Is that correct? I'm pretty sure that I have to replace "function_name" by e.g. "OnStart" and then create a function that has the same name.

But what's that "control HWND"?
ascTim#
It now looks like this:

${NSD_CreateButton} 0 0 100% 180u "Start"
Pop $0
${NSD_OnClick} $0 OnStart 
But it does not work yet...
JasonFriday13#
You do have a function for it right?
Function OnStart
MessageBox MB_OK "Button click."
FunctionEnd