Even easier paging system, no more Abort and Quit from custom pages creator functions, NSIS does it all!

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@1636 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2002-11-09 12:50:00 +00:00
parent 35b45db225
commit 297e981d32
17 changed files with 123 additions and 335 deletions

View file

@ -1,6 +1,6 @@
#include <Windows.h> #include <Windows.h>
#include <Mmsystem.h> #include <Mmsystem.h>
#include "exdll.h" #include "../exdll/exdll.h"
int x, y; int x, y;
char temp[MAX_PATH]; char temp[MAX_PATH];

View file

@ -67,7 +67,7 @@ SOURCE=.\BgImage.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl" # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File # Begin Source File
SOURCE=.\exdll.h SOURCE=..\ExDLL\exdll.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Resource Files" # Begin Group "Resource Files"

View file

@ -1,49 +0,0 @@
#ifndef _EXDLL_H_
#define _EXDLL_H_
// only include this file from one place in your DLL.
// (it is all static, if you use it in two places it will fail)
#define EXDLL_INIT() { \
g_hwndParent=hwndParent; \
g_stringsize=string_size; \
g_stacktop=stacktop; \
/*g_variables=variables;*/ }
typedef struct _stack_t {
struct _stack_t *next;
char text[1]; // this should be the length of string_size
} stack_t;
static int g_stringsize;
static stack_t **g_stacktop;
static HWND g_hwndParent;
static int popstring(char *str); // 0 on success, 1 on empty stack
static void pushstring(char *str);
// utility functions (not required but often useful)
static int popstring(char *str)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
lstrcpy(str,th->text);
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th);
return 0;
}
static void pushstring(char *str)
{
stack_t *th;
if (!g_stacktop) return;
th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
lstrcpyn(th->text,str,g_stringsize);
th->next=*g_stacktop;
*g_stacktop=th;
}
#endif//_EXDLL_H_

View file

