New paging system. All scripts must be updated, but it sure is worth it. InstallOptions has two new functions initDialog and show. Docs massively updated.

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1536 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2002-11-01 20:34:55 +00:00
parent c3013952c0
commit 6c51b44657
25 changed files with 977 additions and 480 deletions

View file

@ -82,9 +82,9 @@ following values:
<TD vAlign=top bgColor=#cccccc><I>(optional)</I></TD>
<TD vAlign=top bgColor=#eeeeee>Controls whether or not the cancel button in the NSIS window is shown. If set to 1 or omitted, the cancel button will be shown. If set to 0, the cancel button will be hidden.</TD></TR>
<TR>
<TD vAlign=top bgColor=#cccccc><B>BackEnabled</B></TD>
<TD vAlign=top bgColor=#cccccc><B>BackDisabled</B></TD>
<TD vAlign=top bgColor=#cccccc><I>(optional)</I></TD>
<TD vAlign=top bgColor=#eeeeee>Controls whether or not the back button in the NSIS window is enabled. If set to 0 or omitted, the back button will be disabled. If set to 1, the back button will be enabled.</TD></TR>
<TD vAlign=top bgColor=#eeeeee>Controls whether or not the back button in the NSIS window is disabled. If set to 0 or omitted, the back button will be enabled. If set to 1, the back button will be disabled.</TD></TR>
<TR>
<TD vAlign=top bgColor=#cccccc><B>CancelButtonText</B></TD>
<TD vAlign=top bgColor=#cccccc><I>(optional)</I></TD>

View file

