Leave function for custom pages too

git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2335 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
kichik 2003-03-18 15:45:25 +00:00
parent 156648c9d5
commit 070d1f136a
10 changed files with 81 additions and 56 deletions

View file

@ -605,17 +605,27 @@ LRESULT WMCommandProc(HWND hWnd, UINT id, HWND hwndCtl, UINT codeNotify) {
static void *lpWndProcOld;
static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_NOTIFY_OUTER_NEXT)
{
PostMessage(hConfigWindow,WM_USER+666,wParam,0);
}
return CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam);
}
int g_is_cancel,g_is_back;
BOOL CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
BOOL bRes;
if (message == WM_NOTIFY_OUTER_NEXT && wParam == 1)
// Get the settings ready for the leave function verification
SaveSettings();
bRes = CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam);
if (message == WM_NOTIFY_OUTER_NEXT && !bRes)
{
// if leave function didn't abort (lRes != 0 in that case)
if (wParam == NOTIFY_BYE_BYE || wParam == -1 || ValidateFields()) {
if (wParam == -1) g_is_back++;
if (wParam == NOTIFY_BYE_BYE) g_is_cancel++;
g_done++;
PostMessage(hConfigWindow,WM_CLOSE,0,0);
}
}
return bRes;
}
BOOL CALLBACK cfgDlgProc(HWND hwndDlg,
UINT uMsg,
@ -625,15 +635,6 @@ BOOL CALLBACK cfgDlgProc(HWND hwndDlg,
switch (uMsg)
{
HANDLE_MSG(hwndDlg, WM_COMMAND, WMCommandProc);
return 0;
case WM_USER+666:
if (wParam == NOTIFY_BYE_BYE || wParam == -1 || ValidateFields()) {
if (wParam == -1) g_is_back++;
if (wParam == NOTIFY_BYE_BYE) g_is_cancel++;
g_done++;
PostMessage(hwndDlg,WM_CLOSE,0,0);
}
break;
case WM_CTLCOLORSTATIC:
case WM_CTLCOLORDLG:
SetBkMode((HDC)wParam, TRANSPARENT);
@ -962,7 +963,7 @@ int createCfgDlg()
void showCfgDlg()
{
lpWndProcOld = (void *) SetWindowLong(hMainWindow,GWL_WNDPROC,(long)ParentWndProc);
lpWndProcOld = (void *) SetWindowLong(hMainWindow,DWL_DLGPROC,(long)ParentWndProc);
SendMessage(hMainWindow, WM_NOTIFY_CUSTOM_READY, 0, 0);
ShowWindow(hConfigWindow, SW_SHOWNA);
@ -982,7 +983,7 @@ void showCfgDlg()
if (!g_is_cancel) SaveSettings();
if (lpWndProcOld)
SetWindowLong(hMainWindow,GWL_WNDPROC,(long)lpWndProcOld);
SetWindowLong(hMainWindow,DWL_DLGPROC,(long)lpWndProcOld);
DestroyWindow(hConfigWindow);
if (was_ok_enabled) EnableWindow(hNextButton,0);
SetWindowText(hCancelButton,old_cancel);

View file

@ -10,6 +10,9 @@ Name "InstallOptions Test"
;The file to write
OutFile "Test.exe"
; Show install details
ShowInstDetails show
;Things that need to be extracted on startup (keep these lines before any File command!)
;Only useful for BZIP2 compression
;Use ReserveFile for your own InstallOptions INI files too!
@ -18,7 +21,7 @@ ReserveFile "${NSISDIR}\Plugins\InstallOptions.dll"
ReserveFile "test.ini"
;Order of pages
Page custom SetCustom ": Testing InstallOptions" ;Custom page. InstallOptions gets called in SetCustom.
Page custom SetCustom VerifyCustom ": Testing InstallOptions" ;Custom page. InstallOptions gets called in SetCustom.
Page instfiles
Section "Components"
@ -26,15 +29,15 @@ Section "Components"
;Get Install Options dialog user input
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 2" "State"
MessageBox MB_OK "Install X=${TEMP1}"
DetailPrint "Install X=${TEMP1}"
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 3" "State"
MessageBox MB_OK "Install Y=${TEMP1}"
DetailPrint "Install Y=${TEMP1}"
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 4" "State"
MessageBox MB_OK "Install Z=${TEMP1}"
DetailPrint "Install Z=${TEMP1}"
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 5" "State"
MessageBox MB_OK "File=${TEMP1}"
DetailPrint "File=${TEMP1}"
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 6" "State"
MessageBox MB_OK "Dir=${TEMP1}"
DetailPrint "Dir=${TEMP1}"
SectionEnd
@ -59,4 +62,16 @@ Function SetCustom
Pop ${TEMP1}
FunctionEnd
Function VerifyCustom
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 2" "State"
StrCmp ${TEMP1} 1 done
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 3" "State"
StrCmp ${TEMP1} 1 done
ReadINIStr ${TEMP1} "$PLUGINSDIR\test.ini" "Field 4" "State"
StrCmp ${TEMP1} 1 done
MessageBox MB_ICONSTOP|MB_OK "You must select at least one install option!"
Abort
done:
FunctionEnd

View file

@ -26,7 +26,7 @@ int noicon = 0;
void *lpWndProcOld;
BOOL CALLBACK dlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK ParentWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
BOOL CALLBACK ParentWndProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void AddFolderFromReg(HKEY rootKey);
void __declspec(dllexport) Select(HWND hwndParent, int string_size, char *variables, stack_t **stacktop)
@ -91,7 +91,7 @@ void __declspec(dllexport) Select(HWND hwndParent, int string_size, char *variab
}
else
{
lpWndProcOld = (void *) SetWindowLong(hwndParent, GWL_WNDPROC, (long) ParentWndProc);
lpWndProcOld = (void *) SetWindowLong(hwndParent, DWL_DLGPROC, (long) ParentWndProc);
}
while (!g_done)
@ -103,19 +103,21 @@ void __declspec(dllexport) Select(HWND hwndParent, int string_size, char *variab
}
DestroyWindow(hwStartMenuSelect);
SetWindowLong(hwndParent, GWL_WNDPROC, (long) lpWndProcOld);
SetWindowLong(hwndParent, DWL_DLGPROC, (long) lpWndProcOld);
if (cw_vis) ShowWindow(hwChild, SW_SHOW);
}
}
static LRESULT CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
static BOOL CALLBACK ParentWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
if (message == WM_NOTIFY_OUTER_NEXT)
BOOL bRes = CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam);
if (message == WM_NOTIFY_OUTER_NEXT && !bRes)
{
// if leave function didn't abort (lRes != 0 in that case)
PostMessage(hwStartMenuSelect,WM_USER+666,wParam,0);
}
return CallWindowProc((long (__stdcall *)(struct HWND__ *,unsigned int,unsigned int,long))lpWndProcOld,hwnd,message,wParam,lParam);
return bRes;
}
#define ProgressiveSetWindowPos(hwWindow, x, cx, cy) \