@ -9,6 +9,8 @@
g_stacktop=stacktop; \ g_stacktop=stacktop; \
g_variables=variables; } g_variables=variables; }
// For page showing plug-ins
#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
typedef struct _stack_t { typedef struct _stack_t {
struct _stack_t *next; struct _stack_t *next;

View file

@ -282,10 +282,8 @@ Here is a little example:
InstallOptions::show InstallOptions::show
Pop $0 Pop $0
StrCmp $0 "success" done StrCmp $0 "success" done
StrCmp $0 "back" 0 +2 StrCmp $0 "back" done
Abort StrCmp $0 "cancel" done
StrCmp $0 "cancel" 0 error
Quit
error: error:
MessageBox MB_OK|MB_ICONSTOP "IO error: $0" MessageBox MB_OK|MB_ICONSTOP "IO error: $0"
Quit Quit
@ -404,8 +402,8 @@ Here is a little example:
<UL> <UL>
<LI>Barely qualifies as a distribution. </LI></UL></LI></UL> <LI>Barely qualifies as a distribution. </LI></UL></LI></UL>
<HR> <HR>
<A name=license><PRE> Copyright © 2001 Michael Bishop <A name=license><PRE> Copyright &copy; 2001 Michael Bishop
Portions Copyright © 2001 Nullsoft, Inc. Portions Copyright &copy; 2001 Nullsoft, Inc.
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages warranty. In no event will the authors be held liable for any damages

View file

@ -165,12 +165,9 @@ HINSTANCE m_hInstance = NULL;
char *pszFilename = NULL; char *pszFilename = NULL;
char *pszTitle = NULL; char *pszTitle = NULL;
char *pszCancelQuestion = NULL;
char *pszCancelQuestionCaption = NULL;
char *pszCancelButtonText = NULL; char *pszCancelButtonText = NULL;
char *pszNextButtonText = NULL; char *pszNextButtonText = NULL;
char *pszBackButtonText = NULL; char *pszBackButtonText = NULL;
unsigned int nCancelConfirmFlags=0;
BOOL bBackDisabled=FALSE; BOOL bBackDisabled=FALSE;
BOOL bCancelEnabled=TRUE; // by ORTIM: 13-August-2002 BOOL bCancelEnabled=TRUE; // by ORTIM: 13-August-2002
@ -455,36 +452,12 @@ char * WINAPI myGetProfileStringDup(LPCTSTR lpAppName, LPCTSTR lpKeyName)
bool ReadSettings(void) { bool ReadSettings(void) {
static char szField[25]; static char szField[25];
int nIdx; int nIdx;
// Messagebox flags
static TableEntry MBFlagTable[] = {
{ "MB_ICONEXCLAMATION", MB_ICONEXCLAMATION },
// { "MB_ICONWARNING", MB_ICONWARNING }, // same as above
{ "MB_ICONINFORMATION", MB_ICONINFORMATION },
// { "MB_ICONASTERISK", MB_ICONASTERISK }, // same as above
{ "MB_ICONQUESTION", MB_ICONQUESTION },
{ "MB_ICONSTOP", MB_ICONSTOP },
// { "MB_ICONERROR", MB_ICONERROR }, // same as above
// { "MB_ICONHAND", MB_ICONHAND }, // same as above
{ "MB_TOPMOST", MB_TOPMOST },
{ "MB_SETFOREGROUND", MB_SETFOREGROUND },
{ "MB_RIGHT", MB_RIGHT },
{ "MB_DEFBUTTON1", MB_DEFBUTTON1 },
{ "MB_DEFBUTTON2", MB_DEFBUTTON2 },
// { "MB_DEFBUTTON3", MB_DEFBUTTON3 }, // useless, as there are only two buttons
// { "MB_DEFBUTTON4", MB_DEFBUTTON4 }, // useless, as there are only two buttons
{ NULL, 0 }
};
pszTitle = myGetProfileStringDup("Settings", "Title"); pszTitle = myGetProfileStringDup("Settings", "Title");
pszCancelQuestion = myGetProfileStringDup("Settings", "CancelConfirm");
pszCancelQuestionCaption = myGetProfileStringDup("Settings", "CancelConfirmCaption");
pszCancelButtonText = myGetProfileStringDup("Settings", "CancelButtonText"); pszCancelButtonText = myGetProfileStringDup("Settings", "CancelButtonText");
pszNextButtonText = myGetProfileStringDup("Settings", "NextButtonText"); pszNextButtonText = myGetProfileStringDup("Settings", "NextButtonText");
pszBackButtonText = myGetProfileStringDup("Settings", "BackButtonText"); pszBackButtonText = myGetProfileStringDup("Settings", "BackButtonText");
myGetProfileString("Settings", "CancelConfirmFlags");
nCancelConfirmFlags = LookupTokens(MBFlagTable, szResult);
nNumFields = GetPrivateProfileInt("Settings", "NumFields", 0, pszFilename); nNumFields = GetPrivateProfileInt("Settings", "NumFields", 0, pszFilename);
bBackDisabled = GetPrivateProfileInt("Settings", "BackDisabled", 0, pszFilename); bBackDisabled = GetPrivateProfileInt("Settings", "BackDisabled", 0, pszFilename);
@ -671,15 +644,9 @@ static void *lpWndProcOld;
static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
if (message == WM_CLOSE) if (message == WM_NOTIFY_OUTER_NEXT)
{ {
message = WM_COMMAND; PostMessage(hConfigWindow,WM_USER+666,wParam,0);
wParam = IDCANCEL;
}
if (message == WM_COMMAND && (LOWORD(wParam) == IDCANCEL || LOWORD(wParam) == IDOK || LOWORD(wParam) == 3))
{
PostMessage(hConfigWindow,WM_USER+666,0,LOWORD(wParam));
return 0;
} }
return CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam); return CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam);
} }
@ -697,14 +664,11 @@ BOOL CALLBACK cfgDlgProc(HWND hwndDlg,
HANDLE_MSG(hwndDlg, WM_COMMAND, WMCommandProc); HANDLE_MSG(hwndDlg, WM_COMMAND, WMCommandProc);
return 0; return 0;
case WM_USER+666: case WM_USER+666:
if (lParam != IDCANCEL || !pszCancelQuestion || MessageBox(hwndDlg,pszCancelQuestion,pszCancelQuestionCaption?pszCancelQuestionCaption:"Question",MB_YESNO|nCancelConfirmFlags)==IDYES) if (wParam == 0xD1E || wParam == -1 || ValidateFields()) {
{ if (wParam == -1) g_is_back++;
if (lParam == IDCANCEL || lParam == 3 || ValidateFields()) { if (wParam == 0xD1E) g_is_cancel++;
if (lParam == 3) g_is_back++; g_done++;
if (lParam == IDCANCEL) g_is_cancel++; PostMessage(hwndDlg,WM_CLOSE,0,0);
g_done++;
PostMessage(hwndDlg,WM_CLOSE,0,0);
}
} }
break; break;
case WM_CTLCOLORSTATIC: case WM_CTLCOLORSTATIC:
@ -1036,8 +1000,6 @@ void showCfgDlg()
if (cw_vis) ShowWindow(childwnd,SW_SHOWNA); if (cw_vis) ShowWindow(childwnd,SW_SHOWNA);
FREE(pszTitle); FREE(pszTitle);
FREE(pszCancelQuestion);
FREE(pszCancelQuestionCaption);
FREE(pszCancelButtonText); FREE(pszCancelButtonText);
FREE(pszNextButtonText); FREE(pszNextButtonText);
FREE(pszBackButtonText); FREE(pszBackButtonText);

View file

@ -61,21 +61,22 @@ FunctionEnd
Function SetCustom Function SetCustom
;Display the Install Options dialog ;Display the Install Options dialog
Push ${TEMP1} Push ${TEMP1}
InstallOptions::dialog "$PLUGINSDIR\test.ini" InstallOptions::dialog "$PLUGINSDIR\test.ini"
Pop ${TEMP1} Pop ${TEMP1}
StrCmp ${TEMP1} "cancel" "" +3 StrCmp ${TEMP1} "cancel" done
Pop ${TEMP1} StrCmp ${TEMP1} "back" done
Quit StrCmp ${TEMP1} "success" 0 error
# User clicked Next, all fields validated, read stuff from the INI here or later
Goto done
error:
MessageBox MB_OK|MB_ICONSTOP "InstallOptions error:$\r$\n${TEMP1}"
done: Pop ${TEMP1}
StrCmp ${TEMP1} "back" "" +3
Pop ${TEMP1}
Abort
Pop ${TEMP1}
FunctionEnd FunctionEnd

View file

@ -9,7 +9,7 @@ OutFile "StartMenu Test.exe"
XPStyle on XPStyle on
Page directory Page directory
DirText "This installer will create some shortcuts to MakeNSIS in the start menu.$\nFor this it needs NSIS's folder path." \ DirText "This installer will create some shortcuts to MakeNSIS in the start menu.$\nFor this it needs NSIS's path." \
"Please specify the path in which you have installed NSIS:" "Please specify the path in which you have installed NSIS:"
InstallDir "${NSISDIR}" InstallDir "${NSISDIR}"
Function .onVerifyInstDir Function .onVerifyInstDir
@ -21,7 +21,7 @@ Page custom StartMenuGroupSelect
Function StartMenuGroupSelect Function StartMenuGroupSelect
SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:StartMenu.dll test Setup: Start Menu Folder" SendMessage $HWNDPARENT ${WM_SETTEXT} 0 "STR:StartMenu.dll test Setup: Start Menu Folder"
StartMenu::Select /autoadd "StartMenu.dll test" StartMenu::Select /autoadd /lastused $R0 "StartMenu.dll test"
Pop $R1 Pop $R1
StrCpy $R2 $R1 5 StrCpy $R2 $R1 5
@ -29,11 +29,8 @@ Function StartMenuGroupSelect
; error ; error
MessageBox MB_OK $R1 MessageBox MB_OK $R1
Return Return
StrCmp $R1 "cancel" 0 +2 StrCpy $R0 $R1 ; got the dir, or cancel, but if it's cancel NSIS will exit and
Quit ; then we shouldn't care about the value of $R0
StrCmp $R1 "back" 0 +2
Abort
StrCpy $R0 $R1 ; got the dir
FunctionEnd FunctionEnd
Page instfiles Page instfiles

View file

@ -5,10 +5,11 @@ To show the dialog use the Select function. This function has one required param
which is the program group default name, and some more optional parameters: which is the program group default name, and some more optional parameters:
/autoadd - automatically adds the program name to the selected folder /autoadd - automatically adds the program name to the selected folder
/noicon - doesn't show the icon in the top left corner /noicon - doesn't show the icon in the top left corner
/text [please select...] - sets the top text to something else than "Select /text [please select...] - sets the top text to something else than
the Start Menu folder in which..." "Select the Start Menu folder in which..."
/cancelconfirm [text] [caption] [flags] - displays a cancel confirmation /lastused [folder] - sets the edit box to a specific value folder.
message box when the user click on the cancel button Use this to make this plug-in remember the last
folder selected by the user
The function pushes the folder selection back to the stack. It does not push the The function pushes the folder selection back to the stack. It does not push the
full path but only the selected sub-folder. It's up to you to decide if to put full path but only the selected sub-folder. It's up to you to decide if to put

View file

@ -1,7 +1,9 @@
#include <windows.h> #include <windows.h>
#include "exdll.h" #include "../exdll/exdll.h"
#include "resource.h" #include "resource.h"
#define WM_NOTIFY_OUTER_NEXT (WM_USER+0x8)
HINSTANCE g_hInstance; HINSTANCE g_hInstance;
HWND hwParent; HWND hwParent;
@ -15,10 +17,7 @@ HWND hwDirList;
char buf[MAX_PATH]; char buf[MAX_PATH];
char text[1024]; char text[1024];
char progname[1024]; char progname[1024];
char cancelconfirm[1024]; char lastused[1024];
char cancelconfirmcaption[1024];
unsigned int cancelconfirmflags = 0;
int autoadd = 0; int autoadd = 0;
int g_done = 0; int g_done = 0;
@ -71,24 +70,9 @@ void __declspec(dllexport) Select(HWND hwndParent, int string_size, char *variab
{ {
autoadd = 1; autoadd = 1;
} }
else if (!lstrcmpi(buf+1, "cancelconfirm")) else if (!lstrcmpi(buf+1, "lastused"))
{ {
static TableEntry MBFlagTable[] = { popstring(lastused);
{ "MB_ICONEXCLAMATION", MB_ICONEXCLAMATION },
{ "MB_ICONINFORMATION", MB_ICONINFORMATION },
{ "MB_ICONQUESTION", MB_ICONQUESTION },
{ "MB_ICONSTOP", MB_ICONSTOP },
{ "MB_TOPMOST", MB_TOPMOST },
{ "MB_SETFOREGROUND", MB_SETFOREGROUND },
{ "MB_RIGHT", MB_RIGHT },
{ "MB_DEFBUTTON1", MB_DEFBUTTON1 },
{ "MB_DEFBUTTON2", MB_DEFBUTTON2 },
{ NULL, 0 }
};
popstring(cancelconfirm);
popstring(cancelconfirmcaption);
popstring(buf);
cancelconfirmflags = LookupTokens(MBFlagTable, buf);
} }
if (popstring(buf)) if (popstring(buf))
*buf = 0; *buf = 0;
@ -131,15 +115,9 @@ void __declspec(dllexport) Select(HWND hwndParent, int string_size, char *variab
static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{ {
if (message == WM_CLOSE) if (message == WM_NOTIFY_OUTER_NEXT)
{ {
message = WM_COMMAND; PostMessage(hwStartMenuSelect,WM_USER+666,wParam,0);
wParam = IDCANCEL;
}
if (message == WM_COMMAND && (LOWORD(wParam) == IDCANCEL || LOWORD(wParam) == IDOK || LOWORD(wParam) == 3))
{
PostMessage(hwStartMenuSelect,WM_USER+666,0,LOWORD(wParam));
return 0;
} }
return CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam); return CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam);
} }
@ -238,7 +216,7 @@ BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
temp_r.bottom - temp_r.top temp_r.bottom - temp_r.top
); );
SendMessage(hwLocation, WM_SETTEXT, 0, (LPARAM) progname); SendMessage(hwLocation, WM_SETTEXT, 0, (LPARAM) (*lastused ? lastused : progname));
ProgressiveSetWindowPos( ProgressiveSetWindowPos(
hwDirList, hwDirList,
@ -268,20 +246,12 @@ BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
break; break;
case WM_USER+666: case WM_USER+666:
g_done = 1; g_done = 1;
switch (lParam) { if (wParam == 0xD1E)
case IDOK: pushstring("cancel");
SendMessage(hwLocation, WM_GETTEXT, MAX_PATH, (LPARAM) buf); else
pushstring(buf); {
break; SendMessage(hwLocation, WM_GETTEXT, MAX_PATH, (LPARAM) buf);
case IDCANCEL: pushstring(buf);
if (*cancelconfirm && MessageBox(hwStartMenuSelect, cancelconfirm, cancelconfirmcaption, MB_YESNO|cancelconfirmflags) == IDNO)
g_done = 0;
else
pushstring("cancel");
break;
case 3:
pushstring("back");
break;
} }
break; break;
} }