@ -44,6 +44,8 @@
*
* - Added Icon and Bitmap controls (by Amir Szekely 4th September 2002)
*
* - Added initDialog and show for support with NSIS's new CreateFont and SetStaticBkColor
*
* Copyright (C) 2001 Michael Bishop
* Portions Copyright (C) 2001 Nullsoft, Inc.
*
@ -166,7 +168,7 @@ char *pszCancelButtonText = NULL;
char *pszNextButtonText = NULL;
char *pszBackButtonText = NULL;
unsigned int nCancelConfirmFlags=0;
BOOL bBackEnabled=FALSE;
BOOL bBackDisabled=FALSE;
BOOL bCancelEnabled=TRUE; // by ORTIM: 13-August-2002
int bCancelShow=1; // by ORTIM: 13-August-2002
@ -309,7 +311,7 @@ bool ValidateFields() {
// this if statement prevents a stupid bug where a min/max length is assigned to a label control
// where the user obviously has no way of changing what is displayed. (can you say, "infinite loop"?)
if (pFields[nIdx].nType >= FIELD_TEXT) {
nLength = GetWindowTextLength(pFields[nIdx].hwnd);
nLength = SendMessage(pFields[nIdx].hwnd, WM_GETTEXTLENGTH, 0, 0);
if (((pFields[nIdx].nMaxLength > 0) && (nLength > pFields[nIdx].nMaxLength)) ||
((pFields[nIdx].nMinLength > 0) && (nLength < pFields[nIdx].nMinLength))) {
@ -374,7 +376,7 @@ bool SaveSettings(void) {
}
default:
{
int nLength = GetWindowTextLength(pFields[nIdx].hwnd);
int nLength = SendMessage(pFields[nIdx].hwnd, WM_GETTEXTLENGTH, 0, 0);
if (nLength > nBufLen) {
FREE(pszBuffer);
// add a bit extra so we do this less often
@ -481,7 +483,7 @@ bool ReadSettings(void) {
nCancelConfirmFlags = LookupTokens(MBFlagTable, szResult);
nNumFields = GetPrivateProfileInt("Settings", "NumFields", 0, pszFilename);
bBackEnabled = GetPrivateProfileInt("Settings", "BackEnabled", 0, pszFilename);
bBackDisabled = GetPrivateProfileInt("Settings", "BackDisabled", 0, pszFilename);
bCancelEnabled = GetPrivateProfileInt("Settings", "CancelEnabled", 1, pszFilename); // by ORTIM: 13-August-2002
bCancelShow = GetPrivateProfileInt("Settings", "CancelShow", 1, pszFilename); // by ORTIM: 13-August-2002
@ -702,66 +704,76 @@ BOOL CALLBACK cfgDlgProc(HWND hwndDlg,
}
}
break;
case WM_CTLCOLORSTATIC:
{
COLORREF color = GetWindowLong((HWND)lParam, GWL_USERDATA);
if (color) {
LOGBRUSH b={BS_SOLID, color-1, 0};
SetBkColor((HDC)wParam, b.lbColor);
return (BOOL)CreateBrushIndirect(&b);
}
}
}
return 0;
}
int nIdx;
HWND childwnd;
int cw_vis;
int was_cancel_enabled;
int was_ok_enabled;
char old_cancel[256];
char old_ok[256];
char old_back[256];
int old_cancel_enabled;
int old_cancel_visible;
char old_title[1024];
extern "C" void __declspec(dllexport) dialog(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop)
int createCfgDlg()
{
hMainWindow=hwndParent;
EXDLL_INIT();
int nIdx;
UINT nAddMsg;
g_is_back=0;
g_is_cancel=0;
if (!hMainWindow)
{
popstring(NULL);
pushstring("error finding mainwnd");
return; // cannot be used in silent mode unfortunately.
return 1; // cannot be used in silent mode unfortunately.
}
HWND childwnd=FindWindowEx(hMainWindow,NULL,"#32770",NULL); // find window to replace
childwnd=FindWindowEx(hMainWindow,NULL,"#32770",NULL); // find window to replace
if (!childwnd) childwnd=GetDlgItem(hMainWindow,1018);
if (!childwnd)
{
popstring(NULL);
pushstring("error finding childwnd");
return;
return 1;
}
if (!stacktop || !*stacktop || !(pszFilename = (*stacktop)->text) || !pszFilename[0] || !ReadSettings())
if (!g_stacktop || !*g_stacktop || !(pszFilename = (*g_stacktop)->text) || !pszFilename[0] || !ReadSettings())
{
popstring(NULL);
pushstring("error finding config");
return;
return 1;
}
int cw_vis=IsWindowVisible(childwnd);
cw_vis=IsWindowVisible(childwnd);
if (cw_vis) ShowWindow(childwnd,SW_HIDE);
int was_cancel_enabled=EnableWindow(GetDlgItem(hMainWindow,IDCANCEL),1);
int was_ok_enabled=EnableWindow(GetDlgItem(hMainWindow,IDOK),1);
static char old_cancel[256];
was_cancel_enabled=EnableWindow(GetDlgItem(hMainWindow,IDCANCEL),1);
was_ok_enabled=EnableWindow(GetDlgItem(hMainWindow,IDOK),1);
GetDlgItemText(hMainWindow,IDCANCEL,old_cancel,sizeof(old_cancel));
if (pszCancelButtonText) SetDlgItemText(hMainWindow,IDCANCEL,pszCancelButtonText);
static char old_ok[256];
GetDlgItemText(hMainWindow,IDOK,old_ok,sizeof(old_ok));
if (pszNextButtonText) SetDlgItemText(hMainWindow,IDOK,pszNextButtonText);
static char old_back[256];
GetDlgItemText(hMainWindow,3,old_back,sizeof(old_back));
if (pszBackButtonText) SetDlgItemText(hMainWindow,3,pszBackButtonText);
int old_back_enabled=!EnableWindow(GetDlgItem(hMainWindow,3),bBackEnabled);
int old_back_visible=IsWindowVisible(GetDlgItem(hMainWindow,3));
ShowWindow(GetDlgItem(hMainWindow,3),bBackEnabled?SW_SHOWNA:SW_HIDE);
EnableWindow(GetDlgItem(hMainWindow,3),!bBackDisabled);
int old_cancel_enabled=!EnableWindow(GetDlgItem(hMainWindow,IDCANCEL),bCancelEnabled); // by ORTIM: 13-August-2002
int old_cancel_visible=IsWindowVisible(GetDlgItem(hMainWindow,IDCANCEL)); // by ORTIM: 13-August-2002
old_cancel_enabled=!EnableWindow(GetDlgItem(hMainWindow,IDCANCEL),bCancelEnabled); // by ORTIM: 13-August-2002
old_cancel_visible=IsWindowVisible(GetDlgItem(hMainWindow,IDCANCEL)); // by ORTIM: 13-August-2002
EnableWindow(GetDlgItem(hMainWindow,IDCANCEL),bCancelEnabled?SW_SHOWNA:SW_HIDE); // by ORTIM: 13-August-2002
ShowWindow(GetDlgItem(hMainWindow,IDCANCEL),bCancelShow?SW_SHOWNA:SW_HIDE); // by ORTIM: 13-August-2002
@ -786,7 +798,7 @@ extern "C" void __declspec(dllexport) dialog(HWND hwndParent, int string_size,
{
popstring(NULL);
pushstring("error creating dialog");
return;
return 1;
}
// by ORTIM: 14-August-2002
@ -972,16 +984,24 @@ extern "C" void __declspec(dllexport) dialog(HWND hwndParent, int string_size,
}
}
static char old_title[1024];
if (pszTitle)
{
GetWindowText(hMainWindow,old_title,sizeof(old_title));
SetWindowText(hMainWindow,pszTitle);
}
char tmp[32];
wsprintf(tmp,"%d",hConfigWindow);
pushstring(tmp);
return 0;
}
void showCfgDlg()
{
ShowWindow(hConfigWindow, SW_SHOWNA);
SetFocus(GetDlgItem(hMainWindow,IDOK));
g_done=0;
while (!g_done) {
MSG msg;
int nResult = GetMessage(&msg, NULL, 0, 0);
@ -1002,12 +1022,9 @@ extern "C" void __declspec(dllexport) dialog(HWND hwndParent, int string_size,
SetDlgItemText(hMainWindow,IDOK,old_ok);
SetDlgItemText(hMainWindow,3,old_back);
EnableWindow(GetDlgItem(hMainWindow,3),old_back_enabled);
EnableWindow(GetDlgItem(hMainWindow,IDCANCEL),old_cancel_enabled); // by ORTIM: 13-August-2002
ShowWindow(GetDlgItem(hMainWindow,IDCANCEL),old_cancel_visible?SW_SHOWNA:SW_HIDE); // by ORTIM: 13-August-2002
ShowWindow(GetDlgItem(hMainWindow,3),old_back_visible?SW_SHOWNA:SW_HIDE);
if (pszTitle) SetWindowText(hMainWindow,old_title);
if (cw_vis) ShowWindow(childwnd,SW_SHOWNA);
@ -1031,7 +1048,48 @@ extern "C" void __declspec(dllexport) dialog(HWND hwndParent, int string_size,
pushstring(g_is_cancel?"cancel":g_is_back?"back":"success");
}
int initCalled;
extern "C" void __declspec(dllexport) dialog(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop)
{
hMainWindow=hwndParent;
EXDLL_INIT();
if (initCalled) {
pushstring("error");
return;
}
if (createCfgDlg()) {
return;
}
popstring(NULL);
showCfgDlg();
}
extern "C" void __declspec(dllexport) initDialog(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop)
{
hMainWindow=hwndParent;
EXDLL_INIT();
if (initCalled) {
pushstring("error");
return;
}
initCalled++;
createCfgDlg();
}
extern "C" void __declspec(dllexport) show(HWND hwndParent, int string_size,
char *variables, stack_t **stacktop)
{
EXDLL_INIT();
if (!initCalled) {
pushstring("error");
return;
}
initCalled--;
showCfgDlg();
}
extern "C" BOOL WINAPI _DllMainCRTStartup(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{

View file

@ -43,7 +43,8 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "INSTOPTDLL_EXPORTS" /YX /FD /c
# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "INSTOPTDLL_EXPORTS" /D "WIN32_LEAN_AND_MEAN" /YX /FD /c
# ADD CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "INSTOPTDLL_EXPORTS" /D "WIN32_LEAN_AND_MEAN" /FD /c
# SUBTRACT CPP /FA<none> /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD BASE RSC /l 0x409 /d "NDEBUG"

View file

@ -14,7 +14,7 @@ Adds a branding image on the top of the installer or on the left. Its size will
\c true|\\<b\\>false\\</b\\>
Controls whether or not installs are enabled to the root directory of a drive, or directly into a network share. Set to 'true' to change the safe behavior, which prevents users from selecting C:\\ or \\\\Server\\Share as an install (and later on, uninstall) directory. For additional directory selection page customizability, see .onVerifyInstDir (\k{onVerifyInstDir}).
Controls whether or not installs are enabled to the root directory of a drive, or directly into a network share. Set to 'true' to change the safe behavior, which prevents users from selecting C:\\ or \\\\Server\\Share as an install (and later on, uninstall) directory. For additional directory selection page customizability, see .onVerifyInstDir (\k{onverifyinstdir}).
\H{aautoclosewindow} AutoCloseWindow

View file

@ -1,4 +1,4 @@
bin\halibut.exe config.but intro.but usage.but script.but attributes.but compilerflags.but sections.but basic.but registry.but generalpurpose.but flowcontrol.but file.but misc.but string.but stack.but int.but reboot.but uninstall.but log.but sec.but functions.but labels.but var.but usection.but callback.but compiler.but defines.but plugin.but history.but modernui.but usefulfunc.but license.but
bin\halibut.exe config.but intro.but usage.but script.but attributes.but compilerflags.but pages.but sections.but basic.but registry.but generalpurpose.but flowcontrol.but file.but misc.but string.but stack.but int.but reboot.but uninstall.but log.but sec.but functions.but labels.but var.but usection.but callback.but compiler.but defines.but plugin.but history.but modernui.but usefulfunc.but license.but
@del *.hlp
@del *.cnt
@copy Contents.html index.html

View file

@ -4,6 +4,22 @@ You can create callback functions which have special names, that will be called
\H{instcallbacks} Install Callbacks
\S{onguiinit} .onGUIInit
This callback will be called just before the first page is loaded and the installer dialog is shown, allowing you to tweak the the user interface.
Example:
\c !insertmacro ${NSISDIR}\Examples\WinMessages.NSH
\c
\c Funciton .onGUIInit
\c # 1028 is the id of the branding text control
\c GetDlgItem $R0 $HWNDPARENT 1028
\c CreateFont $R1 "Tahoma" 10 700
\c SendMessage $R0 ${WM_SETFONT} $R1 0
\c SetStaticBkColor $R0 0x00FFFFFF
\c FunctionEnd
\S{oninit} .onInit
This callback will be called when the installer is nearly finished initializing. If the '.onInit' function calls Abort, the installer will quit instantly.
@ -26,11 +42,7 @@ or:
\c NoAbort:
\c FunctionEnd
\S{oninitdialog} .onInitDialog
This callback is called right after an inner dialog is created (excluding InstallOptions dialogs) and before it is shown. Useful for CreateFont, SetStaticBkColor and any other last minute text changes.
\S{onInstFailed} .onInstFailed
\S{oninstfailed} .onInstFailed
This callback is called when the user hits the 'cancel' button after the install has failed (if it could not extract a file, or the install script used the Abort command).
@ -40,7 +52,7 @@ Example:
\c MessageBox MB_OK "Better luck next time."
\c FunctionEnd
\S{onInstSuccess} .onInstSuccess
\S{oninstsuccess} .onInstSuccess
This callback is called when the install was successful, right before the install window closes (which may be after the user clicks 'Close' if AutoCloseWindow is set to false).
@ -52,7 +64,7 @@ Example:
\c NoReadme:
\c FunctionEnd
\S{onMouseOverSection} .onMouseOverSection
\S{onmouseoversection} .onMouseOverSection
This callback is called whenever the mouse position over the sections tree has changed. This allows you to set a description for each section for example. The section id on which the mouse is over currently is stored, temporarly, in $0.
@ -69,38 +81,7 @@ Example:
\c SendMessage $R0 $\{WM_SETTEXT\} 0 "second section description"
\c FunctionEnd
\S{onNextPage} .onNextPage
Called when the user selects to go from one page to the next. Also called when the first page is shown (after .onInit). Call Abort from this callback in order to make the installer stay on the current page (or to make it move relative to the current page - Abort 0 means to stay put, Abort 1 means to go to the next page, Abort 2 means to go to the following page, Abort -1 means to go back a page, and so on). To figure out which page you are on, you can just keep a counter and increment it on .onNextPage, and decrement it on .onPrevPage. Note that if the directory selection page is disabled, .onNextPage and .onPrevPage are still called for it.
Example use of .onNextPage/.onPrevPage/.onInit:
\c Function .onInit
\c StrCpy $9 0 ; we start on page 0
\c FunctionEnd
\c Function .onNextPage
\c StrCmp $9 1 "" noabort
\c MessageBox MB_YESNO "advance to the second page?" IDYES noabort
\c Abort
\c noabort:
\c IntOp $9 $9 + 1
\c FunctionEnd
\c Function .onPrevPage
\c StrCmp $9 2 "" noabort
\c MessageBox MB_YESNO "go back to the first page?" IDYES noabort
\c Abort
\c noabort:
\c IntOp $9 $9 - 1
\c FunctionEnd
\S{onPrevPage} .onPrevPage
Called when the user selects to go from one page to the previous. Call Abort from this callback in order to make the installer stay on the current page (or pass an integer parameter to Abort to specify how many pages to move: Abort 1 means to go back one page, Abort 2 means to go back two pages, Abort -1 means to go forward a page, and so on). See .onNextPage for more information.
\S{onSelChange} .onSelChange
\S{onselchange} .onSelChange
Called when the selection changes on the component page. Useful for using with SectionSetFlags and SectionGetFlags.
@ -116,7 +97,7 @@ Example:
\c NoCancelAbort:
\c FunctionEnd
\S{onVerifyInstDir} .onVerifyInstDir
\S{onverifyinstdir} .onVerifyInstDir
This callback enables control over whether or not an installation path is valid for your installer. This code will be called every time the user changes the install directory, so it shouldn't do anything crazy with MessageBox or the likes. If this function calls Abort, the installation path in $INSTDIR is deemed invalid.
@ -130,6 +111,12 @@ Example:
\H{uninstcallbacks} Uninstall Callbacks
\S{unonguiinit} un.onGUIInit
This callback will be called just before the first page is loaded and the installer dialog is shown, allowing you to tweak the the user interface.
Have a look at .onGUIInit (\K{onguiinit}) for an example.
\S{unonInit} un.onInit
This callback will be called when the uninstaller is nearly finished initializing. If the 'un.onInit' function calls Abort, the uninstaller will quit instantly. Note that this function can verify and/or modify $INSTDIR if necessary.
@ -151,16 +138,7 @@ or:
\c found:
\c FunctionEnd
\S{unonInitDialog} un.onInitDialog
This callback is called right after an inner dialog is created (excluding InstallOptions dialogs) and before it is shown. Useful for CreateFont, SetStaticBkColor and any other last minute text changes.
\S{unonNextPage} un.onNextPage
Called when the user selects 'Uninstall' or 'Close' from the uninstaller. Call Abort from this callback in order to make the uninstaller stay on the current page.
\S{unonUninstFailed} un.onUninstFailed
\S{unonuninstfailed} un.onUninstFailed
This callback is called when the user hits the 'cancel' button after the uninstall has failed (if it used the Abort command or otherwise failed).
@ -170,7 +148,7 @@ Example:
\c MessageBox MB_OK "Better luck next time."
\c FunctionEnd
\S{unonUninstSuccess} un.onUninstSuccess
\S{unonuninstsuccess} un.onUninstSuccess
This callback is called when the uninstall was successful, right before the install window closes (which may be after the user clicks 'Close' if AutoCloseWindow is set to false).
@ -180,7 +158,7 @@ Example:
\c MessageBox MB_OK "Congrats, it's gone."
\c FunctionEnd
\S{unonUserAbort} un.onUserAbort
\S{unonuserabort} un.onUserAbort
This callback is called when the user hits the 'cancel' button and the uninstall hasn't already failed. If this function calls Abort, the install will not be aborted.

View file

@ -1,22 +1,22 @@
\C{flowcontrol} Flow Control Instructions
\H{Abort} Abort
\H{abort} Abort
\c user_message
Cancels the install, stops execution of script, and displays user_message in the status display. Note: you can use this from Callback Functions (\k{callbacks}) to do special things. Note 2: When using from .onNextPage (\k{onNextPage}) or .onPrevPage (\k{onPrevPage}), the parameter to Abort can be an integer that specifies how many pages to skip.
Cancels the install, stops execution of script, and displays user_message in the status display. Note: you can use this from Callback Functions (\k{callbacks}) to do special things. Pages callbacks (\K{pages}) also uses Abort for special purposes.
\H{Call} Call
\H{call} Call
\c function_name | :label_name
Calls the function named function_name. If in the Uninstall section, Call can only be used with function names beginning with "un.". If the parameter starts with a ':' it will be treated as a label (so you can call to a label in your function - this is probably not going to be used most of the time).
\H{ClearErrors} ClearErrors
\H{clearerrors} ClearErrors
Clears the error flag.
\H{FindWindow} FindWindow
\H{findwindow} FindWindow
\c user_var(hwnd output) windowclass [windowtitle] [windowparent] [childafter]
@ -28,13 +28,13 @@ Searches for a window. Behaves like the win32 FindWindowEx(). Seaches by windowc
Gets the address of the current instruction (the GetCurrentAddress) and stores it in the output user variable. This user variable then can be passed to Call or Goto.
\H{GetDlgItem} GetDlgItem
\H{getdlgitem} GetDlgItem
\c user_var(output) dialog item_id
Retrieves the handle of a control identified by item_id in the specified dialog box dialog. If you want to get the handle of a control on the inner dialog, first use FindWindow user_var(output) "#32770" "" $HWNDPARENT to get the handle of the inner dialog.
\H{GetFunctionAddress} GetFunctionAddress
\H{getfunctionaddress} GetFunctionAddress
\c user_var(output) function_name
@ -56,37 +56,37 @@ If +offset or -offset is specified, jump is relative by offset instructions. Got
If a user variable is specified, jumps to absolute address (generally you will want to get this value from a function like GetLabelAddress. I Compiler flag commands and SectionIn aren't instructions so jumping over them has no effect.
\H{IfErrors} IfErrors
\H{iferrors} IfErrors
\c jumpto_iferror [jumpto_ifnoerror]
Checks and clears the error flag, and if it is set, it will goto jumpto_iferror, otherwise it will goto jumpto_ifnoerror. The error flag is set by other instructions when a recoverable error (such as trying to delete a file that is in use) occurs.
\H{IfFileExists} IfFileExists
\H{iffileexists} IfFileExists
\c file_to_check_for jump_if_present [jump_otherwise]
Checks for existence of file(s) file_to_check_for (which can be a wildcard, or a directory), and Gotos jump_if_present if the file exists, otherwise Gotos jump_otherwise. If you want to check to see if a file is a directory, use IfFileExists DIRECTORY\\*.*
\H{IntCmp} IntCmp
\H{intcmp} IntCmp
\c val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]
Compares two integers val1 and val2. If val1 and val2 are equal, Gotos jump_if_equal, otherwise if val1 < val2, Gotos jump_if_val1_less, otherwise if val1 > val2, Gotos jump_if_val1_more.
\H{IntCmpU} IntCmpU
\H{intcmpu} IntCmpU
\c val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]
Compares two unsigned integers val1 and val2. If val1 and val2 are equal, Gotos jump_if_equal, otherwise if val1 < val2, Gotos jump_if_val1_less, otherwise if val1 > val2, Gotos jump_if_val1_more. Performs the comparison as unsigned integers.
\H{IsWindow} IsWindow
\H{iswindow} IsWindow
\c HWND jump_if_window [jump_if_not_window]
If HWND is a window, Gotos jump_if_window, otherwise, Gotos jump_if_not_window (if specified).
\H{MessageBox} MessageBox
\H{messagebox} MessageBox
\c mb_option_list messagebox_text [return_check jumpto] [return_check_2 jumpto_2]
@ -144,11 +144,11 @@ Return_check can be 0 (or empty, or left off), or one of the following:
If the return value of the MessageBox is return_check, the installer will Goto jumpto.
\H{Return} Return
\H{return} Return
Returns from a function or section.
\H{SendMessage} SendMessage
\H{sendmessage} SendMessage
\c HWND msg wparam lparam [user_var(return value)] [/TIMEOUT=time_in_ms]
@ -166,15 +166,15 @@ To send a string param, put STR: before the parameter, for example: "STR:Some st
Use /TIMEOUT=time_in_ms to specify the duration, in milliseconds, of the time-out period.
\H{Quit} Quit
\H{quit} Quit
Causes the installer to exit as soon as possible. After Quit is called, the installer will exit (no callback functions will get a chance to run).
\H{SetErrors} SetErrors
\H{seterrors} SetErrors
Sets the error flag.
\H{StrCmp} StrCmp
\H{strcmp} StrCmp
\c str1 str2 jump_if_equal [jump_if_not_equal]

View file

@ -2,6 +2,12 @@
\e{v2.0b0}
\b New paging system
\b Added Page and UninstPage
\b Removed .onNextPage, .onPrevPage, .onInitDialog
\b New easier version of the Modern User Interface with better multilanguage support, InstallOptions integration etc.
\b Added accelerator keys

View file

@ -4,59 +4,59 @@
Makes the installer window visible and brings it to the top of the window list (i.e. if a command was executed that shows itself in front of the installer, a BringToFront would bring the installer back in focus).
\H{CreateFont} CreateFont
\H{createfont} CreateFont
\c user_var(handle output) face_name [height] [weight] [/ITALIC] [/UNDERLINE] [/STRIKE]
Creates a font and puts its handle into user_var. For more information about the different parameters have a look at \W{http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/fontext_8fp0.asp}{MSDN's page about the Win32 API function CreateFont()}.
\H{DetailPrint} DetailPrint
\H{detailprint} DetailPrint
\c user_message
Adds the string "user_message" to the details view of the installer.
\H{HideWindow} HideWindow
\H{hidewindow} HideWindow
Hides the installer.
\H{SetAutoClose} SetAutoClose
\H{setautoclose} SetAutoClose
\c true|false
Overrides the default auto window-closing flag (specified for the installer using AutoCloseWindow, and false for the uninstaller). Specify 'true' to have the install window immediately disappear after the install has completed, or 'false' to make it require a manual close.
\H{SetBrandingImage} SetBrandingImage
\H{setbrandingimage} SetBrandingImage
\c [/IMGID=item_id_in_dialog] [/RESIZETOFIT] path_to_bitmap_file.bmp
Sets the current bitmap file displayed as the branding image. If no IMGID is specified, the first image control found will be used, or the image control created by AddBrandingImage. Note that this bitmap must be present on the user's machine. Use File first to put it there. If /RESIZETOFIT is specified the image will be automatically resized (very poorly) to the image control size. If you used AddBrandingImage you can get this size, by compiling your script and watching for AddBrandingImage output, it will tell you the size. SetBrandingImage will not work when called from .onInit!
\H{SetDetailsView} SetDetailsView
\H{setdetailsview} SetDetailsView
\c show|hide
Shows or hides the details, depending on which parameter you pass. Overrides the default details view, which is set via ShowInstDetails
\H{SetDetailsPrint} SetDetailsPrint
\H{setdetailsprint} SetDetailsPrint
\c none|listonly|textonly|both|lastused
Sets mode at which commands print their status. None has commands be quiet, listonly has status text only added to the listbox, textonly has status text only printed to the status bar, and both enables both (the default). For extracting many small files, textonly is recommended (especially on win9x with smooth scrolling enabled).
\H{SetShellVarContext} SetShellVarContext
\H{setshellvarcontext} SetShellVarContext
\c current|all
Sets the context of $SMPROGRAMS and other shell folders. If set to 'current' (the default), the current user's shell folders are used. If set to 'all', the 'all users' shell folder is used. The all users folder may not be supported on all OSes. If the all users folder is not found, the current user folder will be used.
\H{SetStaticBkColor} SetStaticBkColor
\H{setstaticbkcolor} SetStaticBkColor
\c hwnd color
Sets a background color for a static control. Use GetDlgItem to get the handle (HWND) of the static control.
\H{Sleep} Sleep
\H{sleep} Sleep
\c sleeptime_in_ms

68
Docs/src/pages.but Normal file
View file

@ -0,0 +1,68 @@
\C{pages} Pages
Each (non-silent) NSIS installer has a set of pages. Each page can be a NSIS built-in page or a custom page created by a user's function (with InstallOptions for example).
\H{pageoreder} Ordering
The page order is set simply by the order they are in the script. For example:
\c Page license
\c Page components
\c Page directory
\c Page instfiles
This code will show the license page, then the components selction page, then the directory selection page and then the install log, just like in old installers.
Please note that you must still use LicenseText and LicenseData for the license page to show, ComponentText for the components selection page to show and DirText for the directory page to show.
If you don't use any Page command the installer pages order will be just as in older version: license (if LicenseText and LicenseData were specified), components (if ComponentText was specified and there is more than one visible section), directory (if DirText was specified), instfiles.
\H{pagecallbacks} Callbacks
Each built-in page has two callback functions. The pre-function and the post-creation function. The pre-function is called right before the page is created and the post-function is called right after it is created and before it is showed so you can tweak its user interface with CreateFont (\K{createfont}), SetStaticBkColor (\K{setstaticbkcolor}) and SendMessage (\K{sendmessage}).
A custom page has only one callback function that creates it but unlike the built-in pages this function is mandatory.
Abort (see \K{abort}) has special usage from pages' callback functions.
\b Use Abort from a built-in pre-function to skip the page
\b Use Abort from a custom page creator function to go to the previous page
Examples:
\c Page license skipLicense
\c Page custom customPage
\c Page instfiles
\c
\c Function skipLicense
\c MessageBox MB_YES "Do you want to skip the license page?" IDNO no
\c Abort
\c no:
\c FunctionEnd
\c
\c Function customPage
\c GetTempFileName $R0
\c File /oname=$R0 customPage.ini
\c InstallOptions::dialog $R0
\c Delete $R0
\c Pop $R1
\c StrCmp $R1 "cancel" "" nocancel
\c Quit
\c nocancel:
\c StrCmp $R1 "back" "" noback
\c Abort
\c noback:
\c FunctionEnd
\H{page} Page
\c custom function | (license|components|directory|instfiles) [pre_function] [post_function]
Adds an installer page. See the above sections for more information about built-in versus custom pages and about callback functions.
\H{uninstpage} UninstPage
\c custom function | (uninstConfirm|instfiles) [pre_function] [post_function]
Adds an uninstaller page. See the above sections for more information about built-in versus custom pages and about callback functions.

View file

@ -6,6 +6,15 @@
; Written by Amir Szkeley 22nd July 2002
;
!macro BIMAGE IMAGE PARMS
Push $0
GetTempFileName $0
File /oname=$0 "${IMAGE}"
SetBrandingImage ${PARMS} $0
Delete $0
Pop $0
!macroend
Name "Graphical effects"
OutFile "gfx.exe"
@ -26,37 +35,41 @@ LicenseText "Second page"
LicenseData "gfx.nsi"
DirText "Lets make a third page!"
; Pages
Page license licenseImage
Page custom customPage
Page directory dirImage
Page instfiles instImage
Function licenseImage
!insertmacro BIMAGE "${NSISDIR}\Contrib\Icons\checks1.bmp" /RESIZETOFIT
MessageBox MB_YESNO 'Would you like to skip the license page?' IDNO no
Abort
no:
FunctionEnd
Function customPage
!insertmacro BIMAGE "${NSISDIR}\Contrib\Icons\modern.bmp" /RESIZETOFIT
MessageBox MB_YESNO 'This is a nice custom "page" with yet another image :P$\r$\n$\r$\nWould you like to go to the next page now?' IDYES yes
Abort
yes:
FunctionEnd
Function dirImage
!insertmacro BIMAGE "${NSISDIR}\Contrib\Icons\checks2.bmp" /RESIZETOFIT
FunctionEnd
Function instImage
!insertmacro BIMAGE "${NSISDIR}\Contrib\Icons\checks4.bmp" /RESIZETOFIT
FunctionEnd
; Install dir
InstallDir "${NSISDIR}\Examples"
; Branding helper functions
!include "branding.nsh"
Function .onInit
!insertmacro BI_INIT $R0
FunctionEnd
Function .onNextPage
!insertmacro BI_NEXT
FunctionEnd
Function .onPrevPage
!insertmacro BI_PREV
FunctionEnd
!insertmacro BI_LIST
!insertmacro BI_LIST_ADD "${NSISDIR}\Contrib\Icons\checks1.bmp" /RESIZETOFIT
!insertmacro BI_LIST_ADD "${NSISDIR}\Contrib\Icons\checks2.bmp" /RESIZETOFIT
!insertmacro BI_LIST_ADD "${NSISDIR}\Contrib\Icons\checks4.bmp" /RESIZETOFIT
!insertmacro BI_LIST_END
Section
; You can also use the BI_NEXT macro here...
MessageBox MB_YESNO "We can change the branding image from within a section too!$\nDo you want me to change it?" IDNO done
GetTempFileName $1
File /oname=$1 "${NSISDIR}\Contrib\Icons\checksX2.bmp"
SetBrandingImage $1
Delete $1
!insertmacro BIMAGE "${NSISDIR}\Contrib\Icons\checksX2.bmp" ""
done:
WriteUninstaller uninst.exe
SectionEnd
@ -64,23 +77,18 @@ SectionEnd
; Another page for uninstaller
UninstallText "Another page..."
; Uninstall branding helper functions
!define BI_UNINSTALL
!include "branding.nsh"
; Uninstall pages
UninstPage uninstConfirm un.uninstImage
UninstPage instfiles un.instImage
Function un.onInit
!insertmacro BI_INIT $R0
Function un.uninstImage
!insertmacro BIMAGE "${NSISDIR}\Contrib\Icons\checksX.bmp" /RESIZETOFIT
FunctionEnd
Function un.onNextPage
!insertmacro BI_NEXT
Function un.instImage
!insertmacro BIMAGE "${NSISDIR}\Contrib\Icons\jarsonic-checks.bmp" /RESIZETOFIT
FunctionEnd
!insertmacro BI_LIST
!insertmacro BI_LIST_ADD "${NSISDIR}\Contrib\Icons\checksX.bmp" /RESIZETOFIT
!insertmacro BI_LIST_ADD "${NSISDIR}\Contrib\Icons\jarsonic-checks.bmp" /RESIZETOFIT
!insertmacro BI_LIST_END
Section uninstall
MessageBox MB_OK "Bla"
SectionEnd

Binary file not shown.

View file

@ -10,6 +10,7 @@
#include "ResourceEditor.h"
#include "exehead/resource.h"
#include "exehead/lang.h"
void CEXEBuild::define(const char *p, const char *v)
{
@ -281,9 +282,16 @@ CEXEBuild::CEXEBuild()
no_space_texts=false;
#ifdef NSIS_CONFIG_PLUGIN_SUPPORT
build_plugin_unload=0;
#endif
last_used_lang=MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
build_header.common.num_pages=0;
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
build_uninst.common.num_pages=0;
#endif
}
int CEXEBuild::getcurdbsize() { return cur_datablock->getlen(); }
@ -1021,7 +1029,7 @@ int CEXEBuild::resolve_coderefs(const char *str)
{
section *sec=(section *)cur_functions->get();
int l=cur_functions->getlen()/sizeof(section);
entry *w=(entry*)cur_entries->get();
entry *w=(entry *)cur_entries->get();
while (l-- > 0)
{
int x;
@ -1038,6 +1046,19 @@ int CEXEBuild::resolve_coderefs(const char *str)
int x;
for (x = build_uninst.code; x < build_uninst.code+build_uninst.code_size; x ++)
if (resolve_instruction("\"uninstall section\"",str,w+x,x,build_uninst.code,build_uninst.code+build_uninst.code_size)) return 1;
#ifdef NSIS_SUPPORT_CODECALLBACKS
if (ubuild_pages.getlen()) {
page *p=(page *)ubuild_pages.get();
int i = 0;
while (i < build_uninst.common.num_pages) {
if (resolve_call_int("uninstall pages","pre-page function",p->prefunc,&p->prefunc)) return 1;
if (resolve_call_int("uninstall pages","post-page function",p->postfunc,&p->postfunc)) return 1;
p++;
i++;
}
}
#endif
}
else
{
@ -1057,6 +1078,18 @@ int CEXEBuild::resolve_coderefs(const char *str)
sec++;
cnt++;
}
#ifdef NSIS_SUPPORT_CODECALLBACKS
if (build_pages.getlen()) {
page *p=(page *)build_pages.get();
int i = 0;
while (i < build_header.common.num_pages) {
if (resolve_call_int("pages","pre-page function",p->prefunc,&p->prefunc)) return 1;
if (resolve_call_int("pages","post-page function",p->postfunc,&p->postfunc)) return 1;
p++;
i++;
}
}
#endif
}
}
@ -1181,11 +1214,11 @@ int CEXEBuild::write_output(void)
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onUninstSuccess",0),&build_uninst.common.code_onInstSuccess)) return PS_ERROR;
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onUninstFailed",0),&build_uninst.common.code_onInstFailed)) return PS_ERROR;
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onUserAbort",0),&build_uninst.common.code_onUserAbort)) return PS_ERROR;
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onNextPage",0),&build_uninst.common.code_onNextPage)) return PS_ERROR;
#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onInitDialog",0),&build_uninst.common.code_onInitDialog)) return PS_ERROR;
if (resolve_call_int("uninstall callback","un.callbacks",ns_func.find("un.onGUIInit",0),&build_uninst.common.code_onGUIInit)) return PS_ERROR;
#endif
#endif//NSIS_SUPPORT_CODECALLBACKS
if (resolve_coderefs("uninstall")) return PS_ERROR;
set_uninstall_mode(0);
}
@ -1204,10 +1237,8 @@ int CEXEBuild::write_output(void)
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onInstFailed",0),&build_header.common.code_onInstFailed)) return PS_ERROR;
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onUserAbort",0),&build_header.common.code_onUserAbort)) return PS_ERROR;
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onVerifyInstDir",0),&build_header.code_onVerifyInstDir)) return PS_ERROR;
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onNextPage",0),&build_header.common.code_onNextPage)) return PS_ERROR;
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onPrevPage",0),&build_header.code_onPrevPage)) return PS_ERROR;
#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onInitDialog",0),&build_header.common.code_onInitDialog)) return PS_ERROR;
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onGUIInit",0),&build_header.common.code_onGUIInit)) return PS_ERROR;
if (resolve_call_int("install callback",".callbacks",ns_func.find(".onMouseOverSection",0),&build_header.code_onMouseOverSection)) return PS_ERROR;
#endif
#ifdef NSIS_CONFIG_COMPONENTPAGE
@ -1217,73 +1248,248 @@ int CEXEBuild::write_output(void)
if (resolve_coderefs("install")) return PS_ERROR;
// Added by Amir Szekely 8th July 2002
// Removes any unused resources
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
try {
SCRIPT_MSG("Removing unused resources... ");
CResourceEditor re(header_data_new, exeheader_size_new);
{
page pg = {
0,
#ifdef NSIS_SUPPORT_CODECALLBACKS
-1,
-1
#endif
};
int add_pages=!build_pages.getlen();
int add_uninst_pages=!ubuild_pages.getlen();
int license=0;
int selcom=0;
int dir=0;
int uninst=0;
int instlog=0;
int main=2;
#ifdef NSIS_CONFIG_SILENT_SUPPORT
if (!build_header.common.silent_install)
#endif
{
#ifdef NSIS_CONFIG_LICENSEPAGE
if (IsNotSet(installer.licensedata)
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|| build_header.common.silent_install
#endif // NSIS_CONFIG_SILENT_SUPPORT
)
{
re.UpdateResource(RT_DIALOG, IDD_LICENSE, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#endif // NSIS_CONFIG_LICENSEPAGE
if (!IsNotSet(installer.licensedata)) license++;
#endif
#ifdef NSIS_CONFIG_COMPONENTPAGE
if (IsNotSet(installer.componenttext)
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|| build_header.common.silent_install
#endif // NSIS_CONFIG_SILENT_SUPPORT
)
{
re.UpdateResource(RT_DIALOG, IDD_SELCOM, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
re.UpdateResource(RT_BITMAP, IDB_BITMAP1, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#endif // NSIS_CONFIG_COMPONENTPAGE
if (IsNotSet(installer.text)
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|| build_header.common.silent_install
#endif // NSIS_CONFIG_SILENT_SUPPORT
)
{
re.UpdateResource(RT_DIALOG, IDD_DIR, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if (!uninstaller_writes_used
#ifdef NSIS_CONFIG_SILENT_SUPPORT
|| build_uninst.common.silent_install
#endif // NSIS_CONFIG_SILENT_SUPPORT
)
{
re.UpdateResource(RT_DIALOG, IDD_UNINST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#endif // NSIS_CONFIG_UNINSTALL_SUPPORT
#ifdef NSIS_CONFIG_SILENT_SUPPORT
if (build_header.common.silent_install
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
&& (build_uninst.common.silent_install || !uninstaller_writes_used)
#endif // NSIS_CONFIG_UNINSTALL_SUPPORT
)
{
re.UpdateResource(RT_DIALOG, IDD_INST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
re.UpdateResource(RT_DIALOG, IDD_INSTFILES, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
if (!build_compress_whole && !build_crcchk)
re.UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#endif // NSIS_CONFIG_SILENT_SUPPORT
if (!IsNotSet(installer.componenttext)) selcom++;
#endif
if (!IsNotSet(installer.text)) dir++;
free(header_data_new);
header_data_new = re.Save((DWORD&)exeheader_size_new);
if (!add_pages) {
int i=0;
page *p=(page *) build_pages.get();
while (i!=build_header.common.num_pages) {
switch (p->id) {
#ifdef NSIS_CONFIG_LICENSEPAGE
case NSIS_PAGE_LICENSE:
license++;
break;
#endif
#ifdef NSIS_CONFIG_COMPONENTPAGE
case NSIS_PAGE_SELCOM:
selcom++;
break;
#endif
case NSIS_PAGE_DIR:
dir++;
break;
case NSIS_PAGE_INSTFILES:
instlog++;
break;
}
p++;
i++;
}
SCRIPT_MSG("Done!\n");
}
catch (exception& err) {
ERROR_MSG("\nError: %s\n", err.what());
return PS_ERROR;
if (license==1) {
ERROR_MSG("Error: %s page and %s depend on each other, both must be in the script!\n", "license", "LicenseData");
return PS_ERROR;
}
if (selcom==1) {
ERROR_MSG("Error: %s page and %s depend on each other, both must be in the script!\n", "components", "ComponentText");
return PS_ERROR;
}
if (dir==1) {
ERROR_MSG("Error: %s page and %s depend on each other, both must be in the script!\n", "directory selection", "DirText");
return PS_ERROR;
}
if (!instlog) {
warning("Page instfiles not specefied, no sections will be executed!");
}
}
else {
#ifdef NSIS_CONFIG_LICENSEPAGE
if (license) {
pg.id=NSIS_PAGE_LICENSE;
build_pages.add(&pg,sizeof(page));
build_header.common.num_pages++;
}
#endif
#ifdef NSIS_CONFIG_COMPONENTPAGE
if (selcom) {
pg.id=NSIS_PAGE_SELCOM;
build_pages.add(&pg,sizeof(page));
build_header.common.num_pages++;
}
#endif
if (dir) {
pg.id=NSIS_PAGE_DIR;
build_pages.add(&pg,sizeof(page));
build_header.common.num_pages++;
}
instlog++;
pg.id=NSIS_PAGE_INSTFILES;
build_pages.add(&pg,sizeof(page));
build_header.common.num_pages++;
pg.id=NSIS_PAGE_COMPLETED;
build_pages.add(&pg,sizeof(page));
build_header.common.num_pages++;
}
page *p=(page *) build_pages.get();
for (int i=0; i<build_header.common.num_pages; i++, p++) {
if (i) p->back=2; // 2 - enabled, 1 - disabled, 0 - invisible
else p->back=0;
p->next=LANG_BTN_NEXT;
#ifdef NSIS_CONFIG_LICENSEPAGE
if (p->id==NSIS_PAGE_LICENSE)
p->next=LANG_BTN_LICENSE;
#endif
if (i<build_header.common.num_pages-1 && (p+1)->id==NSIS_PAGE_INSTFILES)
p->next=LANG_BTN_INSTALL;
if (p->id==NSIS_PAGE_INSTFILES || p->id==NSIS_PAGE_COMPLETED)
p->back=1;
}
(--p)->next=LANG_BTN_CLOSE;
if (p->id==NSIS_PAGE_COMPLETED) (--p)->next=LANG_BTN_CLOSE;
}
#ifdef NSIS_CONFIG_SILENT_SUPPORT
else main--;
#endif
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
#ifdef NSIS_CONFIG_SILENT_SUPPORT
if (!build_uninst.common.silent_install && uninstaller_writes_used)
#endif
{
if (!IsNotSet(uninstall.uninstalltext)) uninst++;
if (!add_uninst_pages) {
int i=0;
page *p=(page *) ubuild_pages.get();
while (i!=build_header.common.num_pages) {
switch (p->id) {
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
case NSIS_PAGE_UNINST:
uninst++;
break;
#endif
case NSIS_PAGE_INSTFILES:
instlog++;
break;
}
p++;
i++;
}
if (uninst==1) {
ERROR_MSG("Error: %s page and %s depend on each other, both must be in the script!\n", "UninstallText");
return PS_ERROR;
}
if (!instlog) {
warning("UninstPage instfiles not specefied, no sections will be executed!");
}
}
else {
if (uninst) {
pg.id=NSIS_PAGE_UNINST;
ubuild_pages.add(&pg,sizeof(page));
build_uninst.common.num_pages++;
}
instlog++;
pg.id=NSIS_PAGE_INSTFILES;
ubuild_pages.add(&pg,sizeof(page));
build_uninst.common.num_pages++;
pg.id=NSIS_PAGE_COMPLETED;
ubuild_pages.add(&pg,sizeof(page));
build_uninst.common.num_pages++;
}
/*case NSIS_PAGE_UNINST:
p->next=LANG_BTN_UNINST;
break;*/
page *p=(page *) ubuild_pages.get();
int noinstlogback=0;
for (int i=0; i<build_uninst.common.num_pages; i++, p++) {
if (i) p->back=2; // 2 - enabled, 1 - disabled, 0 - invisible
else p->back=0;
p->next=LANG_BTN_NEXT;
if (i<build_uninst.common.num_pages-1 && (p+1)->id==NSIS_PAGE_INSTFILES) {
if (p->id==NSIS_PAGE_UNINST)
noinstlogback=1;
p->next=LANG_BTN_UNINST;
}
if (p->id==NSIS_PAGE_INSTFILES || p->id==NSIS_PAGE_COMPLETED)
p->back=noinstlogback?0:1;
}
(--p)->next=LANG_BTN_CLOSE;
if (p->id==NSIS_PAGE_COMPLETED) (--p)->next=LANG_BTN_CLOSE;
}
#ifdef NSIS_CONFIG_SILENT_SUPPORT
else
#endif
#endif
main--;
try {
SCRIPT_MSG("Removing unused resources... ");
CResourceEditor re(header_data_new, exeheader_size_new);
#ifdef NSIS_CONFIG_LICENSEPAGE
if (!license) {
re.UpdateResource(RT_DIALOG, IDD_LICENSE, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#endif // NSIS_CONFIG_LICENSEPAGE
#ifdef NSIS_CONFIG_COMPONENTPAGE
if (!selcom) {
re.UpdateResource(RT_DIALOG, IDD_SELCOM, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
re.UpdateResource(RT_BITMAP, IDB_BITMAP1, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#endif // NSIS_CONFIG_COMPONENTPAGE
if (!dir) {
re.UpdateResource(RT_DIALOG, IDD_DIR, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if (!uninst) {
re.UpdateResource(RT_DIALOG, IDD_UNINST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
#endif // NSIS_CONFIG_UNINSTALL_SUPPORT
if (!instlog) {
re.UpdateResource(RT_DIALOG, IDD_INSTFILES, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
if (!main) {
re.UpdateResource(RT_DIALOG, IDD_INST, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
if (!build_compress_whole && !build_crcchk)
re.UpdateResource(RT_DIALOG, IDD_VERIFY, MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), 0, 0);
}
free(header_data_new);
header_data_new = re.Save((DWORD&)exeheader_size_new);
SCRIPT_MSG("Done!\n");
}
catch (exception& err) {
ERROR_MSG("\nError: %s\n", err.what());
return PS_ERROR;
}
}
#endif // NSIS_CONFIG_VISIBLE_SUPPORT
@ -1415,6 +1621,9 @@ int CEXEBuild::write_output(void)
GrowBuf hdrcomp;
hdrcomp.add(&build_header,sizeof(build_header));
hdrcomp.add(build_sections.get(),build_sections.getlen());
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
hdrcomp.add(build_pages.get(),build_pages.getlen());
#endif
hdrcomp.add(build_entries.get(),build_entries.getlen());
hdrcomp.add(build_strlist.get(),build_strlist.getlen());
hdrcomp.add(build_langtables.get(),build_langtables.getlen());
@ -1692,6 +1901,9 @@ int CEXEBuild::uninstall_generate()
GrowBuf udata;
udata.add(&build_uninst,sizeof(build_uninst));
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
udata.add(ubuild_pages.get(),ubuild_pages.getlen());
#endif
udata.add(ubuild_entries.get(),ubuild_entries.getlen());
udata.add(ubuild_strlist.get(),ubuild_strlist.getlen());
udata.add(ubuild_langtables.get(),ubuild_langtables.getlen());

View file

@ -2,6 +2,7 @@
#define _BUILD_H_
#include <Vector>
#include <List>
using namespace std;
#include "strlist.h"
@ -201,6 +202,7 @@ class CEXEBuild {
StringList build_strlist,ubuild_strlist;
GrowBuf build_langtables, ubuild_langtables;
StringList build_userlangstrings, ubuild_userlangstrings;
GrowBuf build_pages, ubuild_pages;
MMapBuf build_datablock, ubuild_datablock; // use GrowBuf here instead of MMapBuf if you want
IGrowBuf *cur_datablock;

View file

@ -39,7 +39,7 @@
#define LB_ICONHEIGHT 20
HICON g_hIcon;
static char gDontFookWithFocus = 0;
static int gDontFookWithFocus = 0;
// Added by Amir Szekely 3rd August 2002
char *language_tables;
@ -51,9 +51,9 @@ int g_quit_flag; // set when Quit has been called (meaning bail out ASAP)
#error invalid value for NSIS_MAX_INST_TYPES
#endif
char g_autoclose;
char g_noicon;
int g_autoclose;
int progress_bar_pos, progress_bar_len;
int g_is_uninstaller;
HWND g_progresswnd;
@ -98,16 +98,9 @@ HWND NSISCALL bgWnd_Init();
HWND insthwnd, insthwnd2,insthwndbutton;
void *g_inst_combinedheader;
page *g_inst_page;
section *g_inst_section;
entry *g_inst_entry;
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
int g_is_uninstaller;
static int g_max_page=1;
static int g_page_offs=4;
#else
#define g_max_page 3
#define g_page_offs 0
#endif
static int m_page=-1,m_abort;
static HWND m_curwnd, m_bgwnd, m_hwndOK, m_hwndCancel;
@ -272,8 +265,9 @@ lang_again:
}
myitoa(state_language, *(LANGID*)language_table);
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
SendMessage(m_bgwnd, WM_SETTEXT, 0, (LPARAM)process_string_fromtab(g_caption,LANG_CAPTION));
#endif
}
int NSISCALL ui_doinstall(void)
@ -282,12 +276,8 @@ int NSISCALL ui_doinstall(void)
g_autoclose=g_inst_cmnheader->misc_flags&1;
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if (!g_is_uninstaller)
{
g_max_page=3;
g_page_offs=0;
#else
{
#endif
{
if (!is_valid_instpath(state_install_directory))
{
if (g_inst_header->install_reg_key_ptr)
@ -443,9 +433,7 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
if (uMsg == WM_INITDIALOG || uMsg == WM_NOTIFY_OUTER_NEXT)
{
int iscp=0,islp=0,isdp=0,ispotentiallydp=0;
int delta=(uMsg == WM_NOTIFY_OUTER_NEXT)?wParam:0;
int prev_page=m_page;
#define delta wParam
static struct
{
char *id;
@ -455,19 +443,15 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
#ifdef NSIS_CONFIG_LICENSEPAGE
{MAKEINTRESOURCE(IDD_LICENSE),LicenseProc},
#else
{NULL,NULL},
#endif
#ifdef NSIS_CONFIG_COMPONENTPAGE
{MAKEINTRESOURCE(IDD_SELCOM),SelProc},
#else
{NULL,NULL},
#endif
{MAKEINTRESOURCE(IDD_DIR),DirProc},
{MAKEINTRESOURCE(IDD_INSTFILES),InstProc},
{NULL,NULL}, // imaginary completed page
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
{MAKEINTRESOURCE(IDD_UNINST),UninstProc},
{MAKEINTRESOURCE(IDD_INSTFILES),InstProc},
{MAKEINTRESOURCE(IDD_UNINST),UninstProc}
#endif
};
@ -479,126 +463,96 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
SetDlgItemTextFromLang(hwndDlg,IDC_VERSTR,LANG_BRANDING);
SetClassLong(hwndDlg,GCL_HICON,(long)g_hIcon);
SetDlgItemTextFromLang(hwndDlg,IDCANCEL,LANG_BTN_CANCEL);
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if (!g_is_uninstaller)
SetDlgItemTextFromLang(hwndDlg,IDC_BACK,LANG_BTN_BACK);
#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
ExecuteCodeSegment(g_inst_cmnheader->code_onGUIInit,NULL);
#endif
SetDlgItemTextFromLang(hwndDlg,IDC_BACK,LANG_BTN_BACK);
ShowWindow(hwndDlg,SW_SHOW);
}
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
if (g_is_uninstaller)
{
islp = LANG_STR_TAB(LANG_UNINST_TEXT);
iscp++;
}
else
#endif//NSIS_CONFIG_UNINSTALL_SUPPORT
{
#ifdef NSIS_CONFIG_LICENSEPAGE
islp = LANG_STR_TAB(LANG_LICENSE_DATA);
#endif//NSIS_CONFIG_LICENSEPAGE
#ifdef NSIS_CONFIG_COMPONENTPAGE
iscp = LANG_STR_TAB(LANG_COMP_TEXT);
#endif//NSIS_CONFIG_COMPONENTPAGE
ispotentiallydp = LANG_STR_TAB(LANG_DIR_TEXT);
if (ispotentiallydp &&
!((g_inst_cmnheader->misc_flags&2) &&
is_valid_instpath(state_install_directory)
#ifdef NSIS_SUPPORT_CODECALLBACKS
&& !ExecuteCodeSegment(g_inst_header->code_onVerifyInstDir,NULL)
#endif//NSIS_SUPPORT_CODECALLBACKS
)) isdp++;
}
nextPage:
if (m_page<=0) delta=1;
do
{
int count=1; // Number of pages to move by
#ifdef NSIS_SUPPORT_CODECALLBACKS
// Call onNext|PrevPage for every not-definitely-disabled page
if (ExecuteCodeSegment(delta>0?g_inst_cmnheader->code_onNextPage:g_inst_header->code_onPrevPage,NULL))
{
if (g_quit_flag) // Quit instruction used?
m_page=count=-1;
// Mmm - relies on ps_tmpbuf still being set from the Abort command - safe?
else if ((count = myatoi(ps_tmpbuf)) != 0)
count /= (delta = (count>0?1:-1));
}
#endif//NSIS_SUPPORT_CODECALLBACKS
// Skip any definitely-disabled pages, then the required number of pages
while ((m_page==0 && !islp) || (m_page==1 && !iscp) || (m_page==2 && !ispotentiallydp) || (--count>=0))
m_page+=delta;
// Skip any possibly-disabled pages
} while ((m_page >= 0) && (m_page <= g_max_page) && (m_page==2 && !isdp));
if (m_page<0) delta=1;
m_page+=delta;
#ifdef NSIS_SUPPORT_CODECALLBACKS
if (m_page>g_max_page) ExecuteCodeSegment(g_inst_cmnheader->code_onInstSuccess,NULL);
if (m_page==g_inst_cmnheader->num_pages) ExecuteCodeSegment(g_inst_cmnheader->code_onInstSuccess,NULL);
#endif//NSIS_SUPPORT_CODECALLBACKS
if (m_curwnd && (m_page!=prev_page))
if (g_quit_flag || m_page < 0 || m_page == g_inst_cmnheader->num_pages)
{
DestroyWindow(m_curwnd);
m_curwnd=0;
}
if (m_page < 0 || m_page > g_max_page)
EndDialog(hwndDlg,0);
else if (!m_curwnd)
}
else
{
HWND hwndtmp;
int str =
(m_page == g_max_page) ? LANG_BTN_CLOSE :
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
g_is_uninstaller ? LANG_BTN_UNINST :
#endif
#ifdef NSIS_CONFIG_LICENSEPAGE
(m_page == 0) ? LANG_BTN_LICENSE :
#endif
(m_page == 2 || (m_page == 1 && !isdp)) ? LANG_BTN_INSTALL :
LANG_BTN_NEXT;
SetDlgItemTextFromLang(hwndDlg,IDOK,str);
mystrcpy(g_tmp,g_caption);
process_string_fromtab(g_tmp+mystrlen(g_tmp),LANG_SUBCAPTION(m_page));
int page_id=g_inst_page[m_page].id;
SetWindowText(hwndDlg,g_tmp);
SetDlgItemTextFromLang(hwndDlg,IDOK,g_inst_page[m_page].next);
hwndtmp=GetDlgItem(hwndDlg,IDC_BACK);
ShowWindow(hwndtmp,g_inst_page[m_page].back?SW_SHOWNA:SW_HIDE);
EnableWindow(hwndtmp, g_inst_page[m_page].back&2);
gDontFookWithFocus = 0;
m_curwnd=CreateDialog(g_hInstance,windows[g_page_offs+m_page].id,hwndDlg,windows[g_page_offs+m_page].proc);
if (m_curwnd)
if (page_id!=NSIS_PAGE_COMPLETED) DestroyWindow(m_curwnd);
else if (g_autoclose) goto nextPage;
if (page_id>=0) // NSIS page
{
RECT r;
GetWindowRect(GetDlgItem(hwndDlg,IDC_CHILDRECT),&r);
ScreenToClient(hwndDlg,(LPPOINT)&r);
SetWindowPos(m_curwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
#ifdef NSIS_SUPPORT_CODECALLBACKS
ExecuteCodeSegment(g_inst_cmnheader->code_onInitDialog,NULL);
if (ExecuteCodeSegment(g_inst_page[m_page].prefunc,NULL))
goto nextPage;
else
#endif //NSIS_SUPPORT_CODECALLBACKS
SendMessage(m_curwnd, WM_NOTIFY_START, 0, 0);
ShowWindow(m_curwnd,SW_SHOWNA);
{
mystrcpy(g_tmp,g_caption);
process_string_fromtab(
g_tmp+mystrlen(g_tmp),
LANG_SUBCAPTION(page_id-(g_is_uninstaller?NSIS_PAGE_INSTFILES:0))
);
SetWindowText(hwndDlg,g_tmp);
gDontFookWithFocus = 0;
m_curwnd=CreateDialog(g_hInstance,windows[page_id].id,hwndDlg,windows[page_id].proc);
if (m_curwnd)
{
RECT r;
GetWindowRect(GetDlgItem(hwndDlg,IDC_CHILDRECT),&r);
ScreenToClient(hwndDlg,(LPPOINT)&r);
SetWindowPos(m_curwnd,0,r.left,r.top,0,0,SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOZORDER);
SendMessage(m_curwnd, WM_NOTIFY_START, 0, 0);
ShowWindow(m_curwnd,SW_SHOWNA);
}
//XGE 5th September 2002 - Do *not* move the focus to the OK button if we are
//on the license page, instead we want the focus left alone because in
//WM_INITDIALOG it is given to the richedit control.
if (!gDontFookWithFocus)
SetFocus(m_hwndOK);
//XGE End
}
}
#ifdef NSIS_SUPPORT_CODECALLBACKS
else // User custom page
{
if (ExecuteCodeSegment(g_inst_page[m_page].prefunc,NULL))
delta=-1;
else
delta=1;
goto nextPage;
}
hwndtmp=GetDlgItem(hwndDlg,IDC_BACK);
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
ShowWindow(hwndtmp,(m_page&&!g_is_uninstaller)?SW_SHOWNA:SW_HIDE);
if (!g_is_uninstaller)
#else
ShowWindow(hwndtmp,m_page?SW_SHOWNA:SW_HIDE);
#endif
EnableWindow(hwndtmp, (m_page==1&&islp) || (m_page==2&&(islp||iscp)));
//XGE 5th September 2002 - Do *not* move the focus to the OK button if we are
//on the license page, instead we want the focus left alone because in
//WM_INITDIALOG it is given to the richedit control.
if (!gDontFookWithFocus)
SetFocus(m_hwndOK);
//XGE End
ExecuteCodeSegment(g_inst_page[m_page].postfunc,NULL);
#endif //NSIS_SUPPORT_CODECALLBACKS
}
}
if (uMsg == WM_COMMAND)
{
int id=LOWORD(wParam);
if (id == IDOK && m_curwnd)
if (id == IDOK)
{
outernotify(1);
}
@ -606,9 +560,8 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
!g_is_uninstaller &&
#endif
(id == IDC_BACK && m_curwnd && m_page>0))
(id == IDC_BACK && m_page>0))
{
EnableWindow(m_hwndOK, TRUE);
outernotify(-1);
}
if (id == IDCANCEL)
@ -900,7 +853,7 @@ static DWORD WINAPI newTreeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
SendMessage(m_curwnd,WM_TREEVIEW_KEYHACK,0,0);
return 0;
}
#ifdef NSIS_SUPPORT_CODECALLBACKS
#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
if (uMsg == WM_DESTROY) {
last_item=-1;
}
@ -927,12 +880,13 @@ static DWORD WINAPI newTreeWndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM l
mystrcpy(g_tmp, g_usrvars[0]);
myitoa(g_usrvars[0], last_item);
ExecuteCodeSegment(g_inst_header->code_onMouseOverSection,NULL);
mystrcpy(g_usrvars[0], g_tmp);
}
}
#endif//NSIS_SUPPORT_CODECALLBACKS
#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
return CallWindowProc((WNDPROC)oldTreeWndProc,hwnd,uMsg,wParam,lParam);
}
@ -1166,11 +1120,11 @@ static BOOL CALLBACK SelProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPar
} // not ro
} // was valid click
} // was click or hack
#ifdef NSIS_SUPPORT_CODECALLBACKS
#if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
else if (lpnmh->code == TVN_SELCHANGED) {
SendMessage(hwndTree1, WM_USER+0x19, 0, ((LPNMTREEVIEW)lpnmh)->itemNew.lParam);
}
#endif//NSIS_SUPPORT_CODECALLBACKS
#endif//NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
}
}
if (uMsg == WM_COMMAND)
@ -1403,19 +1357,10 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
{
HWND h=m_hwndOK;
EnableWindow(h,1);
if (!g_autoclose)
{
ShowWindow(g_hwnd,SW_SHOWNA);
mystrcpy(g_tmp,g_caption);
process_string_fromtab(g_tmp+mystrlen(g_tmp),LANG_SUBCAPTION(g_max_page+1));
update_status_text_from_lang(LANG_COMPLETED,"");
SetWindowText(g_hwnd,g_tmp);
SetFocus(h);
}
else
{
outernotify(1);
}
ShowWindow(g_hwnd,SW_SHOWNA);
update_status_text_from_lang(LANG_COMPLETED,"");
outernotify(1);
SetFocus(h);
}
else
{

View file

@ -795,6 +795,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
f.lfItalic=parm4&1;
f.lfUnderline=parm4&2;
f.lfStrikeOut=parm4&4;
f.lfCharSet=DEFAULT_CHARSET;
process_string_fromtab(f.lfFaceName,parm1);
myitoa(var0,(int)CreateFontIndirect(&f));
}
@ -959,7 +960,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
update_status_text_from_lang(LANG_CANNOTFINDSYMBOL,buf1);
log_printf3("Error registering DLL: %s not found in %s",buf1,buf0);
}
if (!parm3) FreeLibrary(h);
if (!parm3) while (FreeLibrary(h));
// saves 2 bytes - FreeLibrary((HANDLE)((unsigned long)h&(unsigned long)parm3));
}
else

View file

@ -99,15 +99,16 @@ const char * NSISCALL loadHeaders(void)
if (h.flags&FH_FLAGS_UNINSTALL)
{
g_is_uninstaller++;
g_inst_entry=(entry *) ((g_inst_uninstheader) + 1);
g_inst_page=(page *) (g_inst_uninstheader + 1);
}
else
#endif
{
g_inst_section=(section *) (g_inst_header + 1);
g_inst_entry=(entry *) (g_inst_section + g_inst_header->num_sections);
g_inst_page=(page *) (g_inst_section + g_inst_header->num_sections);
}
g_db_strtab = (char *)(g_inst_entry + g_inst_cmnheader->num_entries);
g_inst_entry=(entry *) (g_inst_page + g_inst_cmnheader->num_pages);
g_db_strtab = (char *) (g_inst_entry + g_inst_cmnheader->num_entries);
return 0;
}

View file

@ -13,6 +13,7 @@
// sections (20 bytes each)
// (if uninstall)
// uninstall_header (~116 bytes)
// pages (12 bytes each)
// entries (24 bytes each)
// string table
// language tables
@ -182,9 +183,25 @@ enum
};
#define FH_FLAGS_MASK 15
#define FH_FLAGS_CRC 1
#define FH_FLAGS_UNINSTALL 2
#ifdef NSIS_CONFIG_SILENT_SUPPORT
#define FH_FLAGS_SILENT 4
#endif
// Added by Amir Szekely 23rd July 2002
#define FH_FLAGS_FORCE_CRC 8
#define FH_SIG 0xDEADBEEF
// neato surprise signature that goes in firstheader. :)
#define FH_INT1 0x6C6C754E
#define FH_INT2 0x74666F73
#define FH_INT3 0x74736E49
typedef struct
{
int flags; // &1=CRC, &2=uninstall, &4=silent
int flags; // &1=CRC, &2=uninstall, &4=silent, &8=force CRC
int siginfo; // FH_SIG
int nsinst[3]; // FH_INT1,FH_INT2,FH_INT3
@ -199,17 +216,22 @@ typedef struct
// Strings common to both installers and uninstallers
typedef struct
{
// unprocessed strings
int branding;
int cancelbutton;
int showdetailsbutton;
int completed;
int closebutton; // "Close"
int name; // name of installer
// unprocessed strings
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
int branding;
int backbutton;
int nextbutton;
int cancelbutton;
int showdetailsbutton;
int closebutton; // "Close"
int completed;
// processed strings
int caption; // name of installer + " Setup" or whatever.
int subcaptions[5];
#endif
int caption; // name of installer + " Setup" or whatever.
#ifdef NSIS_SUPPORT_FILE
int fileerrtext;
@ -278,6 +300,8 @@ typedef struct
int num_entries; // total number of entries
int num_string_bytes; // total number of bytes taken by strings
int num_pages; // number of used pages (including custom pages)
#ifdef NSIS_SUPPORT_BGBG
int bg_color1, bg_color2, bg_textcolor;
#endif
@ -289,9 +313,8 @@ typedef struct
int code_onInstSuccess;
int code_onInstFailed;
int code_onUserAbort;
int code_onNextPage;
#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
int code_onInitDialog;
int code_onGUIInit;
#endif
#endif//NSIS_SUPPORT_CODECALLBACKS
@ -309,8 +332,6 @@ typedef struct
{
// these first strings are literals (should not be encoded)
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
int backbutton;
int nextbutton;
int browse; // "Browse..."
int installbutton; // "Install"
int spacerequired; // "Space required: "
@ -364,7 +385,6 @@ typedef struct
#ifdef NSIS_SUPPORT_CODECALLBACKS
// .on* calls
int code_onPrevPage;
int code_onVerifyInstDir;
#ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
int code_onMouseOverSection;
@ -418,22 +438,33 @@ typedef struct
int offsets[MAX_ENTRY_OFFSETS]; // count and meaning of offsets depend on 'which'
} entry;
#define FH_FLAGS_MASK 15
#define FH_FLAGS_CRC 1
#define FH_FLAGS_UNINSTALL 2
#ifdef NSIS_CONFIG_SILENT_SUPPORT
#define FH_FLAGS_SILENT 4
enum
{
NSIS_PAGE_CUSTOM = -1,
#ifdef NSIS_CONFIG_LICENSEPAGE
NSIS_PAGE_LICENSE,
#endif
// Added by Amir Szekely 23rd July 2002
#define FH_FLAGS_FORCE_CRC 8
#ifdef NSIS_CONFIG_COMPONENTPAGE
NSIS_PAGE_SELCOM,
#endif
NSIS_PAGE_DIR,
NSIS_PAGE_INSTFILES,
NSIS_PAGE_COMPLETED,
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
NSIS_PAGE_UNINST
#endif
};
#define FH_SIG 0xDEADBEEF
// neato surprise signature that goes in firstheader. :)
#define FH_INT1 0x6C6C754E
#define FH_INT2 0x74666F73
#define FH_INT3 0x74736E49
typedef struct
{
int id; // index in the pages array
#ifdef NSIS_SUPPORT_CODECALLBACKS
int prefunc; // function to use Abort in, or show the custom page if id == NSIS_PAGE_CUSTOM
int postfunc; // function to do stuff after the page is shown
#endif //NSIS_SUPPORT_CODECALLBACKS
int next;
int back;
} page;
// the following are only used/implemented in exehead, not makensis.

View file

@ -46,8 +46,6 @@
#define INSTALL_STR(x) (~((sizeof(common_strings) + FIELD_OFFSET(installer_strings, x)) / sizeof(int)))
// Installer specific strings
#define LANG_BTN_BACK (INSTALL_STR(backbutton))
#define LANG_BTN_NEXT (INSTALL_STR(nextbutton))
#define LANG_BTN_BROWSE (INSTALL_STR(browse))
#define LANG_BTN_INSTALL (INSTALL_STR(installbutton))
#define LANG_SPACE_REQ (INSTALL_STR(spacerequired))
@ -71,6 +69,8 @@
#define COMMON_STR(x) (~(FIELD_OFFSET(common_strings, x) / sizeof(int)))
// Common strings
#define LANG_BTN_NEXT (COMMON_STR(nextbutton))
#define LANG_BTN_BACK (COMMON_STR(backbutton))
#define LANG_BRANDING (COMMON_STR(branding))
#define LANG_BTN_CANCEL (COMMON_STR(cancelbutton))
#define LANG_BTN_DETAILS (COMMON_STR(showdetailsbutton))

View file

@ -10,8 +10,9 @@ void NSISCALL update_status_text_from_lang(int id, const char *text2);
void NSISCALL update_status_text(const char *text1, const char *text2);
extern int ui_st_updateflag;
extern char g_autoclose;
extern int g_autoclose;
extern void *g_inst_combinedheader;
extern page *g_inst_page;
extern section *g_inst_section;
extern entry *g_inst_entry;

View file

@ -123,25 +123,27 @@ int CEXEBuild::SetString(char *string, int id, int process, StringTable *table)
#define HANDLE_STRING_U(id,strname) case id: ustr=&(table->strname); break;
#endif
switch (id) {
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
HANDLE_STRING_C(NLF_COMPLETED, common.completed);
HANDLE_STRING_C(NLF_BTN_NEXT, common.nextbutton);
HANDLE_STRING_C(NLF_BTN_BACK, common.backbutton);
HANDLE_STRING_C(NLF_BRANDING, common.branding);
HANDLE_STRING_C(NLF_BTN_CANCEL, common.cancelbutton);
HANDLE_STRING_C(NLF_BTN_CLOSE, common.closebutton);
HANDLE_STRING_C(NLF_BTN_DETAILS, common.showdetailsbutton);
HANDLE_STRING_C(NLF_COMPLETED, common.completed);
#endif
#ifdef NSIS_CONFIG_LICENSEPAGE
#ifdef NSIS_SUPPORT_FILE
HANDLE_STRING_C(NLF_FILE_ERROR, common.fileerrtext);
#endif
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
HANDLE_STRING_I(NLF_CAPTION, common.caption);
HANDLE_STRING_I(NLF_SUBCAPTION_LICENSE, common.subcaptions[0]);
HANDLE_STRING_I(NLF_SUBCAPTION_OPTIONS, common.subcaptions[1]);
HANDLE_STRING_I(NLF_SUBCAPTION_DIR, common.subcaptions[2]);
HANDLE_STRING_I(NLF_SUBCAPTION_INSTFILES, common.subcaptions[3]);
HANDLE_STRING_I(NLF_SUBCAPTION_COMPLETED, common.subcaptions[4]);
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
HANDLE_STRING_I(NLF_BTN_NEXT, installer.nextbutton);
HANDLE_STRING_I(NLF_BTN_BACK, installer.backbutton);
#ifdef NSIS_CONFIG_LICENSEPAGE
HANDLE_STRING_I(NLF_BTN_LICENSE, installer.licensebutton);
#endif
HANDLE_STRING_I(NLF_BTN_INSTALL, installer.installbutton);
@ -154,15 +156,16 @@ int CEXEBuild::SetString(char *string, int id, int process, StringTable *table)
HANDLE_STRING_I(NLF_DIR_SUBTEXT, installer.dirsubtext);
HANDLE_STRING_I(NLF_SPACE_AVAIL, installer.spaceavailable);
HANDLE_STRING_I(NLF_SPACE_REQ, installer.spacerequired);
#endif
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
HANDLE_STRING_U(NLF_UCAPTION, ucommon.caption);
HANDLE_STRING_U(NLF_USUBCAPTION_CONFIRM, ucommon.subcaptions[0]);
HANDLE_STRING_U(NLF_USUBCAPTION_INSTFILES, ucommon.subcaptions[1]);
HANDLE_STRING_U(NLF_USUBCAPTION_COMPLETED, ucommon.subcaptions[2]);
HANDLE_STRING_U(NLF_USUBCAPTION_INSTFILES, ucommon.subcaptions[0]);
HANDLE_STRING_U(NLF_USUBCAPTION_COMPLETED, ucommon.subcaptions[1]);
HANDLE_STRING_U(NLF_USUBCAPTION_CONFIRM, ucommon.subcaptions[2]);
HANDLE_STRING_U(NLF_BTN_UNINSTALL, uninstall.uninstbutton);
HANDLE_STRING_U(NLF_UNINST_SUBTEXT, uninstall.uninstalltext2);
#endif
#endif
HANDLE_STRING_C(LANG_NAME, common.name);
@ -397,7 +400,7 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) {
// Changed by Amir Szekely 22nd July 2002
// Adds the ability to disable space texts
if (!table->installer.spacerequired && !no_space_texts) table->installer.spacerequired=add_string_main(str(NLF_SPACE_REQ),0);
if (!table->installer.nextbutton) table->installer.nextbutton=add_string_main(str(NLF_BTN_NEXT),0);
if (!table->common.nextbutton) table->common.nextbutton=add_string_main(str(NLF_BTN_NEXT),0);
if (!table->installer.installbutton) table->installer.installbutton=add_string_main(str(NLF_BTN_INSTALL),0);
}
@ -412,7 +415,7 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) {
wsprintf(buf,str(NLF_BRANDING),NSIS_VERSION);
table->common.branding=add_string_main(buf,0);
}
if (!table->installer.backbutton) table->installer.backbutton=add_string_main(str(NLF_BTN_BACK),0);
if (!table->common.backbutton) table->common.backbutton=add_string_main(str(NLF_BTN_BACK),0);
if (!table->common.cancelbutton) table->common.cancelbutton=add_string_main(str(NLF_BTN_CANCEL),0);
if (!table->common.showdetailsbutton) table->common.showdetailsbutton=add_string_main(str(NLF_BTN_DETAILS),0);
@ -433,23 +436,27 @@ void CEXEBuild::FillDefaultsIfNeeded(StringTable *table, NLF *nlf/*=0*/) {
if (uninstaller_writes_used) {
if (!table->uninstall.uninstalltext2)
table->uninstall.uninstalltext2=add_string_uninst(str(NLF_UNINST_SUBTEXT),0);
if (!table->ucommon.subcaptions[0])
table->ucommon.subcaptions[0]=add_string_uninst(str(NLF_USUBCAPTION_CONFIRM));
if (!table->ucommon.subcaptions[1])
table->ucommon.subcaptions[1]=add_string_uninst(str(NLF_USUBCAPTION_INSTFILES));
if (!table->ucommon.subcaptions[2])
table->ucommon.subcaptions[2]=add_string_uninst(str(NLF_USUBCAPTION_COMPLETED));
if (!table->ucommon.caption)
{
char buf[1024];
wsprintf(buf,str(NLF_UCAPTION),ubuild_strlist.get()+table->ucommon.name);
table->ucommon.caption=add_string_uninst(buf);
}
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT
if (!table->ucommon.subcaptions[0])
table->ucommon.subcaptions[0]=add_string_uninst(str(NLF_USUBCAPTION_INSTFILES));
if (!table->ucommon.subcaptions[1])
table->ucommon.subcaptions[1]=add_string_uninst(str(NLF_USUBCAPTION_COMPLETED));
if (!table->ucommon.subcaptions[2])
table->ucommon.subcaptions[2]=add_string_uninst(str(NLF_USUBCAPTION_CONFIRM));
table->ucommon.branding=add_string_uninst(build_strlist.get() + table->common.branding,0);
table->ucommon.backbutton=add_string_uninst(build_strlist.get() + table->common.backbutton,0);
table->ucommon.nextbutton=add_string_uninst(build_strlist.get() + table->common.nextbutton,0);
table->ucommon.cancelbutton=add_string_uninst(build_strlist.get() + table->common.cancelbutton,0);
table->ucommon.showdetailsbutton=add_string_uninst(build_strlist.get() + table->common.showdetailsbutton,0);
table->ucommon.closebutton=add_string_uninst(build_strlist.get() + table->common.closebutton,0);
table->ucommon.completed=add_string_uninst(build_strlist.get() + table->common.completed,0);
#endif
if (!table->uninstall.uninstbutton) table->uninstall.uninstbutton=add_string_uninst(str(NLF_BTN_UNINSTALL),0);
}

View file

@ -20,70 +20,72 @@ struct StringTable {
#define NLF_VERSION 2
#define NLF_STRINGS 57
#define NLF_BRANDING 0
#define NLF_CAPTION 1
#define NLF_UCAPTION 2
#define NLF_SUBCAPTION_LICENSE 3
#define NLF_SUBCAPTION_OPTIONS 4
#define NLF_SUBCAPTION_DIR 5
#define NLF_SUBCAPTION_INSTFILES 6
#define NLF_SUBCAPTION_COMPLETED 7
#define NLF_USUBCAPTION_CONFIRM 8
#define NLF_USUBCAPTION_INSTFILES 9
#define NLF_USUBCAPTION_COMPLETED 10
#define NLF_BTN_BACK 11
#define NLF_BTN_NEXT 12
#define NLF_BTN_LICENSE 13
#define NLF_BTN_INSTALL 14
#define NLF_BTN_UNINSTALL 15
#define NLF_BTN_CANCEL 16
#define NLF_BTN_CLOSE 17
#define NLF_BTN_BROWSE 18
#define NLF_BTN_DETAILS 19
#define NLF_DEF_NAME 20
#define NLF_COMPLETED 21
#define NLF_COMP_CUSTOM 22
#define NLF_COMP_SUBTEXT1 23
#define NLF_COMP_SUBTEXT1_NO_INST_TYPES 24
#define NLF_COMP_SUBTEXT2 25
#define NLF_DIR_SUBTEXT 26
#define NLF_SPACE_AVAIL 27
#define NLF_SPACE_REQ 28
#define NLF_UNINST_SUBTEXT 29
#define NLF_FILE_ERROR 30
#define NLF_CANT_WRITE 31
#define NLF_COPY_FAILED 32
#define NLF_COPY_TO 33
#define NLF_SYMBOL_NOT_FOUND 34
#define NLF_COULD_NOT_LOAD 35
#define NLF_CREATE_DIR 36
#define NLF_CREATE_SHORTCUT 37
#define NLF_CREATED_UNINST 38
#define NLF_DEL_FILE 39
#define NLF_DEL_ON_REBOOT 40
#define NLF_ERR_CREATING_SHORTCUT 41
#define NLF_ERR_CREATING 42
#define NLF_ERR_DECOMPRESSING 43
#define NLF_ERR_REG_DLL 44
#define NLF_EXEC_SHELL 45
#define NLF_EXEC 46
#define NLF_EXTRACT 47
#define NLF_ERR_WRITING 48
#define NLF_INST_CORRUPTED 49
#define NLF_NO_OLE 50
#define NLF_OUTPUT_DIR 51
#define NLF_REMOVE_DIR 52
#define NLF_RENAME_ON_REBOOT 53
#define NLF_RENAME 54
#define NLF_SKIPPED 55
#define NLF_COPY_DETAILS 56
enum {
NLF_BRANDING,
NLF_CAPTION,
NLF_UCAPTION,
NLF_SUBCAPTION_LICENSE,
NLF_SUBCAPTION_OPTIONS,
NLF_SUBCAPTION_DIR,
NLF_SUBCAPTION_INSTFILES,
NLF_SUBCAPTION_COMPLETED,
NLF_USUBCAPTION_CONFIRM,
NLF_USUBCAPTION_INSTFILES,
NLF_USUBCAPTION_COMPLETED,
NLF_BTN_BACK,
NLF_BTN_NEXT,
NLF_BTN_LICENSE,
NLF_BTN_INSTALL,
NLF_BTN_UNINSTALL,
NLF_BTN_CANCEL,
NLF_BTN_CLOSE,
NLF_BTN_BROWSE,
NLF_BTN_DETAILS,
NLF_DEF_NAME,
NLF_COMPLETED,
NLF_COMP_CUSTOM,
NLF_COMP_SUBTEXT1,
NLF_COMP_SUBTEXT1_NO_INST_TYPES,
NLF_COMP_SUBTEXT2,
NLF_DIR_SUBTEXT,
NLF_SPACE_AVAIL,
NLF_SPACE_REQ,
NLF_UNINST_SUBTEXT,
NLF_FILE_ERROR,
NLF_CANT_WRITE,
NLF_COPY_FAILED,
NLF_COPY_TO,
NLF_SYMBOL_NOT_FOUND,
NLF_COULD_NOT_LOAD,
NLF_CREATE_DIR,
NLF_CREATE_SHORTCUT,
NLF_CREATED_UNINST,
NLF_DEL_FILE,
NLF_DEL_ON_REBOOT,
NLF_ERR_CREATING_SHORTCUT,
NLF_ERR_CREATING,
NLF_ERR_DECOMPRESSING,
NLF_ERR_REG_DLL,
NLF_EXEC_SHELL,
NLF_EXEC,
NLF_EXTRACT,
NLF_ERR_WRITING,
NLF_INST_CORRUPTED,
NLF_NO_OLE,
NLF_OUTPUT_DIR,
NLF_REMOVE_DIR,
NLF_RENAME_ON_REBOOT,
NLF_RENAME,
NLF_SKIPPED,
NLF_COPY_DETAILS,
#define LANG_NAME 102
#define LANG_COMP_TEXT 103
#define LANG_LICENSE_TEXT 104
#define LANG_LICENSE_DATA 105
#define LANG_DIR_TEXT 106
#define LANG_UNINST_TEXT 107
LANG_NAME,
LANG_COMP_TEXT,
LANG_LICENSE_TEXT,
LANG_LICENSE_DATA,
LANG_DIR_TEXT,
LANG_UNINST_TEXT
};
extern char *english_strings[NLF_STRINGS];

View file

@ -506,6 +506,176 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
}
return PS_OK;
// page ordering shit
///////////////////////////////////////////////////////////////////////////////
case TOK_PAGE:
{
SCRIPT_MSG("Page: %s", line.gettoken_str(1));
int k = line.gettoken_enum(1,"custom\0license\0components\0directory\0instfiles");
page p = {
0,
#ifdef NSIS_SUPPORT_CODECALLBACKS
-1,
-1
#endif
};
if (line.getnumtokens()>2) {
#ifdef NSIS_SUPPORT_CODECALLBACKS
if (*line.gettoken_str(2))
p.prefunc = ns_func.add(line.gettoken_str(2),0);
if (line.getnumtokens()>3) {
if (k==0) {
ERROR_MSG("\nError: custom page don't need post creation functions!\n");
PRINTHELP();
}
p.postfunc = ns_func.add(line.gettoken_str(3),0);
}
#else
ERROR_MSG("Error: Page callback specified, NSIS_CONFIG_LICENSEPAGE not defined.\n");
return PS_ERROR;
#endif
}
else if (k==0) {
ERROR_MSG("\nError: custom page must have a creator function!\n");
PRINTHELP();
}
switch (k) {
case 0:
p.id = NSIS_PAGE_CUSTOM;
break;
case 1:
#ifdef NSIS_CONFIG_LICENSEPAGE
p.id = NSIS_PAGE_LICENSE;
break;
#else
ERROR_MSG("Error: %s specified, NSIS_CONFIG_LICENSEPAGE not defined.\n", line.gettoken_str(1));
return PS_ERROR;
#endif
case 2:
#ifdef NSIS_CONFIG_COMPONENTPAGE
p.id = NSIS_PAGE_SELCOM;
break;
#else
ERROR_MSG("Error: %s specified, NSIS_CONFIG_COMPONENTPAGE not defined.\n", line.gettoken_str(1));
return PS_ERROR;
#endif
case 3:
p.id = NSIS_PAGE_DIR;
break;
case 4:
p.id = NSIS_PAGE_INSTFILES;
break;
default:
PRINTHELP();
}
#ifdef NSIS_SUPPORT_CODECALLBACKS
if (p.prefunc>=0)
SCRIPT_MSG(" (%s:%s)", k?"pre":"creator", line.gettoken_str(2));
if (p.postfunc>=0)
SCRIPT_MSG(" (post:%s)", line.gettoken_str(3));
#endif
SCRIPT_MSG("\n");
build_pages.add(&p,sizeof(page));
build_header.common.num_pages++;
if (p.id==NSIS_PAGE_INSTFILES) {
p.id=NSIS_PAGE_COMPLETED;
#ifdef NSIS_SUPPORT_CODECALLBACKS
p.prefunc=-1;
p.postfunc=-1;
#endif
build_pages.add(&p,sizeof(page));
build_header.common.num_pages++;
}
}
return PS_OK;
case TOK_UNINSTPAGE:
#ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
{
SCRIPT_MSG("UninstPage: %s", line.gettoken_str(1));
int k = line.gettoken_enum(1,"custom\0uninstConfirm\0instfiles");
page p = {
0,
#ifdef NSIS_SUPPORT_CODECALLBACKS
-1,
-1
#endif
};
if (line.getnumtokens()>2) {
#ifdef NSIS_SUPPORT_CODECALLBACKS
if (*line.gettoken_str(2)) {
if (strnicmp(line.gettoken_str(2),"un.",3)) {
ERROR_MSG("\nError: function must have a un. prefix!\n");
return PS_ERROR;
}
p.prefunc = ns_func.add(line.gettoken_str(2),0);
}
if (line.getnumtokens()>3) {
if (k==0) {
ERROR_MSG("\nError: custom page don't need post creation functions!\n");
PRINTHELP();
}
if (strnicmp(line.gettoken_str(3),"un.",3)) {
ERROR_MSG("\nError: function must have a un. prefix!\n");
return PS_ERROR;
}
p.postfunc = ns_func.add(line.gettoken_str(3),0);
}
#else
ERROR_MSG("Error: UninstPage callback specified, NSIS_CONFIG_LICENSEPAGE not defined.\n");
return PS_ERROR;
#endif
}
else if (k==0) {
ERROR_MSG("\nError: custom page must have a creator function!\n");
PRINTHELP();
}
switch (k) {
case 0:
p.id = NSIS_PAGE_CUSTOM;
break;
case 1:
p.id = NSIS_PAGE_UNINST;
break;
case 2:
p.id = NSIS_PAGE_INSTFILES;
break;
default:
PRINTHELP();
}
#ifdef NSIS_SUPPORT_CODECALLBACKS
if (p.prefunc>=0)
SCRIPT_MSG(" (%s:%s)", k?"pre":"creator", line.gettoken_str(2));
if (p.postfunc>=0)
SCRIPT_MSG(" (post:%s)", line.gettoken_str(3));
#endif
SCRIPT_MSG("\n");
ubuild_pages.add(&p,sizeof(page));
build_uninst.common.num_pages++;
if (p.id==NSIS_PAGE_INSTFILES) {
p.id=NSIS_PAGE_COMPLETED;
#ifdef NSIS_SUPPORT_CODECALLBACKS
p.prefunc=-1;
p.postfunc=-1;
#endif
ubuild_pages.add(&p,sizeof(page));
build_uninst.common.num_pages++;
}
}
return PS_OK;
#else
ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
return PS_ERROR;
#endif
// header flags
///////////////////////////////////////////////////////////////////////////////
case TOK_LANGSTRING:
@ -1591,7 +1761,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
case TOK_UNINSTICON:
case TOK_UNINSTTEXT:
case TOK_UNINSTSUBCAPTION:
ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
ERROR_MSG("Error: %s specified, NSIS_CONFIG_UNINSTALL_SUPPORT not defined.\n", line.gettoken_str(0));
return PS_ERROR;
#endif

View file

@ -61,7 +61,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_FINDCLOSE,"FindClose",1,0,"$(user_var: handle input)"},
{TOK_FINDFIRST,"FindFirst",3,0,"$(user_var: handle output) $(user_var: filename output) filespec"},
{TOK_FINDNEXT,"FindNext",2,0,"$(user_var: handle input) $(user_var: filename output)"},
{TOK_FILE,"File",1,-1,"[/nonfatal] ([/a] [/r] filespec [...]|/oname=outfile one_file_only)"},
{TOK_FILE,"File",1,-1,"[/nonfatal] [/a] ([/r] filespec [...]|/oname=outfile one_file_only)"},
{TOK_RESERVEFILE,"ReserveFile",1,-1,"[/nonfatal] [/r] file [file...]"},
{TOK_FILECLOSE,"FileClose",1,0,"$(user_var: handle input)"},
{TOK_FILEERRORTEXT,"FileErrorText",0,2,"[/LANG=lang_id] [text (can contain $0)]"},
@ -105,6 +105,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_NOP,"Nop",0,0,""},
{TOK_NAME,"Name",1,1,"[/LANG=lang_id] installer_name"},
{TOK_OUTFILE,"OutFile",1,0,"install_output.exe"},
{TOK_PAGE,"Page",1,2,"custom function | (license|components|directory|instfiles) [pre_function] [post_function]"},
{TOK_POP,"Pop",1,0,"$(user_var: output)"},
{TOK_PUSH,"Push",1,0,"string"},
{TOK_QUIT,"Quit",0,0,""},
@ -154,9 +155,10 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_STRLEN,"StrLen",2,0,"$(user_var: length output) str"},
{TOK_SUBCAPTION,"SubCaption",2,1,"[/LANG=lang_id] page_number(0-4) new_subcaption"},
{TOK_UNINSTALLEXENAME,"UninstallExeName",0,0,"no longer supported, use WriteUninstaller from section."},
{TOK_UNINSTICON,"UninstallIcon",1,0,"icon_on_local_system.ico"},
{TOK_UNINSTTEXT,"UninstallText",1,2,"[/LANG=lang_id] Text_to_go_on_uninstall page [subtext]"},
{TOK_UNINSTCAPTION,"UninstallCaption",1,1,"[/LANG=lang_id] uninstaller_caption"},
{TOK_UNINSTICON,"UninstallIcon",1,0,"icon_on_local_system.ico"},
{TOK_UNINSTPAGE,"UninstPage",1,2,"custom function | (uninstConfirm|instfiles) [pre_function] [post_function]"},
{TOK_UNINSTTEXT,"UninstallText",1,2,"[/LANG=lang_id] Text_to_go_on_uninstall page [subtext]"},
{TOK_UNINSTSUBCAPTION,"UninstallSubCaption",2,1,"[/LANG=lang_id] page_number(0-2) new_subcaption"},
{TOK_UNREGDLL,"UnRegDLL",1,0,"dll_path_on_target.dll"},
// useless - {TOK_USEOUTERUIITEM,"UseOuterUIItem",2,0,"item id"},

View file

@ -87,6 +87,10 @@ enum
TOK_FUNCTIONEND,
TOK_ADDSIZE,
// Page oredering shit
TOK_PAGE,
TOK_UNINSTPAGE,
// flag setters
TOK_SETDATESAVE,
TOK_SETOVERWRITE,