static INT_PTR CALLBACK UninstProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_INITDIALOG) { SetUITextFromLang(IDC_UNINSTFROM,this_page->parms[1]); SetUITextNT(IDC_EDIT1,g_usrvars[this_page->parms[4]]); } return HandleStaticBkColor(); }
INT_PTR CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { if (uMsg == WM_INITDIALOG || uMsg == WM_NOTIFY_OUTER_NEXT) { page *this_page; static DLGPROC winprocs[]= { #ifdef NSIS_CONFIG_LICENSEPAGE LicenseProc, #endif #ifdef NSIS_CONFIG_COMPONENTPAGE SelProc, #endif DirProc, InstProc, #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT UninstProc #endif }; m_delta = wParam; if (uMsg == WM_INITDIALOG) { g_hwnd=hwndDlg; m_hwndOK=GetDlgItem(hwndDlg,IDOK); m_hwndCancel=GetDlgItem(hwndDlg,IDCANCEL); SetDlgItemTextFromLang(hwndDlg,IDC_VERSTR,LANG_BRANDING); SetClassLongPtr(hwndDlg,GCLP_HICON,(LONG_PTR)g_hIcon); // use the following line instead of the above, if .rdata needs shirking //SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(LPARAM)g_hIcon); #if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT) g_quit_flag = ExecuteCallbackFunction(CB_ONGUIINIT); #endif //ShowWindow(hwndDlg, SW_SHOW); m_delta = 1; } this_page=g_pages+m_page; if (m_page>=0) { #ifdef NSIS_SUPPORT_CODECALLBACKS // Call leave function. If Abort used don't move to the next page. // But if quit called we must exit now if (m_delta==1) if (ExecuteCodeSegment(this_page->leavefunc,NULL)) { SendMessage(m_curwnd, WM_IN_UPDATEMSG, 0, 1); return !g_quit_flag; } #endif // 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->dlg_id) return 0; } NotifyCurWnd(WM_NOTIFY_INIGO_MONTOYA); nextPage: m_page+=m_delta; this_page+=m_delta; #ifdef NSIS_SUPPORT_CODECALLBACKS if (m_page==g_blocks[NB_PAGES].num) ExecuteCallbackFunction(CB_ONINSTSUCCESS); #endif//NSIS_SUPPORT_CODECALLBACKS if (g_quit_flag || (unsigned int)m_page >= (unsigned int)g_blocks[NB_PAGES].num) { DestroyWindow(m_curwnd); g_hwnd = 0; EndDialog(hwndDlg,m_retcode); } else { HWND hwndtmp; int pflags = this_page->flags; GetNSISString(state_click_next, this_page->clicknext); SetDlgItemTextFromLang(hwndDlg, IDOK, this_page->next); SetDlgItemTextFromLang(hwndDlg, IDC_BACK, this_page->back); SetDlgItemTextFromLang(hwndDlg, IDCANCEL, this_page->cancel); hwndtmp = GetDlgItem(hwndDlg, IDC_BACK); if (g_exec_flags.abort) { pflags &= ~(PF_BACK_ENABLE | PF_NEXT_ENABLE); pflags |= PF_CANCEL_ENABLE; } ShowWindow(hwndtmp, pflags & PF_BACK_SHOW);// SW_HIDE = 0, PF_BACK_SHOW = SW_SHOWNA = 8 EnableWindow(hwndtmp, pflags & PF_BACK_ENABLE); EnableNext(pflags & PF_NEXT_ENABLE); EnableWindow(m_hwndCancel, pflags & PF_CANCEL_ENABLE); if (pflags & PF_CANCEL_ENABLE) EnableMenuItem(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND | MF_ENABLED); else EnableMenuItem(GetSystemMenu(hwndDlg, FALSE), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED); SendMessage(hwndtmp, BM_SETSTYLE, BS_PUSHBUTTON, TRUE); if (g_exec_flags.abort) { SendMessage(hwndDlg, DM_SETDEFID, IDCANCEL, 0); SetActiveCtl(m_hwndCancel); } else { SetActiveCtl(m_hwndOK); } mystrcpy(g_tmp,g_caption); GetNSISString(g_tmp+mystrlen(g_tmp),this_page->caption); my_SetWindowText(hwndDlg,g_tmp); #ifdef NSIS_SUPPORT_CODECALLBACKS // custom page or user used abort in prefunc if (ExecuteCodeSegment(this_page->prefunc, NULL) || !this_page->dlg_id) { goto nextPage; } #endif //NSIS_SUPPORT_CODECALLBACKS if (this_page->wndproc_id != PWP_COMPLETED) { DestroyWindow(m_curwnd); } else { if (!g_exec_flags.abort && g_exec_flags.autoclose) goto nextPage; // no need to go to skipPage because PWP_COMPLETED always follows PWP_INSTFILES return FALSE; } // update g_this_page for the dialog proc g_this_page=this_page; if (this_page->dlg_id > 0) // NSIS page { m_curwnd=CreateDialogParam( g_hInstance, MAKEINTRESOURCE(this_page->dlg_id+dlg_offset), hwndDlg,winprocs[this_page->wndproc_id],(LPARAM)this_page ); if (m_curwnd) { RECT r; SetDlgItemTextFromLang(m_curwnd,IDC_INTROTEXT,this_page->parms[0]); 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(this_page->showfunc,NULL); if (g_quit_flag) return FALSE; #endif //NSIS_SUPPORT_CODECALLBACKS ShowWindow(m_curwnd,SW_SHOWNA); NotifyCurWnd(WM_NOTIFY_START); } } } skipPage: if (!ui_dlg_visible && m_curwnd) { ShowWindow(hwndDlg, SW_SHOWDEFAULT); ui_dlg_visible = 1; } return FALSE; } #ifdef NSIS_SUPPORT_BGBG if (uMsg == WM_WINDOWPOSCHANGED) { SetWindowPos(m_bgwnd, hwndDlg, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } if (uMsg == WM_SIZE) { ShowWindow(m_bgwnd, wParam == SIZE_MINIMIZED ? SW_HIDE : SW_SHOW); } #endif //NSIS_SUPPORT_BGBG if (uMsg == WM_NOTIFY_CUSTOM_READY) { DestroyWindow(m_curwnd); m_curwnd = (HWND)wParam; goto skipPage; } if (uMsg == WM_QUERYENDSESSION) { SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, FALSE); return TRUE; } if (uMsg == WM_COMMAND) { int id = LOWORD(wParam); HWND hCtl = GetDlgItem(hwndDlg, id); // lParam might be NULL if (hCtl) { SendMessage(hCtl, BM_SETSTATE, FALSE, 0); if (!IsWindowEnabled(hCtl)) return 0; } if (id == IDOK) { outernotify(1); } else if (id == IDC_BACK && m_page>0) { outernotify(-1); } else if (id == IDCANCEL) { if (g_exec_flags.abort) { #ifdef NSIS_SUPPORT_CODECALLBACKS ExecuteCallbackFunction(CB_ONINSTFAILED); #endif//NSIS_SUPPORT_CODECALLBACKS m_retcode=2; outernotify(NOTIFY_BYE_BYE); } else { #ifdef NSIS_SUPPORT_CODECALLBACKS if (!ExecuteCallbackFunction(CB_ONUSERABORT)) #endif//NSIS_SUPPORT_CODECALLBACKS { m_retcode=1; outernotify(NOTIFY_BYE_BYE); } } } else { // Forward WM_COMMANDs to inner dialogs, can be custom ones. // Without this, enter on buttons in inner dialogs won't work. SendMessage(m_curwnd, WM_COMMAND, wParam, lParam); } } return HandleStaticBkColor(); }
static INT_PTR CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { page *m_this_page=g_this_page; HWND hwLicense; #define LicIgnoreWMCommand g_cbLicRead // g_cbLicRead is only used in WM_INITDIALOG during EM_STREAMIN if (uMsg == WM_INITDIALOG) { TCHAR *l = (TCHAR *)GetNSISStringNP(GetNSISTab(this_page->parms[1])); int lt = *l; EDITSTREAM es = { (DWORD_PTR)(++l), 0, #ifdef _UNICODE lt==SF_RTF?StreamLicenseRTF:StreamLicense #else StreamLicense #endif }; int selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION); SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]); SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]); CheckDlgButton(hwndDlg,IDC_LICENSEAGREE+!selected,BST_CHECKED); EnableNext(selected); hwLicense=GetUIItem(IDC_EDIT1); SetActiveCtl(hwLicense); SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0); #define lbg g_header->license_bg SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg)); #undef lbg SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l)); g_cbLicRead = 0; SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es); LicIgnoreWMCommand = 0; return FALSE; } if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && !LicIgnoreWMCommand) { if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) { int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED; m_this_page->flags &= ~PF_LICENSE_SELECTED; m_this_page->flags |= is; EnableNext(is); SetNextDef(); } } if (uMsg == WM_NOTIFY) { hwLicense=GetUIItem(IDC_EDIT1); #define nmhdr ((NMHDR *)lParam) #define enlink ((ENLINK *)lParam) #define msgfilter ((MSGFILTER *)lParam) if (nmhdr->code==EN_LINK) { if (enlink->msg==WM_LBUTTONDOWN) { TEXTRANGE tr = { { enlink->chrg.cpMin, enlink->chrg.cpMax, }, ps_tmpbuf }; if (tr.chrg.cpMax-tr.chrg.cpMin < COUNTOF(ps_tmpbuf)) { SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr); SetCursor(LoadCursor(0, IDC_WAIT)); ShellExecute(hwndDlg,_T("open"),tr.lpstrText,NULL,NULL,SW_SHOWNORMAL); SetCursor(LoadCursor(0, IDC_ARROW)); } } } //Ximon Eighteen 8th September 2002 Capture return key presses in the rich //edit control now that the control gets the focus rather than the default //push button. When the user presses return ask the outer dialog to move //the installer onto the next page. MSDN docs say return non-zero if the //rich edit control should NOT process this message, hence the return 1. // //This is required because the RichEdit control is eating all the key hits. //It does try to release some and convert VK_ESCAPE to WM_CLOSE, VK_ENTER //to a push on the default button and VM_TAB to WM_NEXTDLGCTL. But sadly it //it sends all of these messages to its parent instead of just letting the //dialog manager handle them. Instead of properly handling WM_GETDLGCODE, //it mimics the dialog manager. if (nmhdr->code==EN_MSGFILTER) { if (msgfilter->msg==WM_KEYDOWN) { if (msgfilter->wParam==VK_RETURN) { SendMessage(g_hwnd, WM_COMMAND, IDOK, 0); } if (msgfilter->wParam==VK_ESCAPE) { SendMessage(g_hwnd, WM_CLOSE, 0, 0); } return 1; } } #undef nmhdr #undef enlink #undef msgfilter } if (uMsg == WM_NOTIFY_INIGO_MONTOYA) { LicIgnoreWMCommand++; } return HandleStaticBkColor(); }
static INT_PTR CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { page *m_this_page=g_this_page; HWND hwLicense; static int ignoreWMCommand; if (uMsg == WM_INITDIALOG) { TCHAR *l = (TCHAR *)GetNSISStringNP(GetNSISTab(this_page->parms[1])); int lt = *l; EDITSTREAM es = { (DWORD_PTR)(++l), 0, StreamLicense }; int selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION); SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]); SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]); CheckDlgButton(hwndDlg,IDC_LICENSEAGREE+!selected,BST_CHECKED); EnableNext(selected); hwLicense=GetUIItem(IDC_EDIT1); SetActiveCtl(hwLicense); SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0); #define lbg g_header->license_bg SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg)); #undef lbg SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS dwRead=0; SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l)); SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es); ignoreWMCommand = 0; return FALSE; } if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && !ignoreWMCommand) { if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) { int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED; m_this_page->flags &= ~PF_LICENSE_SELECTED; m_this_page->flags |= is; EnableNext(is); SetNextDef(); } } if (uMsg == WM_NOTIFY) { hwLicense=GetUIItem(IDC_EDIT1); #define nmhdr ((NMHDR *)lParam) #define enlink ((ENLINK *)lParam) #define msgfilter ((MSGFILTER *)lParam) if (nmhdr->code==EN_LINK) { if (enlink->msg==WM_LBUTTONDOWN) { TEXTRANGE tr = { { enlink->chrg.cpMin, enlink->chrg.cpMax, }, ps_tmpbuf }; if (tr.chrg.cpMax-tr.chrg.cpMin < (sizeof(ps_tmpbuf)/sizeof(*ps_tmpbuf))) { SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr); SetCursor(LoadCursor(0, IDC_WAIT)); ShellExecute(hwndDlg,TEXT("open"),tr.lpstrText,NULL,NULL,SW_SHOWNORMAL); SetCursor(LoadCursor(0, IDC_ARROW)); } } } //Ximon Eighteen 8th September 2002 Capture return key presses in the rich //edit control now that the control gets the focus rather than the default //push button. When the user presses return ask the outer dialog to move //the installer onto the next page. MSDN docs say return non-zero if the //rich edit control should NOT process this message, hence the return 1. if (nmhdr->code==EN_MSGFILTER) { if (msgfilter->msg==WM_KEYDOWN) { if (msgfilter->wParam==VK_RETURN) { SendMessage(g_hwnd, WM_COMMAND, IDOK, 0); } if (msgfilter->wParam==VK_ESCAPE) { SendMessage(g_hwnd, WM_CLOSE, 0, 0); } return 1; } } #undef nmhdr #undef enlink #undef msgfilter } if (uMsg == WM_NOTIFY_INIGO_MONTOYA) { ignoreWMCommand++; } return HandleStaticBkColor(); }
static BOOL CALLBACK DirProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { page *thispage = g_this_page; char *dir = g_usrvars[thispage->parms[4]]; int browse_text = thispage->parms[3]; if (uMsg == WM_NOTIFY_INIGO_MONTOYA) { GetUIText(IDC_DIR,dir,NSIS_MAX_STRLEN); validate_filename(dir); #ifdef NSIS_CONFIG_LOG #ifndef NSIS_CONFIG_LOG_ODS build_g_logfile(); #endif log_dolog = IsDlgButtonChecked(hwndDlg,IDC_CHECK1); #endif } if (uMsg == WM_INITDIALOG) { #ifdef NSIS_CONFIG_LOG if (GetAsyncKeyState(VK_SHIFT)&0x8000) { HWND h=GetUIItem(IDC_CHECK1); SetUITextFromLang(IDC_CHECK1,LANG_LOG_INSTALL_PROCESS); ShowWindow(h,SW_SHOWNA); } #endif if (validpathspec(dir) && !skip_root(dir)) addtrailingslash(dir); SetUITextNT(IDC_DIR,dir); SetUITextFromLang(IDC_BROWSE,this_page->parms[2]); SetUITextFromLang(IDC_SELDIRTEXT,this_page->parms[1]); } if (uMsg == WM_COMMAND) { int id=LOWORD(wParam); if (id == IDC_DIR && HIWORD(wParam) == EN_CHANGE) { uMsg = WM_IN_UPDATEMSG; } if (id == IDC_BROWSE) { char name[MAX_PATH]; BROWSEINFO bi = {0,}; ITEMIDLIST *idlist; bi.hwndOwner = hwndDlg; bi.pszDisplayName = name; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM)dir; bi.lpszTitle = GetNSISStringTT(browse_text); #ifndef BIF_NEWDIALOGSTYLE #define BIF_NEWDIALOGSTYLE 0x0040 #endif bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; idlist = SHBrowseForFolder(&bi); if (idlist) { // Get and free idlist my_PIDL2Path(name, idlist); if (g_header->install_directory_auto_append) { const char *post_str=ps_tmpbuf; GetNSISStringTT(g_header->install_directory_auto_append); // name gives just the folder name if (lstrcmpi(post_str,name)) { lstrcat(addtrailingslash(dir),post_str); } } SetUITextNT(IDC_DIR,dir); } } } if (uMsg == WM_IN_UPDATEMSG || uMsg == WM_NOTIFY_START) { static char s[NSIS_MAX_STRLEN]; char *p; int error = 0; int total, available=-1; DWORD spc,bps,fc,tc; GetUIText(IDC_DIR,dir,NSIS_MAX_STRLEN); if (!is_valid_instpath(dir)) error = NSIS_INSTDIR_INVALID; mystrcpy(s,dir); p=skip_root(s); if (p) *p=0; if (GetDiskFreeSpace(s,&spc,&bps,&fc,&tc)) { DWORD r=MulDiv(bps*spc,fc,1<<10); if (r > 0x7fffffff) r=0x7fffffff; available=(int)r; } total = getreqsize(); if ((unsigned int)available < (unsigned int)total) error = NSIS_INSTDIR_NOT_ENOUGH_SPACE; if (LANG_STR_TAB(LANG_SPACE_REQ)) { SetUITextNT(IDC_SPACEREQUIRED,inttosizestr(total,GetNSISString(s,LANG_SPACE_REQ))); if (available != -1) SetUITextNT(IDC_SPACEAVAILABLE,inttosizestr(available,GetNSISString(s,LANG_SPACE_AVAIL))); else SetUITextNT(IDC_SPACEAVAILABLE,""); } g_exec_flags.instdir_error = error; #ifdef NSIS_SUPPORT_CODECALLBACKS if (!error) error = ExecuteCodeSegment(g_header->code_onVerifyInstDir,NULL); #endif if (thispage->flags & PF_DIR_NO_BTN_DISABLE) error = 0; EnableWindow(m_hwndOK, !error); } return HandleStaticBkColor(); }
static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { page *m_this_page=g_this_page; HWND hwLicense; if (uMsg == WM_INITDIALOG) { char *l = (char *)GetNSISStringNP(GetNSISTab(this_page->parms[1])); int lt = *l; EDITSTREAM es = { (DWORD)(++l), 0, StreamLicense }; int selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION); SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]); SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]); SendMessage(GetUIItem(IDC_LICENSEAGREE+!selected),BM_SETCHECK,BST_CHECKED,0); EnableWindow(m_hwndOK,selected); hwLicense=GetUIItem(IDC_EDIT1); SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0); #define lbg g_header->license_bg SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg)); #undef lbg SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS dwRead=0; SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l)); SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es); //XGE 5th September 2002 - place the initial focus in the richedit control SetFocus(hwLicense); return FALSE; //End Xge } if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED) { if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) { int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED; m_this_page->flags &= ~PF_LICENSE_SELECTED; m_this_page->flags |= is; EnableWindow( m_hwndOK, is ); } } if (uMsg == WM_NOTIFY) { hwLicense=GetUIItem(IDC_EDIT1); #define nmhdr ((NMHDR *)lParam) #define enlink ((ENLINK *)lParam) #define msgfilter ((MSGFILTER *)lParam) if (nmhdr->code==EN_LINK) { if (enlink->msg==WM_LBUTTONDOWN) { TEXTRANGE tr = { enlink->chrg.cpMin, enlink->chrg.cpMax, ps_tmpbuf }; if (tr.chrg.cpMax-tr.chrg.cpMin < sizeof(ps_tmpbuf)) { SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr); SetCursor(LoadCursor(0,IDC_WAIT)); ShellExecute(hwndDlg,"open",tr.lpstrText,NULL,NULL,SW_SHOWNORMAL); SetCursor(LoadCursor(0,IDC_ARROW)); } } if (enlink->msg==WM_SETCURSOR) { #ifndef IDC_HAND #define IDC_HAND MAKEINTRESOURCE(32649) #endif SetCursor(LoadCursor(0,IDC_HAND)); } } //Ximon Eighteen 8th September 2002 Capture return key presses in the rich //edit control now that the control gets the focus rather than the default //push button. When the user presses return ask the outer dialog to move //the installer onto the next page. MSDN docs say return non-zero if the //rich edit control should NOT process this message, hence the return 1. if (nmhdr->code==EN_MSGFILTER) { if (msgfilter->msg==WM_KEYDOWN) { if (msgfilter->wParam==VK_RETURN && IsWindowEnabled(m_hwndOK)) { outernotify(1); } if (msgfilter->wParam==VK_ESCAPE) { SendMessage(g_hwnd, WM_CLOSE, 0, 0); } return 1; } } #undef nmhdr #undef enlink #undef msgfilter } return HandleStaticBkColor(); }
BOOL CALLBACK DialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { BOOL bNextPage=FALSE; if (uMsg == WM_INITDIALOG || uMsg == WM_NOTIFY_OUTER_NEXT) { page *this_page; static DLGPROC winprocs[]= { #ifdef NSIS_CONFIG_LICENSEPAGE LicenseProc, #endif #ifdef NSIS_CONFIG_COMPONENTPAGE SelProc, #endif DirProc, InstProc, #ifdef NSIS_CONFIG_UNINSTALL_SUPPORT UninstProc #endif }; if (uMsg == WM_INITDIALOG) { g_hwnd=hwndDlg; m_hwndOK=GetDlgItem(hwndDlg,IDOK); m_hwndCancel=GetDlgItem(hwndDlg,IDCANCEL); SetDlgItemTextFromLang(hwndDlg,IDC_VERSTR,LANG_BRANDING); SetClassLong(hwndDlg,GCL_HICON,(long)g_hIcon); #if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT) g_quit_flag = ExecuteCodeSegment(g_header->code_onGUIInit,NULL); #endif //ShowWindow(hwndDlg, SW_SHOW); } this_page=g_pages+m_page; if (m_page>=0) { #ifdef NSIS_SUPPORT_CODECALLBACKS // Call leave function. If Abort used don't move to the next page. // But if quit called we must exit now if (m_delta==1) if (ExecuteCodeSegment(this_page->leavefunc,NULL)) return !g_quit_flag; #endif // 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->dlg_id) return 0; } SendMessage(m_curwnd, WM_NOTIFY_INIGO_MONTOYA, 0, 0); nextPage: bNextPage=FALSE; m_page+=m_delta; this_page+=m_delta; #ifdef NSIS_SUPPORT_CODECALLBACKS if (m_page==g_blocks[NB_PAGES].num) ExecuteCodeSegment(g_header->code_onInstSuccess,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS if (g_quit_flag || (unsigned int)m_page >= (unsigned int)g_blocks[NB_PAGES].num) { DestroyWindow(m_curwnd); g_hwnd = 0; EndDialog(hwndDlg,m_retcode); } else { HWND hwndtmp; int pflags = this_page->flags; GetNSISString(state_click_next, this_page->clicknext); SetDlgItemTextFromLang(hwndDlg, IDOK, this_page->next); SetDlgItemTextFromLang(hwndDlg, IDC_BACK, this_page->back); SetDlgItemTextFromLang(hwndDlg, IDCANCEL, this_page->cancel); hwndtmp = GetDlgItem(hwndDlg, IDC_BACK); if (g_exec_flags.abort) { pflags &= ~(PF_BACK_ENABLE | PF_NEXT_ENABLE); pflags |= PF_CANCEL_ENABLE; SendMessage(hwndDlg, DM_SETDEFID, IDCANCEL, 0); } else SendMessage(hwndDlg, DM_SETDEFID, IDOK, 0); SetWindowLong(hwndtmp, GWL_STYLE, GetWindowLong(hwndtmp, GWL_STYLE) & ~BS_DEFPUSHBUTTON); ShowWindow(hwndtmp, pflags & PF_BACK_SHOW);// SW_HIDE = 0, PF_BACK_SHOW = SW_SHOWNA = 8 EnableWindow(hwndtmp, pflags & PF_BACK_ENABLE); EnableWindow(m_hwndOK, pflags & PF_NEXT_ENABLE); EnableWindow(m_hwndCancel, pflags & PF_CANCEL_ENABLE); mystrcpy(g_tmp,g_caption); GetNSISString(g_tmp+mystrlen(g_tmp),this_page->caption); my_SetWindowText(hwndDlg,g_tmp); #ifdef NSIS_SUPPORT_CODECALLBACKS if (ExecuteCodeSegment(this_page->prefunc, NULL) || !this_page->dlg_id) { bNextPage=TRUE; goto nextPage; } #endif //NSIS_SUPPORT_CODECALLBACKS if (this_page->wndproc_id != PWP_COMPLETED) DestroyWindow(m_curwnd); else { if (g_exec_flags.abort) SetFocus(m_hwndCancel); else if (g_exec_flags.autoclose) goto nextPage; else SetFocus(m_hwndOK); // without focus button, the system Beeps every time user press one key goto skipPage; } // update g_this_page for the dialog proc g_this_page=this_page; if (this_page->dlg_id > 0) // NSIS page { m_curwnd=CreateDialogParam( g_hInstance, MAKEINTRESOURCE(this_page->dlg_id+dlg_offset), hwndDlg,winprocs[this_page->wndproc_id],(LPARAM)this_page ); if (m_curwnd) { RECT r; SetDlgItemTextFromLang(m_curwnd,IDC_INTROTEXT,this_page->parms[0]); 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(this_page->showfunc,NULL); #endif //NSIS_SUPPORT_CODECALLBACKS ShowWindow(m_curwnd,SW_SHOWNA); SendMessage(m_curwnd,WM_NOTIFY_START,0,0); } //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 ((pflags & PF_NO_NEXT_FOCUS) == 0) SetFocus(m_hwndOK); //XGE End } } skipPage: if (!ui_dlg_visible && m_curwnd) { ShowWindow(hwndDlg, SW_SHOW); ui_dlg_visible = 1; } if (bNextPage) goto nextPage; return FALSE; } #ifdef NSIS_SUPPORT_BGBG if (uMsg == WM_WINDOWPOSCHANGED) { SetWindowPos(m_bgwnd, hwndDlg, 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE); } if (uMsg == WM_SIZE) { ShowWindow(m_bgwnd, wParam == SIZE_MINIMIZED ? SW_HIDE : SW_SHOW); } #endif //NSIS_SUPPORT_BGBG if (uMsg == WM_NOTIFY_CUSTOM_READY) { DestroyWindow(m_curwnd); m_curwnd = (HWND)wParam; goto skipPage; } if (uMsg == WM_CLOSE && m_page == g_blocks[NB_PAGES].num - 1) { if (!IsWindowEnabled(m_hwndCancel) && IsWindowEnabled(m_hwndOK)) { uMsg = WM_COMMAND; wParam = IDOK; } } if (uMsg == WM_COMMAND) { int id=LOWORD(wParam); if (id == IDOK) { outernotify(1); } if (id == IDC_BACK && m_page>0) { outernotify(-1); } if (id == IDCANCEL) { if (g_exec_flags.abort) { #ifdef NSIS_SUPPORT_CODECALLBACKS ExecuteCodeSegment(g_header->code_onInstFailed,NULL); #endif//NSIS_SUPPORT_CODECALLBACKS m_retcode=2; outernotify(NOTIFY_BYE_BYE); } else { #ifdef NSIS_SUPPORT_CODECALLBACKS if (!ExecuteCodeSegment(g_header->code_onUserAbort,NULL)) #endif//NSIS_SUPPORT_CODECALLBACKS { m_retcode=1; outernotify(NOTIFY_BYE_BYE); } } } else { // Forward WM_COMMANDs to inner dialogs, can be custom ones. // Without this, enter on buttons in inner dialogs won't work. SendMessage(m_curwnd, uMsg, wParam, lParam); } } return HandleStaticBkColor(); }
static BOOL CALLBACK LicenseProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { page *m_this_page=g_this_page; HWND hwLicense; static int ignoreWMCommand; EDITSTREAM es; es.dwError = 0; if (uMsg == WM_INITDIALOG) { TCHAR *l = (TCHAR *)GetNSISStringNP(GetNSISTab(this_page->parms[1])); // First char contains SF_RTF or SF_TEXT (SF_UNICODE) int lt = *l; int selected; bCookieNuked = FALSE; // SF_UNICODE is never set for ANSI NSIS if (lt & SF_UNICODE) { es.dwCookie = (DWORD_PTR)(++l); es.pfnCallback = StreamLicenseW; } else { es.pfnCallback = StreamLicenseA; #ifdef _UNICODE { // If Unicode support, then even though this is straight ASCII coming // in, it was encoded as WCHAR and therefore must be turned back to // ASCII. char* tmp = WideCharToAnsi(++l); // How do we nuke tmp so we don't get a memory leak? // Well, we need to teach StreamLicenseA to do that for us. bManageCookie = TRUE; es.dwCookie = (DWORD_PTR) tmp; } #else bManageCookie = FALSE; es.dwCookie = (DWORD_PTR)(++l); #endif } selected = (this_page->flags & PF_LICENSE_SELECTED) | !(this_page->flags & PF_LICENSE_FORCE_SELECTION); SetUITextFromLang(IDC_LICENSEAGREE,this_page->parms[2]); SetUITextFromLang(IDC_LICENSEDISAGREE,this_page->parms[3]); CheckDlgButton(hwndDlg,IDC_LICENSEAGREE+!selected,BST_CHECKED); EnableNext(selected); hwLicense=GetUIItem(IDC_EDIT1); SetActiveCtl(hwLicense); SendMessage(hwLicense,EM_AUTOURLDETECT,TRUE,0); #define lbg g_header->license_bg SendMessage(hwLicense,EM_SETBKGNDCOLOR,0,lbg>=0?lbg:GetSysColor(-lbg)); #undef lbg SendMessage(hwLicense,EM_SETEVENTMASK,0,ENM_LINK|ENM_KEYEVENTS); //XGE 8th September 2002 Or'd in ENM_KEYEVENTS dwRead=0; SendMessage(hwLicense,EM_EXLIMITTEXT,0,mystrlen(l)); SendMessage(hwLicense,EM_STREAMIN,lt,(LPARAM)&es); ignoreWMCommand = 0; return FALSE; } if (uMsg == WM_COMMAND && HIWORD(wParam) == BN_CLICKED && !ignoreWMCommand) { if (m_this_page->flags & PF_LICENSE_FORCE_SELECTION) { int is = SendMessage(GetUIItem(IDC_LICENSEAGREE), BM_GETCHECK, 0, 0) & BST_CHECKED; m_this_page->flags &= ~PF_LICENSE_SELECTED; m_this_page->flags |= is; EnableNext(is); SetNextDef(); } } if (uMsg == WM_NOTIFY) { hwLicense=GetUIItem(IDC_EDIT1); #define nmhdr ((NMHDR *)lParam) #define enlink ((ENLINK *)lParam) #define msgfilter ((MSGFILTER *)lParam) if (nmhdr->code==EN_LINK) { if (enlink->msg==WM_LBUTTONDOWN) { TEXTRANGE tr = { { enlink->chrg.cpMin, enlink->chrg.cpMax, }, ps_tmpbuf }; if (tr.chrg.cpMax-tr.chrg.cpMin < sizeof(ps_tmpbuf)) { SendMessage(hwLicense,EM_GETTEXTRANGE,0,(LPARAM)&tr); SetCursor(LoadCursor(0, IDC_WAIT)); ShellExecute(hwndDlg,_T("open"),tr.lpstrText,NULL,NULL,SW_SHOWNORMAL); SetCursor(LoadCursor(0, IDC_ARROW)); } } } //Ximon Eighteen 8th September 2002 Capture return key presses in the rich //edit control now that the control gets the focus rather than the default //push button. When the user presses return ask the outer dialog to move //the installer onto the next page. MSDN docs say return non-zero if the //rich edit control should NOT process this message, hence the return 1. // //This is required because the RichEdit control is eating all the key hits. //It does try to release some and convert VK_ESCAPE to WM_CLOSE, VK_ENTER //to a push on the default button and VM_TAB to WM_NEXTDLGCTL. But sadly it //it sends all of these messages to its parent instead of just letting the //dialog manager handle them. Instead of properly handling WM_GETDLGCODE, //it mimics the dialog manager. if (nmhdr->code==EN_MSGFILTER) { if (msgfilter->msg==WM_KEYDOWN) { if (msgfilter->wParam==VK_RETURN) { SendMessage(g_hwnd, WM_COMMAND, IDOK, 0); } if (msgfilter->wParam==VK_ESCAPE) { SendMessage(g_hwnd, WM_CLOSE, 0, 0); } return 1; } } #undef nmhdr #undef enlink #undef msgfilter } if (uMsg == WM_NOTIFY_INIGO_MONTOYA) { ignoreWMCommand++; } return HandleStaticBkColor(); }