View file

@ -101,7 +101,7 @@ SOURCE=.\StartMenu.c
# PROP Default_Filter "h;hpp;hxx;hm;inl" # PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File # Begin Source File
SOURCE=.\ExDLL.h SOURCE=..\ExDLL\exdll.h
# End Source File # End Source File
# End Group # End Group
# Begin Group "Resource Files" # Begin Group "Resource Files"

View file

@ -1,93 +0,0 @@
#ifndef _EXDLL_H_
#define _EXDLL_H_
// only include this file from one place in your DLL.
// (it is all static, if you use it in two places it will fail)
#define EXDLL_INIT() { \
g_stringsize=string_size; \
g_stacktop=stacktop; \
g_variables=variables; }
typedef struct _stack_t {
struct _stack_t *next;
char text[1]; // this should be the length of string_size
} stack_t;
static int g_stringsize;
static stack_t **g_stacktop;
static char *g_variables;
static int popstring(char *str); // 0 on success, 1 on empty stack
static void pushstring(char *str);
enum
{
INST_0, // $0
INST_1, // $1
INST_2, // $2
INST_3, // $3
INST_4, // $4
INST_5, // $5
INST_6, // $6
INST_7, // $7
INST_8, // $8
INST_9, // $9
INST_R0, // $R0
INST_R1, // $R1
INST_R2, // $R2
INST_R3, // $R3
INST_R4, // $R4
INST_R5, // $R5
INST_R6, // $R6
INST_R7, // $R7
INST_R8, // $R8
INST_R9, // $R9
INST_CMDLINE, // $CMDLINE
INST_INSTDIR, // $INSTDIR
INST_OUTDIR, // $OUTDIR
INST_EXEDIR, // $EXEDIR
INST_LANG, // $LANGUAGE
__INST_LAST
};
// utility functions (not required but often useful)
static int popstring(char *str)
{
stack_t *th;
if (!g_stacktop || !*g_stacktop) return 1;
th=(*g_stacktop);
lstrcpy(str,th->text);
*g_stacktop = th->next;
GlobalFree((HGLOBAL)th);
return 0;
}
static void pushstring(char *str)
{
stack_t *th;
if (!g_stacktop) return;
th=(stack_t*)GlobalAlloc(GPTR,sizeof(stack_t)+g_stringsize);
lstrcpyn(th->text,str,g_stringsize);
th->next=*g_stacktop;
*g_stacktop=th;
}
static char *getuservariable(int varnum)
{
if (varnum < 0 || varnum >= __INST_LAST) return NULL;
return g_variables+varnum*g_stringsize;
}
static void setuservariable(int varnum, char *var)
{
if (var != NULL && varnum >= 0 && varnum < __INST_LAST)
lstrcpy(g_variables + varnum*g_stringsize, var);
}
#endif//_EXDLL_H_