View file

@ -21,9 +21,9 @@ If you don't use any Page command the installer pages order will be just as in o
\S{pagecallbacks} Callbacks
Each built-in page has three callback functions. The pre-function, the show-creation function and the leave-function. The pre-function is called right before the page is created, the show-function is called right after it is created and before it is showen so you can tweak its user interface with \R{createfont}{CreateFont}, \R{setstaticbkcolor}{SetStaticBkColor } and \R{sendmessage}{SendMessage}; the leave-function is called right after the user has pressed the next button and before the page is left.
Each built-in page has three callback functions. The pre-function, the show-creation function and the leave-function. The pre-function is called right before the page is created, the show-function is called right after it is created and before it is shown so you can tweak its user interface with \R{createfont}{CreateFont}, \R{setstaticbkcolor}{SetStaticBkColor } and \R{sendmessage}{SendMessage}; the leave-function is called right after the user has pressed the next button and before the page is left.
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 two callback functions, one that creates it which is mandatory, and one leave-function that acts just like the leave-function for built-in pages.
Use \R{abort}{Abort} from a built-in page's pre-function to skip the page, and from a built-in page's leave-function to stay in the page.
@ -59,12 +59,12 @@ Examples:
\S{page} Page
\c ((custom [function] [caption]) | ((license|components|directory|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]
\c ((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]
Adds an installer page. See the above sections for more information about built-in versus custom pages and about callback functions. If define_if_last is specified, the parameter will be !defined if the page turns out to be the last page before a instfiles page. This helps you decide on dynamic scripts (such as the Modern UI script) what to put in this page's text, "click the install button to start installation" or "click next to continue" for example.
\S{uninstpage} UninstPage
\c ((custom [function] [caption]) | ((uninstConfirm|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]
\c ((custom [creator_function] [leave_function] [caption]) | ((uninstConfirm|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]
Adds an uninstaller page. See the above sections for more information about built-in versus custom pages and about callback functions. See Page for an explanation about define_if_last.

Binary file not shown.

Binary file not shown.

View file

@ -1086,9 +1086,9 @@ int CEXEBuild::resolve_coderefs(const char *str)
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","show-page function",p->showfunc,&p->showfunc)) return 1;
if (resolve_call_int("uninstall pages","leave-page function",p->leavefunc,&p->leavefunc)) return 1;
if (resolve_call_int("uninstall pages","pre-page",p->prefunc,&p->prefunc)) return 1;
if (resolve_call_int("uninstall pages","show-page",p->showfunc,&p->showfunc)) return 1;
if (resolve_call_int("uninstall pages","leave-page",p->leavefunc,&p->leavefunc)) return 1;
p++;
i++;
}

View file

@ -513,13 +513,13 @@ BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
this_page=g_inst_page+m_page;
if (m_page>=0) {
// Call leave function. If Abort used don't move to the next page.
if (m_delta==1) if (ExecuteCodeSegment(this_page->leavefunc,NULL)) return 1;
// 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;
// Call leave function. If Abort used don't move to the next page.
if (m_delta==1) if (ExecuteCodeSegment(this_page->leavefunc,NULL)) return 0;
}
nextPage:

View file

@ -618,13 +618,14 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
// a custom page
switch (line.getnumtokens() - enable_last_page_cancel) {
case 7:
PRINTHELP();
case 6:
ERROR_MSG("Error: custom page can not have more than the creator function.\n");
return PS_ERROR;
lstrcpy(build_last_page_define, line.gettoken_str(5));
case 5:
lstrcpy(build_last_page_define, line.gettoken_str(4));
p.caption = add_string_main(line.gettoken_str(4));
case 4:
p.caption = add_string_main(line.gettoken_str(3));
if (*line.gettoken_str(3))
p.leavefunc = ns_func.add(line.gettoken_str(3),0);
case 3:
if (*line.gettoken_str(2))
p.prefunc = ns_func.add(line.gettoken_str(2),0);
@ -678,8 +679,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
SCRIPT_MSG(" (%s:%s)", k?"pre":"creator", line.gettoken_str(2));
if (p.showfunc>=0 && k)
SCRIPT_MSG(" (show:%s)", line.gettoken_str(3));
if (p.leavefunc>=0 && k)
SCRIPT_MSG(" (leave:%s)", line.gettoken_str(4));
if (p.leavefunc>=0)
SCRIPT_MSG(" (leave:%s)", line.gettoken_str(4-!k));
else if (p.caption && !k)
SCRIPT_MSG(" (caption:%s)", line.gettoken_str(3));
#endif
@ -776,13 +777,19 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
// a custom page
switch (line.getnumtokens() - uenable_last_page_cancel) {
case 7:
PRINTHELP();
case 6:
ERROR_MSG("Error: custom page can not have more than the creator function.\n");
return PS_ERROR;
lstrcpy(ubuild_last_page_define, line.gettoken_str(5));
case 5:
lstrcpy(ubuild_last_page_define, line.gettoken_str(4));
p.caption = add_string_uninst(line.gettoken_str(4));
case 4:
p.caption = add_string_uninst(line.gettoken_str(3));
if (*line.gettoken_str(3)) {
if (strnicmp(line.gettoken_str(3),"un.",3)) {
ERROR_MSG("\nError: uninstall function must have a un. prefix!\n");
return PS_ERROR;
}
p.leavefunc = ns_func.add(line.gettoken_str(3),0);
}
case 3:
if (*line.gettoken_str(2)) {
if (strnicmp(line.gettoken_str(2),"un.",3)) {
@ -822,8 +829,8 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
SCRIPT_MSG(" (%s:%s)", k?"pre":"creator", line.gettoken_str(2));
if (p.showfunc>=0 && k)
SCRIPT_MSG(" (show:%s)", line.gettoken_str(3));
if (p.leavefunc>=0 && k)
SCRIPT_MSG(" (leave:%s)", line.gettoken_str(4));
if (p.leavefunc>=0)
SCRIPT_MSG(" (leave:%s)", line.gettoken_str(4-!k));
else if (p.caption && !k)
SCRIPT_MSG(" (caption:%s)", line.gettoken_str(3));
#endif

View file

@ -108,7 +108,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_NAME,"Name",1,1,"[/LANG=lang_id] installer_name"},
{TOK_OUTFILE,"OutFile",1,0,"install_output.exe"},
#ifdef NSIS_SUPPORT_CODECALLBACKS
{TOK_PAGE,"Page",1,5,"((custom [function] [caption]) | ((license|components|directory|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]"},
{TOK_PAGE,"Page",1,5,"((custom [creator_function] [leave_function] [caption]) | ((license|components|directory|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]"},
#else
{TOK_PAGE,"Page",1,1,"license|components|directory|instfiles"},
#endif
@ -168,7 +168,7 @@ static tokenType tokenlist[TOK__LAST] =
{TOK_UNINSTCAPTION,"UninstallCaption",1,1,"[/LANG=lang_id] uninstaller_caption"},
{TOK_UNINSTICON,"UninstallIcon",1,0,"icon_on_local_system.ico"},
#ifdef NSIS_SUPPORT_CODECALLBACKS
{TOK_UNINSTPAGE,"UninstPage",1,5,"((custom [function] [caption]) | ((uninstConfirm|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]"},
{TOK_UNINSTPAGE,"UninstPage",1,5,"((custom [creator_function] [leave_function] [caption]) | ((uninstConfirm|instfiles) [pre_function] [show_function] [leave_function])) [define_if_last]"},
#else
{TOK_UNINSTPAGE,"UninstPage",1,1,"uninstConfirm|instfiles"},
#endif