View file

@ -25,11 +25,7 @@ Each built-in page has two callback functions. The pre-function and the post-cre
A custom page has only one callback function that creates it but unlike the built-in pages this function is mandatory. 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. Use Abort (see \K{abort}) from a built-in page pre-function to to skip the page.
\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: Examples:
@ -47,14 +43,12 @@ Examples:
\c GetTempFileName $R0 \c GetTempFileName $R0
\c File /oname=$R0 customPage.ini \c File /oname=$R0 customPage.ini
\c InstallOptions::dialog $R0 \c InstallOptions::dialog $R0
\c Delete $R0
\c Pop $R1 \c Pop $R1
\c StrCmp $R1 "cancel" "" nocancel \c StrCmp $R1 "cancel" done
\c Quit \c StrCmp $R1 "back" done
\c nocancel: \c StrCmp $R1 "sucess" done
\c StrCmp $R1 "back" "" noback \c error: MessageBox MB_OK|MB_ICONSTOP "InstallOptions error:$\r$\n$R1"
\c Abort \c done:
\c noback:
\c FunctionEnd \c FunctionEnd
\S{page} Page \S{page} Page

Binary file not shown.

Binary file not shown.

View file

@ -1355,7 +1355,7 @@ int CEXEBuild::write_output(void)
page *p=(page *) build_pages.get(); page *p=(page *) build_pages.get();
for (int i=0; i<build_header.common.num_pages; i++, p++) { for (int i=0; i<build_header.common.num_pages; i++, p++) {
if (i) p->back=2; // 2 - enabled, 1 - disabled, 0 - invisible if (i) p->back=SW_SHOWNA|2; // 2 - enabled, SW_SHOWNA - visible, 0 - invisible (or'ed)
else p->back=0; else p->back=0;
p->next=LANG_BTN_NEXT; p->next=LANG_BTN_NEXT;
@ -1367,7 +1367,7 @@ int CEXEBuild::write_output(void)
p->next=LANG_BTN_LICENSE; p->next=LANG_BTN_LICENSE;
#endif #endif
if (p->id==NSIS_PAGE_INSTFILES || p->id==NSIS_PAGE_COMPLETED) if (p->id==NSIS_PAGE_INSTFILES || p->id==NSIS_PAGE_COMPLETED)
p->back=1; p->back&=~2;
} }
(--p)->next=LANG_BTN_CLOSE; (--p)->next=LANG_BTN_CLOSE;
if (p->id==NSIS_PAGE_COMPLETED) (--p)->next=LANG_BTN_CLOSE; if (p->id==NSIS_PAGE_COMPLETED) (--p)->next=LANG_BTN_CLOSE;

View file

@ -75,8 +75,13 @@ static int num_sections;
#define WM_TREEVIEW_KEYHACK (WM_USER+0x13) #define WM_TREEVIEW_KEYHACK (WM_USER+0x13)
static void NSISCALL outernotify(char num) { static int m_page,m_abort,m_retcode,m_delta;
SendMessage(g_hwnd,WM_NOTIFY_OUTER_NEXT,(WPARAM)num,0);
static void NSISCALL outernotify(int num) {
if (num==0xD1E)
g_quit_flag=1;
m_delta=num;
SendMessage(g_hwnd,WM_NOTIFY_OUTER_NEXT,(WPARAM)num,0); // it sends num again for plugins - DON'T REMOVE!
} }
#ifdef NSIS_CONFIG_VISIBLE_SUPPORT #ifdef NSIS_CONFIG_VISIBLE_SUPPORT
@ -102,7 +107,6 @@ page *g_inst_page;
section *g_inst_section; section *g_inst_section;
entry *g_inst_entry; entry *g_inst_entry;
static int m_page=-1,m_abort;
static HWND m_curwnd, m_bgwnd, m_hwndOK, m_hwndCancel; static HWND m_curwnd, m_bgwnd, m_hwndOK, m_hwndCancel;
static int m_whichcfg; static int m_whichcfg;
@ -442,7 +446,7 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{ {
if (uMsg == WM_INITDIALOG || uMsg == WM_NOTIFY_OUTER_NEXT) if (uMsg == WM_INITDIALOG || uMsg == WM_NOTIFY_OUTER_NEXT)
{ {
#define delta wParam page *this_page;
static struct static struct
{ {
char *id; char *id;
@ -479,10 +483,18 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
ShowWindow(hwndDlg,SW_SHOW); ShowWindow(hwndDlg,SW_SHOW);
} }
// initial m_page is zero, m_pages grows and checked after this line so no memory misread
this_page=g_inst_page+m_page;
// if the last page was a custom page, wait for it to finish by itself.
// if it doesn't, it's a bad plugin.
// plugins should react to WM_NOTIFY_OUTER_NEXT.
if (this_page->id<0) return 0;
nextPage: nextPage:
if (m_page<0) delta=1; m_page+=m_delta;
m_page+=delta; this_page+=m_delta;
#ifdef NSIS_SUPPORT_CODECALLBACKS #ifdef NSIS_SUPPORT_CODECALLBACKS
if (m_page==g_inst_cmnheader->num_pages) ExecuteCodeSegment(g_inst_cmnheader->code_onInstSuccess,NULL); if (m_page==g_inst_cmnheader->num_pages) ExecuteCodeSegment(g_inst_cmnheader->code_onInstSuccess,NULL);
@ -491,69 +503,57 @@ nextPage:
if (g_quit_flag || m_page < 0 || m_page == g_inst_cmnheader->num_pages) if (g_quit_flag || m_page < 0 || m_page == g_inst_cmnheader->num_pages)
{ {
DestroyWindow(m_curwnd); DestroyWindow(m_curwnd);
EndDialog(hwndDlg,0); EndDialog(hwndDlg,m_retcode);
} }
else else
{ {
HWND hwndtmp; HWND hwndtmp;
int page_id=g_inst_page[m_page].id;
SetDlgItemTextFromLang(hwndDlg,IDOK,g_inst_page[m_page].next); SetDlgItemTextFromLang(hwndDlg,IDOK,this_page->next);
hwndtmp=GetDlgItem(hwndDlg,IDC_BACK); hwndtmp=GetDlgItem(hwndDlg,IDC_BACK);
ShowWindow(hwndtmp,g_inst_page[m_page].back?SW_SHOWNA:SW_HIDE); ShowWindow(hwndtmp,this_page->back&SW_SHOWNA);// SW_HIDE = 0
EnableWindow(hwndtmp, g_inst_page[m_page].back&2); EnableWindow(hwndtmp,this_page->back&2);
if (page_id!=NSIS_PAGE_COMPLETED) DestroyWindow(m_curwnd); if (this_page->id!=NSIS_PAGE_COMPLETED) DestroyWindow(m_curwnd);
else if (g_autoclose) goto nextPage; else if (g_autoclose) goto nextPage;
if (page_id>=0) // NSIS page
{
#ifdef NSIS_SUPPORT_CODECALLBACKS #ifdef NSIS_SUPPORT_CODECALLBACKS
if (ExecuteCodeSegment(g_inst_page[m_page].prefunc,NULL)) if (ExecuteCodeSegment(this_page->prefunc,NULL) || this_page->id<0)
goto nextPage;
else
#endif //NSIS_SUPPORT_CODECALLBACKS
{
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; goto nextPage;
#endif //NSIS_SUPPORT_CODECALLBACKS
if (this_page->id>=0) // NSIS page
{
mystrcpy(g_tmp,g_caption);
process_string_fromtab(
g_tmp+mystrlen(g_tmp),
LANG_SUBCAPTION(this_page->id-(g_is_uninstaller?NSIS_PAGE_INSTFILES:0))
);
SetWindowText(hwndDlg,g_tmp);
gDontFookWithFocus = 0;
m_curwnd=CreateDialog(g_hInstance,windows[this_page->id].id,hwndDlg,windows[this_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
} }
ExecuteCodeSegment(g_inst_page[m_page].postfunc,NULL); #ifdef NSIS_SUPPORT_CODECALLBACKS
ExecuteCodeSegment(this_page->postfunc,NULL);
#endif //NSIS_SUPPORT_CODECALLBACKS #endif //NSIS_SUPPORT_CODECALLBACKS
} }
} }
@ -580,7 +580,8 @@ nextPage:
#ifdef NSIS_SUPPORT_CODECALLBACKS #ifdef NSIS_SUPPORT_CODECALLBACKS
ExecuteCodeSegment(g_inst_cmnheader->code_onInstFailed,NULL); ExecuteCodeSegment(g_inst_cmnheader->code_onInstFailed,NULL);
#endif//NSIS_SUPPORT_CODECALLBACKS #endif//NSIS_SUPPORT_CODECALLBACKS
EndDialog(hwndDlg,2); m_retcode=2;
outernotify(0xD1E);
} }
else else
{ {
@ -588,7 +589,8 @@ nextPage:
if (!ExecuteCodeSegment(g_inst_cmnheader->code_onUserAbort,NULL)) if (!ExecuteCodeSegment(g_inst_cmnheader->code_onUserAbort,NULL))
#endif//NSIS_SUPPORT_CODECALLBACKS #endif//NSIS_SUPPORT_CODECALLBACKS
{ {
EndDialog(hwndDlg,1); m_retcode=1;
outernotify(0xD1E);
} }
} }
} }
@ -1362,7 +1364,10 @@ static BOOL CALLBACK InstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lPa
if (uMsg == WM_NOTIFY_INSTPROC_DONE) if (uMsg == WM_NOTIFY_INSTPROC_DONE)
{ {
if (g_quit_flag) if (g_quit_flag)
EndDialog(g_hwnd,1); {
m_retcode=1;
outernotify(0xD1E);
}
else if (!wParam) else if (!wParam)
{ {
HWND h=m_hwndOK; HWND h=m_hwndOK;