2002-08-02 10:01:35 +00:00
/*
2006-10-28 19:45:02 +00:00
* Ui . c
*
* This file is a part of NSIS .
*
2021-01-01 20:27:52 +00:00
* Copyright ( C ) 1999 - 2021 Nullsoft , Jeff Doozan and Contributors
2006-10-28 19:45:02 +00:00
*
* Licensed under the zlib / libpng license ( the " License " ) ;
* you may not use this file except in compliance with the License .
*
* Licence details can be found in the file COPYING .
*
* This software is provided ' as - is ' , without any express or implied
* warranty .
2010-03-24 17:22:56 +00:00
*
* Unicode support by Jim Park - - 08 / 10 / 2007
2006-10-28 19:45:02 +00:00
*/
2002-08-02 10:01:35 +00:00
2013-09-06 23:48:59 +00:00
# include "../Platform.h"
2002-08-02 10:01:35 +00:00
# include <windowsx.h>
# include <shlobj.h>
# include <shellapi.h>
2005-09-02 11:35:45 +00:00
# include <shlwapi.h>
2002-08-02 10:01:35 +00:00
# include "resource.h"
# include "fileform.h"
# include "state.h"
# include "util.h"
# include "ui.h"
# include "exec.h"
2008-11-29 22:03:33 +00:00
# include "plugin.h"
2002-08-03 23:06:10 +00:00
# include "lang.h"
2005-01-11 16:38:48 +00:00
# include "components.h"
2008-12-09 22:53:39 +00:00
# include "api.h"
2002-08-02 10:01:35 +00:00
2003-09-10 16:39:06 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
2002-09-25 03:06:36 +00:00
HICON g_hIcon ;
2003-09-10 16:39:06 +00:00
# endif
2002-09-06 18:49:02 +00:00
2003-04-21 13:32:34 +00:00
int dlg_offset ;
2003-11-09 22:45:25 +00:00
int ui_dlg_visible = 0 ; // At start main window is not visible
2002-08-02 10:01:35 +00:00
int g_quit_flag ; // set when Quit has been called (meaning bail out ASAP)
2003-05-24 13:50:24 +00:00
# if NSIS_MAX_INST_TYPES > 32 || NSIS_MAX_INST_TYPES < 1
2002-08-02 10:01:35 +00:00
# error invalid value for NSIS_MAX_INST_TYPES
# endif
int progress_bar_pos , progress_bar_len ;
2006-01-24 17:31:24 +00:00
# if NSIS_MAX_STRLEN < 1024
2010-03-24 17:22:56 +00:00
static TCHAR g_tmp [ 4096 ] ;
2006-01-24 17:31:24 +00:00
# else
2010-03-24 17:22:56 +00:00
static TCHAR g_tmp [ NSIS_MAX_STRLEN * 4 ] ;
2006-01-24 17:31:24 +00:00
# endif
2002-08-02 10:01:35 +00:00
2004-05-15 11:22:48 +00:00
static int m_page = - 1 , m_retcode , m_delta ;
2003-09-04 18:25:57 +00:00
static page * g_this_page ;
2002-11-09 12:50:00 +00:00
2004-05-08 16:07:22 +00:00
static void NSISCALL outernotify ( int delta ) {
if ( delta = = NOTIFY_BYE_BYE )
2003-04-01 18:07:32 +00:00
g_quit_flag + + ;
2004-05-08 16:07:22 +00:00
SendMessage ( g_hwnd , WM_NOTIFY_OUTER_NEXT , ( WPARAM ) delta , 0 ) ;
2002-09-12 11:47:05 +00:00
}
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
2013-09-06 23:48:59 +00:00
INT_PTR CALLBACK DialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
2003-06-05 20:33:33 +00:00
static int CALLBACK WINAPI BrowseCallbackProc ( HWND hwnd , UINT uMsg , LPARAM lParam , LPARAM lpData ) ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_LICENSEPAGE
2013-09-06 23:48:59 +00:00
static INT_PTR CALLBACK LicenseProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
2002-08-02 10:01:35 +00:00
# endif
2013-09-06 23:48:59 +00:00
static INT_PTR CALLBACK DirProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
static INT_PTR CALLBACK SelProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
static INT_PTR CALLBACK InstProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
static INT_PTR CALLBACK UninstProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam ) ;
2002-08-02 10:01:35 +00:00
# endif //NSIS_CONFIG_VISIBLE_SUPPORT
static DWORD WINAPI install_thread ( LPVOID p ) ;
2004-01-29 23:18:32 +00:00
void NSISCALL CleanUp ( ) ;
2003-09-04 18:25:57 +00:00
HWND insthwnd , insthwnd2 , insthwndbutton ;
2002-08-02 10:01:35 +00:00
2004-01-04 17:05:03 +00:00
HWND m_curwnd ;
static HWND m_bgwnd , m_hwndOK , m_hwndCancel ;
2002-08-02 10:01:35 +00:00
2002-10-01 14:13:23 +00:00
static BOOL NSISCALL SetDlgItemTextFromLang_ ( HWND dlg , int id , int lid ) {
2003-09-04 18:25:57 +00:00
return my_SetDialogItemText ( dlg , id + 1000 , GetNSISStringTT ( lid ) ) ;
2002-08-07 15:14:40 +00:00
}
2004-01-04 17:05:03 +00:00
static void NSISCALL SetNextDef ( )
{
SendMessage ( g_exec_flags . abort ? m_hwndCancel : m_hwndOK , BM_SETSTYLE , BS_DEFPUSHBUTTON , TRUE ) ;
}
static void NSISCALL EnableNext ( BOOL e )
{
EnableWindow ( m_hwndOK , e ) ;
}
2004-03-06 12:31:26 +00:00
static void NSISCALL SetActiveCtl ( HWND hCtl )
2004-01-04 17:05:03 +00:00
{
2004-03-06 12:31:26 +00:00
SendMessage ( g_hwnd , WM_NEXTDLGCTL , ( WPARAM ) hCtl , TRUE ) ;
2004-01-04 17:05:03 +00:00
}
2017-06-05 01:01:28 +00:00
static BOOL NSISCALL LaunchURL ( HWND hOwner , LPCTSTR URL , int ShowMode )
{
SHELLEXECUTEINFO sei ;
sei . fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_DDEWAIT ;
sei . hwnd = hOwner , sei . nShow = SW_SHOWNORMAL ;
sei . lpVerb = _T ( " open " ) , sei . lpFile = URL , sei . lpParameters = NULL , sei . lpDirectory = NULL ;
return myShellExecuteEx ( & sei ) ;
}
2004-01-04 17:05:03 +00:00
static void NSISCALL NotifyCurWnd ( UINT uNotifyCode )
{
if ( m_curwnd )
SendMessage ( m_curwnd , uNotifyCode , 0 , 0 ) ;
}
2002-09-23 20:56:29 +00:00
# define SetDlgItemTextFromLang(dlg,id,lid) SetDlgItemTextFromLang_(dlg,(id)-1000,lid)
# define SetUITextFromLang(it,la) SetDlgItemTextFromLang_(hwndDlg,(it)-1000,la)
2002-09-23 19:27:42 +00:00
# define SetUITextNT(it,text) my_SetDialogItemText(hwndDlg,it,text)
2004-01-04 17:05:03 +00:00
# define GetUIText(it,s) my_GetDialogItemText(it,s)
2002-09-23 19:27:42 +00:00
# define GetUIItem(it) GetDlgItem(hwndDlg,it)
2002-08-21 19:15:00 +00:00
2002-09-18 19:08:53 +00:00
# ifdef NSIS_CONFIG_ENHANCEDUI_SUPPORT
2017-11-05 18:36:33 +00:00
// "Link Window"/"SysLink" stores a pointer in GWLP_USERDATA on 2000/XP/2003 and it crashes if we clobber it (forums.winamp.com/showthread.php?t=333379).
// Checking for ROLE_SYSTEM_LINK is probably more reliable but requires more code.
# define IsNSISCtlColor(p) ( ( ((p)->lbStyle) <= 1 ) /* BS_SOLID||BS_HOLLOW */ \
& & ( ( UINT ) ( ( p ) - > bkmode ) < = 2 ) /* TRANSPARENT||OPAQUE */ \
& & ( ( ( p ) - > flags > > CC_FLAGSSHIFTFORZERO ) = = 0 ) /* CC_* flags */ \
)
2003-01-24 19:40:20 +00:00
# define HandleStaticBkColor() _HandleStaticBkColor(uMsg, wParam, lParam)
2013-09-06 23:48:59 +00:00
static INT_PTR NSISCALL _HandleStaticBkColor ( UINT uMsg , WPARAM wParam , LPARAM lParam )
2003-12-29 15:12:41 +00:00
{
if ( ( uMsg - WM_CTLCOLOREDIT ) < = ( WM_CTLCOLORSTATIC - WM_CTLCOLOREDIT ) )
{
2011-11-19 15:41:45 +00:00
ctlcolors * c = ( ctlcolors * ) GetWindowLongPtr ( ( HWND ) lParam , GWLP_USERDATA ) ;
2003-12-29 14:27:33 +00:00
2017-11-05 18:36:33 +00:00
if ( c & & IsNSISCtlColor ( c ) ) {
2003-12-29 15:12:41 +00:00
COLORREF text ;
LOGBRUSH lh ;
2003-12-29 14:27:33 +00:00
2003-12-29 15:12:41 +00:00
text = c - > text ;
if ( c - > flags & CC_TEXT_SYS )
text = GetSysColor ( text ) ;
if ( c - > flags & CC_TEXT )
SetTextColor ( ( HDC ) wParam , text ) ;
2003-12-29 14:27:33 +00:00
2003-12-29 15:12:41 +00:00
SetBkMode ( ( HDC ) wParam , c - > bkmode ) ;
2003-12-29 14:27:33 +00:00
2003-12-29 15:12:41 +00:00
lh . lbColor = c - > bkc ;
if ( c - > flags & CC_BK_SYS )
lh . lbColor = GetSysColor ( lh . lbColor ) ;
if ( c - > flags & CC_BK )
SetBkColor ( ( HDC ) wParam , lh . lbColor ) ;
2003-09-04 18:25:57 +00:00
2003-12-29 15:12:41 +00:00
if ( c - > flags & CC_BKB )
{
lh . lbStyle = c - > lbStyle ;
if ( c - > bkb )
DeleteObject ( c - > bkb ) ;
2017-11-05 18:36:33 +00:00
c - > bkb = CreateBrushIndirect ( & lh ) ; // LOGBRUSH::lbHatch is ignored by BS_SOLID and BS_HOLLOW
2003-03-20 20:49:13 +00:00
}
2003-12-29 15:12:41 +00:00
2013-09-06 23:48:59 +00:00
return ( INT_PTR ) c - > bkb ;
2003-01-27 15:05:50 +00:00
}
2003-01-24 19:40:20 +00:00
}
2002-09-22 19:05:43 +00:00
return 0 ;
2002-08-21 19:15:00 +00:00
}
2002-11-30 13:15:49 +00:00
# else
2002-09-18 19:08:53 +00:00
# define HandleStaticBkColor() 0
2017-11-05 18:36:33 +00:00
# endif //~ NSIS_CONFIG_ENHANCEDUI_SUPPORT
2002-08-07 15:14:40 +00:00
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_LOG
2006-01-27 17:53:00 +00:00
# if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
2002-08-19 23:18:19 +00:00
void NSISCALL build_g_logfile ( )
2002-08-02 10:01:35 +00:00
{
2010-03-24 17:22:56 +00:00
mystrcat ( addtrailingslash ( mystrcpy ( g_log_file , state_install_directory ) ) , _T ( " install.log " ) ) ;
2002-08-02 10:01:35 +00:00
}
# endif
2003-11-24 14:22:50 +00:00
# endif
2002-08-02 10:01:35 +00:00
2003-09-04 18:25:57 +00:00
int * cur_langtable ;
2017-05-22 18:10:19 +00:00
static TCHAR * update_caption ( )
{
TCHAR * gcap = g_caption ;
GetNSISString ( gcap , LANG_CAPTION ) ;
# ifdef NSIS_SUPPORT_BGBG
my_SetWindowText ( m_bgwnd , gcap ) ;
# endif
return gcap ;
}
2002-08-28 21:13:54 +00:00
static void NSISCALL set_language ( )
2002-08-24 14:44:23 +00:00
{
2003-06-08 14:45:56 +00:00
LANGID lang_mask = ( LANGID ) ~ 0 ;
2005-12-30 15:47:47 +00:00
LANGID lang = myatoi ( state_language ) ;
2002-09-29 20:25:15 +00:00
char * language_table = 0 ;
2003-09-04 18:25:57 +00:00
int lang_num ;
2005-10-17 13:39:18 +00:00
int * selected_langtable = 0 ;
2002-08-28 16:57:46 +00:00
2010-03-24 17:22:56 +00:00
// Jim Park: We are doing byte offsets to get to various data structures so
// no TCHARs here.
2002-08-24 14:44:23 +00:00
lang_again :
2003-09-04 18:25:57 +00:00
lang_num = g_blocks [ NB_LANGTABLES ] . num ;
while ( lang_num - - ) {
language_table = ( ( char * ) g_blocks [ NB_LANGTABLES ] . offset ) + lang_num * g_header - > langtable_size ;
2002-09-29 20:25:15 +00:00
if ( ! ( ( lang ^ * ( LANGID * ) language_table ) & lang_mask ) ) {
2003-04-21 13:32:34 +00:00
dlg_offset = * ( int * ) ( language_table + sizeof ( LANGID ) ) ;
2003-12-06 20:45:35 +00:00
g_exec_flags . rtl = * ( int * ) ( language_table + sizeof ( LANGID ) + sizeof ( int ) ) ;
2005-10-17 13:39:18 +00:00
selected_langtable = ( int * ) ( language_table + sizeof ( LANGID ) + 2 * sizeof ( int ) ) ;
2002-08-24 14:44:23 +00:00
break ;
}
}
2005-10-17 13:39:18 +00:00
if ( ! selected_langtable ) {
2003-06-08 14:45:56 +00:00
if ( lang_mask = = ( LANGID ) ~ 0 )
2002-09-29 20:25:15 +00:00
lang_mask = 0x3ff ; // primary lang
else // we already tried once and we still don't have a language table
lang_mask = 0 ; // first lang
2002-08-24 14:44:23 +00:00
goto lang_again ;
}
2005-10-17 13:39:18 +00:00
cur_langtable = selected_langtable ;
2002-09-29 20:25:15 +00:00
myitoa ( state_language , * ( LANGID * ) language_table ) ;
2017-05-22 18:10:19 +00:00
update_caption ( ) ;
2005-01-14 15:24:51 +00:00
// reload section names
{
section * sec = g_sections ;
int x = num_sections ;
while ( x - - )
{
if ( sec - > name_ptr )
{
GetNSISString ( sec - > name , sec - > name_ptr ) ;
}
sec + + ;
}
}
2002-08-24 14:44:23 +00:00
}
2004-03-06 18:37:19 +00:00
FORCE_INLINE int NSISCALL ui_doinstall ( void )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
header * header = g_header ;
2003-03-29 17:16:09 +00:00
static WNDCLASS wc ; // richedit subclassing and bgbg creation
2003-09-04 18:25:57 +00:00
2005-12-30 15:47:47 +00:00
// detect default language
// more information at:
2016-10-11 19:58:58 +00:00
// https://web.archive.org/web/20060618155426/http://msdn.microsoft.com/library/en-us/intl/nls_0xrn.asp
2005-12-30 15:47:47 +00:00
LANGID ( WINAPI * GUDUIL ) ( ) ;
2014-05-19 22:03:09 +00:00
# ifdef _WIN64
2014-02-08 00:13:52 +00:00
GUDUIL = GetUserDefaultUILanguage ;
2014-05-19 22:03:09 +00:00
# else
GUDUIL = myGetProcAddress ( MGA_GetUserDefaultUILanguage ) ;
2005-12-30 15:47:47 +00:00
if ( GUDUIL )
2014-05-19 22:03:09 +00:00
# endif
2005-12-30 15:47:47 +00:00
{
// Windows ME/2000+
myitoa ( state_language , GUDUIL ( ) ) ;
}
2014-05-19 22:03:09 +00:00
# ifndef _WIN64
2005-12-30 15:47:47 +00:00
else
{
2010-03-24 17:22:56 +00:00
static const TCHAR reg_9x_locale [ ] = _T ( " Control Panel \\ Desktop \\ ResourceLocale " ) ;
static const TCHAR reg_nt_locale_key [ ] = _T ( " .DEFAULT \\ Control Panel \\ International " ) ;
const TCHAR * reg_nt_locale_val = & reg_9x_locale [ 30 ] ; // = _T("Locale") with opt
2007-03-03 14:19:30 +00:00
2010-03-29 14:24:47 +00:00
state_language [ 0 ] = _T ( ' 0 ' ) ;
state_language [ 1 ] = _T ( ' x ' ) ;
state_language [ 2 ] = 0 ;
2005-12-30 15:47:47 +00:00
{
// Windows 9x
2007-04-14 13:54:47 +00:00
myRegGetStr ( HKEY_CURRENT_USER , reg_9x_locale , NULL , g_tmp , 0 ) ;
2005-12-30 15:47:47 +00:00
}
2006-01-24 17:57:50 +00:00
if ( ! g_tmp [ 0 ] )
2005-12-30 15:47:47 +00:00
{
// Windows NT
// This key exists on 9x as well, so it's only read if ResourceLocale wasn't found
2007-04-14 13:54:47 +00:00
myRegGetStr ( HKEY_USERS , reg_nt_locale_key , reg_nt_locale_val , g_tmp , 0 ) ;
2005-12-30 15:47:47 +00:00
}
2006-01-24 17:54:35 +00:00
mystrcat ( state_language , g_tmp ) ;
2005-12-30 15:47:47 +00:00
}
2014-05-19 22:03:09 +00:00
# endif
2005-12-30 15:47:47 +00:00
// set default language
2003-09-23 19:01:19 +00:00
set_language ( ) ;
2005-12-30 15:47:47 +00:00
// initialize auto close flag
g_exec_flags . autoclose = g_flags & CH_FLAGS_AUTO_CLOSE ;
2008-11-29 22:03:33 +00:00
# ifdef NSIS_CONFIG_PLUGIN_SUPPORT
// initialize plugin api
g_exec_flags . plugin_api_version = NSISPIAPIVER_CURR ;
# endif
2005-12-30 15:47:47 +00:00
// read install directory from registry
2003-09-04 18:25:57 +00:00
if ( ! is_valid_instpath ( state_install_directory ) )
2002-11-01 20:34:55 +00:00
{
2003-09-04 18:25:57 +00:00
if ( header - > install_reg_key_ptr )
2002-08-02 10:01:35 +00:00
{
2003-11-14 21:08:51 +00:00
myRegGetStr (
2015-09-17 14:30:07 +00:00
( HKEY ) ( UINT_PTR ) header - > install_reg_rootkey ,
2003-09-04 18:25:57 +00:00
GetNSISStringNP ( header - > install_reg_key_ptr ) ,
2003-11-14 21:08:51 +00:00
GetNSISStringNP ( header - > install_reg_value_ptr ) ,
2007-04-14 13:54:47 +00:00
ps_tmpbuf ,
0
2003-11-14 21:08:51 +00:00
) ;
2003-09-04 18:25:57 +00:00
if ( ps_tmpbuf [ 0 ] )
2002-08-02 10:01:35 +00:00
{
2010-03-24 17:22:56 +00:00
TCHAR * p = ps_tmpbuf ;
TCHAR * e ;
if ( p [ 0 ] = = _T ( ' \" ' ) )
2002-08-02 10:01:35 +00:00
{
2010-03-24 17:22:56 +00:00
TCHAR * p2 ;
2004-02-20 15:13:13 +00:00
p + + ;
2010-03-24 17:22:56 +00:00
p2 = findchar ( p , _T ( ' " ' ) ) ;
2004-02-20 15:13:13 +00:00
* p2 = 0 ;
2003-09-04 18:25:57 +00:00
}
// p is the path now, check for .exe extension
2002-08-02 10:01:35 +00:00
2003-09-04 18:25:57 +00:00
e = p + mystrlen ( p ) - 4 ;
if ( e > p )
{
// if filename ends in .exe, and is not a directory, remove the filename
2010-03-24 17:22:56 +00:00
if ( ! lstrcmpi ( e , _T ( " .exe " ) ) ) // check extension
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
DWORD d ;
d = GetFileAttributes ( p ) ;
2004-01-30 23:51:31 +00:00
if ( d = = INVALID_FILE_ATTRIBUTES | | ! ( d & FILE_ATTRIBUTE_DIRECTORY ) )
2002-08-02 10:01:35 +00:00
{
2003-09-23 19:01:19 +00:00
// if there is no back-slash, the string will become empty, but that's ok because
// it would make an invalid instdir anyway
trimslashtoend ( p ) ;
2002-08-02 10:01:35 +00:00
}
}
}
2004-02-20 15:13:13 +00:00
mystrcpy ( state_install_directory , addtrailingslash ( p ) ) ;
2003-09-04 18:25:57 +00:00
}
2002-08-04 20:25:10 +00:00
}
}
2003-09-04 18:25:57 +00:00
if ( ! is_valid_instpath ( state_install_directory ) )
2002-08-24 14:44:23 +00:00
{
2003-09-04 18:25:57 +00:00
GetNSISString ( state_install_directory , header - > install_directory_ptr ) ;
}
2002-08-24 14:44:23 +00:00
2003-09-04 18:25:57 +00:00
# ifdef NSIS_CONFIG_LOG
if ( g_flags & CH_FLAGS_SILENT_LOG & & ! g_is_uninstaller )
{
2006-01-27 17:53:00 +00:00
# if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
2003-09-04 18:25:57 +00:00
build_g_logfile ( ) ;
2003-11-24 14:22:50 +00:00
# endif
2003-09-04 18:25:57 +00:00
log_dolog = 1 ;
2002-08-24 14:44:23 +00:00
}
2003-09-04 18:25:57 +00:00
# endif
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
2003-09-04 18:25:57 +00:00
g_hIcon = LoadImage ( g_hInstance , MAKEINTRESOURCE ( IDI_ICON2 ) , IMAGE_ICON , 0 , 0 , LR_DEFAULTSIZE | LR_SHARED ) ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_SUPPORT_BGBG
2003-09-04 18:25:57 +00:00
if ( header - > bg_color1 ! = - 1 )
{
2010-03-29 14:24:47 +00:00
LPCTSTR cn = _T ( " _Nb " ) ;
2003-09-04 18:25:57 +00:00
RECT vp ;
extern LRESULT CALLBACK BG_WndProc ( HWND , UINT , WPARAM , LPARAM ) ;
wc . lpfnWndProc = BG_WndProc ;
wc . hInstance = g_hInstance ;
wc . hIcon = g_hIcon ;
//wc.hCursor = LoadCursor(NULL,IDC_ARROW);
2010-03-29 14:24:47 +00:00
wc . lpszClassName = cn ;
2002-11-21 16:46:05 +00:00
2003-09-04 18:25:57 +00:00
if ( ! RegisterClass ( & wc ) ) return 0 ;
2002-11-21 16:46:05 +00:00
2003-09-04 18:25:57 +00:00
SystemParametersInfo ( SPI_GETWORKAREA , 0 , & vp , 0 ) ;
2010-03-29 14:24:47 +00:00
m_bgwnd = CreateWindowEx ( WS_EX_TOOLWINDOW , cn , 0 , WS_POPUP ,
2003-09-04 18:25:57 +00:00
vp . left , vp . top , vp . right - vp . left , vp . bottom - vp . top , 0 , NULL , g_hInstance , NULL ) ;
}
2002-08-02 10:01:35 +00:00
# endif //NSIS_SUPPORT_BGBG
2003-09-04 18:25:57 +00:00
# endif //NSIS_CONFIG_VISIBLE_SUPPORT
# ifdef NSIS_SUPPORT_CODECALLBACKS
// Select language
2004-09-25 10:49:08 +00:00
if ( ExecuteCallbackFunction ( CB_ONINIT ) ) return 2 ;
2003-09-04 18:25:57 +00:00
set_language ( ) ;
# endif
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
# ifdef NSIS_CONFIG_SILENT_SUPPORT
if ( ! g_exec_flags . silent )
# endif //NSIS_CONFIG_SILENT_SUPPORT
{
2003-05-09 21:11:14 +00:00
# ifdef NSIS_SUPPORT_BGBG
ShowWindow ( m_bgwnd , SW_SHOW ) ;
# endif //NSIS_SUPPORT_BGBG
2002-09-03 18:49:24 +00:00
# ifdef NSIS_CONFIG_LICENSEPAGE
{ // load richedit DLL
2017-09-14 17:10:33 +00:00
static const CHAR riched20 [ ] = ( " RichEd20 " ) ; // v2..3 DLL
static const CHAR riched32 [ ] = ( " RichEd32 " ) ; // v1 DLL
2013-08-15 23:14:12 +00:00
# ifdef UNICODE
static const TCHAR richedit20t [ ] = _T ( " RichEdit20W " ) ;
# else
static const TCHAR richedit20t [ ] = _T ( " RichEdit20A " ) ;
# endif
2017-09-14 17:10:33 +00:00
static const TCHAR richedit [ ] = _T ( " RichEdit " ) ; // v1 class
2015-11-29 13:54:35 +00:00
if ( ! LoadSystemLibrary ( riched20 ) )
2002-09-18 23:19:13 +00:00
{
2015-11-29 13:54:35 +00:00
LoadSystemLibrary ( riched32 ) ; // Win95 only ships with v1.0, NT4 has v2.0: web.archive.org/web/20030607222419/http://msdn.microsoft.com/library/en-us/shellcc/platform/commctls/richedit/richeditcontrols/aboutricheditcontrols.asp
2002-09-18 23:19:13 +00:00
}
2002-09-03 18:49:24 +00:00
2017-09-14 17:10:33 +00:00
// Register RichEdit20A/W as a RICHEDIT clone (for Win95)
2013-08-15 23:14:12 +00:00
if ( ! GetClassInfo ( NULL , richedit20t , & wc ) )
2002-09-03 18:49:24 +00:00
{
2007-04-20 20:32:04 +00:00
GetClassInfo ( NULL , richedit , & wc ) ;
2013-08-15 23:14:12 +00:00
wc . lpszClassName = richedit20t ;
2002-09-03 18:49:24 +00:00
RegisterClass ( & wc ) ;
}
}
2010-03-29 14:24:47 +00:00
2002-09-03 18:49:24 +00:00
# endif
2003-05-09 21:11:14 +00:00
{
2014-02-08 00:13:52 +00:00
int ret = ( int ) DialogBox ( g_hInstance , MAKEINTRESOURCE ( IDD_INST + dlg_offset ) , 0 , DialogProc ) ;
2003-05-09 21:11:14 +00:00
# if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
2004-08-06 11:05:48 +00:00
ExecuteCallbackFunction ( CB_ONGUIEND ) ;
2008-11-29 22:03:33 +00:00
# endif
# ifdef NSIS_CONFIG_PLUGIN_SUPPORT
Plugins_SendMsgToAllPlugins ( NSPIM_GUIUNLOAD ) ;
2003-05-09 21:11:14 +00:00
# endif
return ret ;
}
2002-08-02 10:01:35 +00:00
}
# endif //NSIS_CONFIG_VISIBLE_SUPPORT
# ifdef NSIS_CONFIG_SILENT_SUPPORT
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
else
2003-09-04 18:25:57 +00:00
# endif //NSIS_CONFIG_VISIBLE_SUPPORT
2002-08-02 10:01:35 +00:00
{
if ( install_thread ( NULL ) )
{
# ifdef NSIS_SUPPORT_CODECALLBACKS
2004-08-06 11:05:48 +00:00
if ( ! g_quit_flag ) ExecuteCallbackFunction ( CB_ONINSTFAILED ) ;
2002-08-02 10:01:35 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS
2004-09-25 10:49:08 +00:00
return 2 ;
2002-08-02 10:01:35 +00:00
}
# ifdef NSIS_SUPPORT_CODECALLBACKS
2004-08-06 11:05:48 +00:00
ExecuteCallbackFunction ( CB_ONINSTSUCCESS ) ;
2002-08-02 10:01:35 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS
2002-08-08 15:04:45 +00:00
2002-08-02 10:01:35 +00:00
return 0 ;
}
# endif //NSIS_CONFIG_SILENT_SUPPORT
}
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
2003-09-04 18:25:57 +00:00
static int CALLBACK WINAPI BrowseCallbackProc ( HWND hwnd , UINT uMsg , LPARAM lParam , LPARAM lpData )
2002-08-02 10:01:35 +00:00
{
2010-03-24 17:22:56 +00:00
// lpData has the TCHAR* to 'dir'.
2002-08-02 10:01:35 +00:00
if ( uMsg = = BFFM_INITIALIZED )
{
2010-03-24 17:22:56 +00:00
my_GetDialogItemText ( IDC_DIR , ( TCHAR * ) lpData ) ;
2003-09-15 22:05:06 +00:00
SendMessage ( hwnd , BFFM_SETSELECTION , ( WPARAM ) 1 , lpData ) ;
}
if ( uMsg = = BFFM_SELCHANGED )
{
2003-09-22 16:06:53 +00:00
SendMessage (
hwnd ,
BFFM_ENABLEOK ,
0 ,
2010-03-24 17:22:56 +00:00
SHGetPathFromIDList ( ( LPITEMIDLIST ) lParam , ( TCHAR * ) lpData )
2003-09-22 16:06:53 +00:00
# ifdef NSIS_SUPPORT_CODECALLBACKS
2004-08-06 11:05:48 +00:00
& & ! ExecuteCallbackFunction ( CB_ONVERIFYINSTDIR )
2003-09-22 16:06:53 +00:00
# endif
) ;
2002-08-02 10:01:35 +00:00
}
return 0 ;
}
2003-10-30 23:12:25 +00:00
2013-09-06 23:48:59 +00:00
INT_PTR CALLBACK DialogProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
if ( uMsg = = WM_INITDIALOG | | uMsg = = WM_NOTIFY_OUTER_NEXT )
{
2002-11-09 12:50:00 +00:00
page * this_page ;
2003-09-04 18:25:57 +00:00
static DLGPROC winprocs [ ] =
2002-08-02 10:01:35 +00:00
{
# ifdef NSIS_CONFIG_LICENSEPAGE
2003-09-04 18:25:57 +00:00
LicenseProc ,
2002-08-02 10:01:35 +00:00
# endif
# ifdef NSIS_CONFIG_COMPONENTPAGE
2003-09-04 18:25:57 +00:00
SelProc ,
2002-08-02 10:01:35 +00:00
# endif
2003-09-04 18:25:57 +00:00
DirProc ,
InstProc ,
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
2003-09-04 18:25:57 +00:00
UninstProc
2002-08-02 10:01:35 +00:00
# endif
} ;
2014-02-08 00:13:52 +00:00
m_delta = ( int ) wParam ;
2004-05-15 11:22:48 +00:00
2002-08-02 10:01:35 +00:00
if ( uMsg = = WM_INITDIALOG )
{
g_hwnd = hwndDlg ;
2002-09-23 20:56:29 +00:00
m_hwndOK = GetDlgItem ( hwndDlg , IDOK ) ;
m_hwndCancel = GetDlgItem ( hwndDlg , IDCANCEL ) ;
2002-10-01 14:13:23 +00:00
SetDlgItemTextFromLang ( hwndDlg , IDC_VERSTR , LANG_BRANDING ) ;
2013-08-07 23:04:23 +00:00
SetClassLongPtr ( hwndDlg , GCLP_HICON , ( LONG_PTR ) g_hIcon ) ;
2005-09-09 16:45:03 +00:00
// use the following line instead of the above, if .rdata needs shirking
//SendMessage(hwndDlg,WM_SETICON,ICON_BIG,(LPARAM)g_hIcon);
2002-11-01 20:34:55 +00:00
# if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
2004-08-06 11:05:48 +00:00
g_quit_flag = ExecuteCallbackFunction ( CB_ONGUIINIT ) ;
2002-08-02 10:01:35 +00:00
# endif
2003-11-09 22:45:25 +00:00
//ShowWindow(hwndDlg, SW_SHOW);
2004-05-15 11:22:48 +00:00
m_delta = 1 ;
2002-08-02 10:01:35 +00:00
}
2003-09-04 18:25:57 +00:00
this_page = g_pages + m_page ;
2002-11-09 12:50:00 +00:00
2003-01-24 19:40:20 +00:00
if ( m_page > = 0 ) {
2003-04-23 15:40:59 +00:00
# ifdef NSIS_SUPPORT_CODECALLBACKS
2003-03-18 15:45:25 +00:00
// Call leave function. If Abort used don't move to the next page.
2003-07-08 23:18:47 +00:00
// But if quit called we must exit now
2005-01-11 16:54:59 +00:00
if ( m_delta = = 1 ) if ( ExecuteCodeSegment ( this_page - > leavefunc , NULL ) ) {
SendMessage ( m_curwnd , WM_IN_UPDATEMSG , 0 , 1 ) ;
return ! g_quit_flag ;
}
2003-04-23 15:40:59 +00:00
# endif
2004-01-04 17:05:03 +00:00
2003-01-24 19:40:20 +00:00
// 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.
2003-09-04 18:25:57 +00:00
if ( ! this_page - > dlg_id ) return 0 ;
2003-01-24 19:40:20 +00:00
}
2002-11-09 12:50:00 +00:00
2004-01-04 17:05:03 +00:00
NotifyCurWnd ( WM_NOTIFY_INIGO_MONTOYA ) ;
2003-09-04 18:25:57 +00:00
2002-11-01 20:34:55 +00:00
nextPage :
2004-05-15 11:22:48 +00:00
m_page + = m_delta ;
this_page + = m_delta ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_SUPPORT_CODECALLBACKS
2004-08-06 11:05:48 +00:00
if ( m_page = = g_blocks [ NB_PAGES ] . num ) ExecuteCallbackFunction ( CB_ONINSTSUCCESS ) ;
2002-08-02 10:01:35 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS
2003-09-04 18:25:57 +00:00
if ( g_quit_flag | | ( unsigned int ) m_page > = ( unsigned int ) g_blocks [ NB_PAGES ] . num )
2002-08-02 10:01:35 +00:00
{
DestroyWindow ( m_curwnd ) ;
2003-07-18 14:22:17 +00:00
g_hwnd = 0 ;
2002-11-09 12:50:00 +00:00
EndDialog ( hwndDlg , m_retcode ) ;
2002-11-01 20:34:55 +00:00
}
else
2002-08-02 10:01:35 +00:00
{
2003-10-30 23:12:25 +00:00
HWND hwndtmp ;
2003-09-04 18:25:57 +00:00
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 ) ;
2004-01-04 17:05:03 +00:00
2003-09-04 18:25:57 +00:00
hwndtmp = GetDlgItem ( hwndDlg , IDC_BACK ) ;
2004-01-04 17:05:03 +00:00
2003-09-04 18:25:57 +00:00
if ( g_exec_flags . abort )
2003-04-04 12:27:58 +00:00
{
2003-09-04 18:25:57 +00:00
pflags & = ~ ( PF_BACK_ENABLE | PF_NEXT_ENABLE ) ;
pflags | = PF_CANCEL_ENABLE ;
2003-04-04 12:27:58 +00:00
}
2004-01-04 17:05:03 +00:00
2003-09-04 18:25:57 +00:00
ShowWindow ( hwndtmp , pflags & PF_BACK_SHOW ) ; // SW_HIDE = 0, PF_BACK_SHOW = SW_SHOWNA = 8
EnableWindow ( hwndtmp , pflags & PF_BACK_ENABLE ) ;
2004-01-04 17:05:03 +00:00
EnableNext ( pflags & PF_NEXT_ENABLE ) ;
2003-09-04 18:25:57 +00:00
EnableWindow ( m_hwndCancel , pflags & PF_CANCEL_ENABLE ) ;
2002-08-02 10:01:35 +00:00
2007-04-13 19:59:30 +00:00
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 ) ;
2004-01-04 17:05:03 +00:00
SendMessage ( hwndtmp , BM_SETSTYLE , BS_PUSHBUTTON , TRUE ) ;
if ( g_exec_flags . abort )
{
SendMessage ( hwndDlg , DM_SETDEFID , IDCANCEL , 0 ) ;
2004-03-06 12:31:26 +00:00
SetActiveCtl ( m_hwndCancel ) ;
2004-01-04 17:05:03 +00:00
}
else
{
2004-03-06 12:31:26 +00:00
SetActiveCtl ( m_hwndOK ) ;
2004-01-04 17:05:03 +00:00
}
2017-05-22 18:10:19 +00:00
mystrcpy ( g_tmp , update_caption ( ) ) ;
2003-09-04 18:25:57 +00:00
GetNSISString ( g_tmp + mystrlen ( g_tmp ) , this_page - > caption ) ;
2002-12-02 23:08:10 +00:00
my_SetWindowText ( hwndDlg , g_tmp ) ;
2002-11-30 13:15:49 +00:00
2002-12-06 15:43:35 +00:00
# ifdef NSIS_SUPPORT_CODECALLBACKS
2003-12-29 14:27:33 +00:00
// custom page or user used abort in prefunc
2003-09-04 18:25:57 +00:00
if ( ExecuteCodeSegment ( this_page - > prefunc , NULL ) | | ! this_page - > dlg_id ) {
2002-12-06 15:43:35 +00:00
goto nextPage ;
2003-09-04 18:25:57 +00:00
}
2002-12-06 15:43:35 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS
2004-01-04 17:05:03 +00:00
if ( this_page - > wndproc_id ! = PWP_COMPLETED )
{
DestroyWindow ( m_curwnd ) ;
}
2002-11-25 16:50:05 +00:00
else {
2004-01-04 17:05:03 +00:00
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 ;
2002-11-25 16:50:05 +00:00
}
2002-08-02 10:01:35 +00:00
2003-09-11 20:46:20 +00:00
// update g_this_page for the dialog proc
g_this_page = this_page ;
2003-09-04 18:25:57 +00:00
if ( this_page - > dlg_id > 0 ) // NSIS page
2002-11-09 12:50:00 +00:00
{
2003-10-30 23:12:25 +00:00
m_curwnd = CreateDialogParam (
2003-04-21 13:32:34 +00:00
g_hInstance ,
2003-09-04 18:25:57 +00:00
MAKEINTRESOURCE ( this_page - > dlg_id + dlg_offset ) ,
hwndDlg , winprocs [ this_page - > wndproc_id ] , ( LPARAM ) this_page
2003-04-21 13:32:34 +00:00
) ;
2003-10-30 23:12:25 +00:00
if ( m_curwnd )
2002-11-09 12:50:00 +00:00
{
RECT r ;
2003-09-04 18:25:57 +00:00
2003-10-30 23:12:25 +00:00
SetDlgItemTextFromLang ( m_curwnd , IDC_INTROTEXT , this_page - > parms [ 0 ] ) ;
2003-09-04 18:25:57 +00:00
2002-11-09 12:50:00 +00:00
GetWindowRect ( GetDlgItem ( hwndDlg , IDC_CHILDRECT ) , & r ) ;
ScreenToClient ( hwndDlg , ( LPPOINT ) & r ) ;
2003-10-30 23:12:25 +00:00
SetWindowPos ( m_curwnd , 0 , r . left , r . top , 0 , 0 , SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER ) ;
2002-11-11 20:24:26 +00:00
# ifdef NSIS_SUPPORT_CODECALLBACKS
2003-01-24 19:40:20 +00:00
ExecuteCodeSegment ( this_page - > showfunc , NULL ) ;
2007-04-17 19:12:24 +00:00
if ( g_quit_flag )
return FALSE ;
2002-11-11 20:24:26 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS
2003-10-30 23:12:25 +00:00
ShowWindow ( m_curwnd , SW_SHOWNA ) ;
2004-01-04 17:05:03 +00:00
NotifyCurWnd ( WM_NOTIFY_START ) ;
2002-11-01 20:34:55 +00:00
}
2002-08-02 10:01:35 +00:00
}
}
2003-11-09 22:45:25 +00:00
skipPage :
if ( ! ui_dlg_visible & & m_curwnd )
{
2016-10-12 19:31:57 +00:00
ShowWindow ( hwndDlg , SW_SHOWDEFAULT ) ;
2003-11-27 23:21:15 +00:00
ui_dlg_visible = 1 ;
2003-11-09 22:45:25 +00:00
}
2003-03-29 17:16:09 +00:00
return FALSE ;
2002-08-02 10:01:35 +00:00
}
2003-03-09 19:49:19 +00:00
# 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
2003-10-30 23:12:25 +00:00
if ( uMsg = = WM_NOTIFY_CUSTOM_READY ) {
2002-12-06 15:43:35 +00:00
DestroyWindow ( m_curwnd ) ;
2003-07-10 00:28:05 +00:00
m_curwnd = ( HWND ) wParam ;
2003-11-09 22:45:25 +00:00
goto skipPage ;
2002-12-06 15:43:35 +00:00
}
2004-10-14 13:56:02 +00:00
if ( uMsg = = WM_QUERYENDSESSION )
{
2011-11-19 15:41:45 +00:00
SetWindowLongPtr ( hwndDlg , DWLP_MSGRESULT , FALSE ) ;
2004-10-14 13:56:02 +00:00
return TRUE ;
}
2002-08-02 10:01:35 +00:00
if ( uMsg = = WM_COMMAND )
{
2003-12-29 15:12:41 +00:00
int id = LOWORD ( wParam ) ;
2007-02-20 21:34:32 +00:00
HWND hCtl = GetDlgItem ( hwndDlg , id ) ; // lParam might be NULL
if ( hCtl )
2004-01-04 17:05:03 +00:00
{
2007-02-20 21:34:32 +00:00
SendMessage ( hCtl , BM_SETSTATE , FALSE , 0 ) ;
if ( ! IsWindowEnabled ( hCtl ) )
2004-01-04 17:05:03 +00:00
return 0 ;
}
2002-08-02 10:01:35 +00:00
2002-11-01 20:34:55 +00:00
if ( id = = IDOK )
2002-08-02 10:01:35 +00:00
{
2002-09-21 03:21:56 +00:00
outernotify ( 1 ) ;
2002-08-02 10:01:35 +00:00
}
2004-09-03 12:52:29 +00:00
else if ( id = = IDC_BACK & & m_page > 0 )
2002-08-02 10:01:35 +00:00
{
2002-09-21 03:21:56 +00:00
outernotify ( - 1 ) ;
2002-08-02 10:01:35 +00:00
}
2004-09-03 12:52:29 +00:00
else if ( id = = IDCANCEL )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
if ( g_exec_flags . abort )
2002-08-02 10:01:35 +00:00
{
# ifdef NSIS_SUPPORT_CODECALLBACKS
2004-08-06 11:05:48 +00:00
ExecuteCallbackFunction ( CB_ONINSTFAILED ) ;
2002-08-02 10:01:35 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS
2002-11-09 12:50:00 +00:00
m_retcode = 2 ;
2002-11-21 16:46:05 +00:00
outernotify ( NOTIFY_BYE_BYE ) ;
2002-08-02 10:01:35 +00:00
}
else
{
# ifdef NSIS_SUPPORT_CODECALLBACKS
2004-08-06 11:05:48 +00:00
if ( ! ExecuteCallbackFunction ( CB_ONUSERABORT ) )
2002-08-02 10:01:35 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS
{
2002-11-09 12:50:00 +00:00
m_retcode = 1 ;
2002-11-21 16:46:05 +00:00
outernotify ( NOTIFY_BYE_BYE ) ;
2002-08-02 10:01:35 +00:00
}
}
}
2003-07-10 00:28:05 +00:00
else
{
2003-12-23 16:29:36 +00:00
// Forward WM_COMMANDs to inner dialogs, can be custom ones.
// Without this, enter on buttons in inner dialogs won't work.
2003-12-29 15:12:41 +00:00
SendMessage ( m_curwnd , WM_COMMAND , wParam , lParam ) ;
2003-07-10 00:28:05 +00:00
}
2002-08-02 10:01:35 +00:00
}
2002-08-21 19:15:00 +00:00
return HandleStaticBkColor ( ) ;
2002-08-02 10:01:35 +00:00
}
2004-01-29 01:23:24 +00:00
# define this_page ((page*)lParam)
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_LICENSEPAGE
2003-03-09 19:49:19 +00:00
2002-08-02 10:01:35 +00:00
# define _RICHEDIT_VER 0x0200
2004-06-11 11:24:09 +00:00
# include <richedit.h>
2002-08-02 10:01:35 +00:00
# undef _RICHEDIT_VER
2013-03-07 21:25:35 +00:00
static DWORD g_cbLicRead ;
2012-10-13 01:47:50 +00:00
DWORD CALLBACK StreamLicense ( DWORD_PTR dwCookie , LPBYTE pbBuff , LONG cb , LONG * pcb )
2002-08-21 19:15:00 +00:00
{
2013-03-07 21:25:35 +00:00
lstrcpyn ( ( LPTSTR ) pbBuff , ( LPTSTR ) ( dwCookie + g_cbLicRead ) , cb / sizeof ( TCHAR ) ) ;
2010-05-04 08:21:49 +00:00
* pcb = lstrlen ( ( LPTSTR ) pbBuff ) * sizeof ( TCHAR ) ;
2013-03-07 21:25:35 +00:00
g_cbLicRead + = * pcb ;
2002-08-21 19:15:00 +00:00
return 0 ;
}
2010-05-04 08:21:49 +00:00
# ifdef _UNICODE
2010-06-14 10:07:22 +00:00
// on-the-fly conversion of Unicode to ANSI (because Windows doesn't recognize Unicode RTF data)
2012-10-13 01:47:50 +00:00
DWORD CALLBACK StreamLicenseRTF ( DWORD_PTR dwCookie , LPBYTE pbBuff , LONG cb , LONG * pcb )
2010-05-04 08:21:49 +00:00
{
2013-03-07 21:25:35 +00:00
size_t len = lstrlen ( ( ( LPWSTR ) dwCookie ) + g_cbLicRead ) ;
2010-05-04 08:21:49 +00:00
len = min ( len , cb / sizeof ( WCHAR ) ) ;
2014-02-08 00:13:52 +00:00
* pcb = WideCharToMultiByte ( CP_ACP , 0 , ( ( LPWSTR ) dwCookie ) + g_cbLicRead , ( int ) len , ( char * ) pbBuff , cb , NULL , NULL ) ;
2010-05-04 08:21:49 +00:00
// RTF uses only ASCII characters, so we can assume "number of output bytes" = "number of source WChar consumed"
2013-03-07 21:25:35 +00:00
g_cbLicRead + = * pcb ;
2010-05-04 08:21:49 +00:00
return 0 ;
}
# endif
2002-08-21 19:15:00 +00:00
2013-09-06 23:48:59 +00:00
static INT_PTR CALLBACK LicenseProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
page * m_this_page = g_this_page ;
2003-03-29 13:39:48 +00:00
HWND hwLicense ;
2013-03-07 21:25:35 +00:00
# define LicIgnoreWMCommand g_cbLicRead // g_cbLicRead is only used in WM_INITDIALOG during EM_STREAMIN
2003-09-04 18:25:57 +00:00
2002-08-02 10:01:35 +00:00
if ( uMsg = = WM_INITDIALOG )
{
2010-03-24 17:22:56 +00:00
TCHAR * l = ( TCHAR * ) GetNSISStringNP ( GetNSISTab ( this_page - > parms [ 1 ] ) ) ;
2003-09-04 18:25:57 +00:00
int lt = * l ;
EDITSTREAM es = {
2010-05-04 08:21:49 +00:00
( DWORD_PTR ) ( + + l ) ,
2003-09-04 18:25:57 +00:00
0 ,
2010-05-04 08:21:49 +00:00
# ifdef _UNICODE
lt = = SF_RTF ? StreamLicenseRTF : StreamLicense
# else
2003-09-04 18:25:57 +00:00
StreamLicense
2010-05-04 08:21:49 +00:00
# endif
2003-09-04 18:25:57 +00:00
} ;
int selected = ( this_page - > flags & PF_LICENSE_SELECTED ) | ! ( this_page - > flags & PF_LICENSE_FORCE_SELECTION ) ;
2003-03-26 17:47:46 +00:00
2003-09-04 18:25:57 +00:00
SetUITextFromLang ( IDC_LICENSEAGREE , this_page - > parms [ 2 ] ) ;
SetUITextFromLang ( IDC_LICENSEDISAGREE , this_page - > parms [ 3 ] ) ;
2004-01-04 17:05:03 +00:00
CheckDlgButton ( hwndDlg , IDC_LICENSEAGREE + ! selected , BST_CHECKED ) ;
EnableNext ( selected ) ;
2003-03-26 17:47:46 +00:00
2002-09-23 19:27:42 +00:00
hwLicense = GetUIItem ( IDC_EDIT1 ) ;
2004-03-06 12:31:26 +00:00
SetActiveCtl ( hwLicense ) ;
2002-08-02 10:01:35 +00:00
SendMessage ( hwLicense , EM_AUTOURLDETECT , TRUE , 0 ) ;
2003-09-04 18:25:57 +00:00
# define lbg g_header->license_bg
2003-05-25 17:51:20 +00:00
SendMessage ( hwLicense , EM_SETBKGNDCOLOR , 0 , lbg > = 0 ? lbg : GetSysColor ( - lbg ) ) ;
# undef lbg
2002-09-08 11:02:28 +00:00
SendMessage ( hwLicense , EM_SETEVENTMASK , 0 , ENM_LINK | ENM_KEYEVENTS ) ; //XGE 8th September 2002 Or'd in ENM_KEYEVENTS
2003-09-04 18:25:57 +00:00
SendMessage ( hwLicense , EM_EXLIMITTEXT , 0 , mystrlen ( l ) ) ;
2013-03-07 21:25:35 +00:00
g_cbLicRead = 0 ;
2003-09-04 18:25:57 +00:00
SendMessage ( hwLicense , EM_STREAMIN , lt , ( LPARAM ) & es ) ;
2013-03-07 21:25:35 +00:00
LicIgnoreWMCommand = 0 ;
2002-09-06 17:29:34 +00:00
return FALSE ;
2002-08-02 10:01:35 +00:00
}
2013-03-07 21:25:35 +00:00
if ( uMsg = = WM_COMMAND & & HIWORD ( wParam ) = = BN_CLICKED & & ! LicIgnoreWMCommand ) {
2003-09-04 18:25:57 +00:00
if ( m_this_page - > flags & PF_LICENSE_FORCE_SELECTION ) {
2014-02-08 00:13:52 +00:00
int is = ( int ) ( SendMessage ( GetUIItem ( IDC_LICENSEAGREE ) , BM_GETCHECK , 0 , 0 ) & BST_CHECKED ) ;
2003-09-04 18:25:57 +00:00
m_this_page - > flags & = ~ PF_LICENSE_SELECTED ;
m_this_page - > flags | = is ;
2004-01-04 17:05:03 +00:00
EnableNext ( is ) ;
SetNextDef ( ) ;
2003-09-04 18:25:57 +00:00
}
2003-03-26 17:47:46 +00:00
}
2002-11-30 13:15:49 +00:00
if ( uMsg = = WM_NOTIFY ) {
2003-03-29 13:39:48 +00:00
hwLicense = GetUIItem ( IDC_EDIT1 ) ;
2002-09-12 11:47:05 +00:00
# define nmhdr ((NMHDR *)lParam)
# define enlink ((ENLINK *)lParam)
# define msgfilter ((MSGFILTER *)lParam)
if ( nmhdr - > code = = EN_LINK ) {
2002-08-02 10:01:35 +00:00
if ( enlink - > msg = = WM_LBUTTONDOWN ) {
2003-03-29 13:39:48 +00:00
TEXTRANGE tr = {
2004-03-12 20:43:54 +00:00
{
enlink - > chrg . cpMin ,
enlink - > chrg . cpMax ,
} ,
2003-03-29 13:39:48 +00:00
ps_tmpbuf
} ;
2013-08-15 23:14:12 +00:00
if ( tr . chrg . cpMax - tr . chrg . cpMin < COUNTOF ( ps_tmpbuf ) ) {
2003-03-29 13:39:48 +00:00
SendMessage ( hwLicense , EM_GETTEXTRANGE , 0 , ( LPARAM ) & tr ) ;
2006-01-27 15:44:40 +00:00
SetCursor ( LoadCursor ( 0 , IDC_WAIT ) ) ;
2017-06-05 01:01:28 +00:00
LaunchURL ( hwndDlg , tr . lpstrText , SW_SHOWNORMAL ) ;
2006-01-27 15:44:40 +00:00
SetCursor ( LoadCursor ( 0 , IDC_ARROW ) ) ;
2003-03-29 13:39:48 +00:00
}
2002-08-02 10:01:35 +00:00
}
}
2002-09-08 11:02:28 +00:00
//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.
2007-06-27 18:54:52 +00:00
//
//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.
2002-11-30 13:15:49 +00:00
if ( nmhdr - > code = = EN_MSGFILTER )
2002-09-07 21:33:48 +00:00
{
2003-03-29 13:39:48 +00:00
if ( msgfilter - > msg = = WM_KEYDOWN )
2002-09-07 21:33:48 +00:00
{
2003-12-29 15:12:41 +00:00
if ( msgfilter - > wParam = = VK_RETURN ) {
SendMessage ( g_hwnd , WM_COMMAND , IDOK , 0 ) ;
2003-03-29 13:39:48 +00:00
}
if ( msgfilter - > wParam = = VK_ESCAPE ) {
SendMessage ( g_hwnd , WM_CLOSE , 0 , 0 ) ;
}
2002-09-07 21:33:48 +00:00
return 1 ;
}
}
2002-11-30 13:15:49 +00:00
# undef nmhdr
# undef enlink
# undef msgfilter
2002-08-02 10:01:35 +00:00
}
2004-01-04 17:05:03 +00:00
if ( uMsg = = WM_NOTIFY_INIGO_MONTOYA )
{
2013-03-07 21:25:35 +00:00
LicIgnoreWMCommand + + ;
2004-01-04 17:05:03 +00:00
}
2002-08-21 19:15:00 +00:00
return HandleStaticBkColor ( ) ;
2002-08-02 10:01:35 +00:00
}
# endif
# ifdef NSIS_CONFIG_UNINSTALL_SUPPORT
2013-09-06 23:48:59 +00:00
static INT_PTR CALLBACK UninstProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
if ( uMsg = = WM_INITDIALOG )
{
2003-09-04 18:25:57 +00:00
SetUITextFromLang ( IDC_UNINSTFROM , this_page - > parms [ 1 ] ) ;
SetUITextNT ( IDC_EDIT1 , g_usrvars [ this_page - > parms [ 4 ] ] ) ;
2002-08-02 10:01:35 +00:00
}
2002-08-21 19:15:00 +00:00
return HandleStaticBkColor ( ) ;
2002-08-02 10:01:35 +00:00
}
# endif
2015-05-14 18:41:06 +00:00
# ifndef _NSIS_NO_INT64_SHR
# define NRT_U64Shr32(v,s) ( (v) >> (s) )
# else
# define NRT_U64Shr32 Int64ShrlMod32
# endif
2002-08-02 10:01:35 +00:00
2015-05-14 18:41:06 +00:00
static void NSISCALL SetSizeText64 ( int dlgItem , int prefix , ULARGE_INTEGER kb64 )
2002-08-02 10:01:35 +00:00
{
2010-03-24 17:22:56 +00:00
TCHAR scalestr [ 32 ] , byte [ 32 ] ;
2005-09-16 16:05:12 +00:00
int scale = LANG_GIGA ;
2015-05-14 18:41:06 +00:00
UINT intgr , fract ;
2005-09-09 12:13:32 +00:00
2015-05-14 20:17:14 +00:00
if ( kb64 . HighPart ) // >= 4 TiB ?
2015-05-14 18:41:06 +00:00
{
kb64 . QuadPart = NRT_U64Shr32 ( kb64 . QuadPart , 20 ) ; // Convert from KiB to GiB
// wsprintf only supports the I64 size specifier on WinXP+.
// Older versions would crash because %s will use a bad pointer if we use "%I64u%s%s".
// Consequently we will only use the bottom 32-bits of the size (in GiB),
// this means we will display the wrong number if you have more than 4194303 TiB of free space.
intgr = kb64 . LowPart ;
fract = 0 ; // We don't even attempt to calculate this
}
else
{
unsigned sh = 20 , kb = kb64 . LowPart ;
if ( kb < 1024 * 1024 ) sh = 10 , scale = LANG_MEGA ;
if ( kb < 1024 ) sh = 0 , scale = LANG_KILO ;
if ( kb < ( 0xFFFFFFFF - ( ( 1 < < 20 ) / 20 ) ) ) // check for overflow
kb + = ( 1 < < sh ) / 20 ; // round numbers for better display (e.g. 1.59 => 1.6)
2005-09-09 12:13:32 +00:00
2015-05-14 18:41:06 +00:00
intgr = kb > > sh ;
// 0x00FFFFFF mask is used to prevent overflow that causes bad results
fract = ( ( ( kb & 0x00FFFFFF ) * 10 ) > > sh ) % 10 ;
}
2005-02-25 15:28:37 +00:00
2008-11-20 19:20:33 +00:00
# if _MSC_VER == 1200 // patch #1982084
2003-09-04 18:25:57 +00:00
wsprintf (
2005-09-09 19:12:49 +00:00
GetNSISString ( g_tmp , prefix ) + mystrlen ( g_tmp ) ,
2008-11-20 19:20:33 +00:00
# else
GetNSISString ( g_tmp , prefix ) ;
wsprintf (
g_tmp + mystrlen ( g_tmp ) ,
# endif
2010-03-24 17:22:56 +00:00
_T ( " %u.%u%s%s " ) ,
2015-05-14 18:41:06 +00:00
intgr , fract ,
2005-09-09 19:12:49 +00:00
GetNSISString ( scalestr , scale ) ,
GetNSISString ( byte , LANG_BYTE )
2015-05-14 18:41:06 +00:00
) ;
2005-02-25 15:28:37 +00:00
my_SetDialogItemText ( m_curwnd , dlgItem , g_tmp ) ;
2002-08-02 10:01:35 +00:00
}
2015-05-14 18:41:06 +00:00
static void NSISCALL SetSizeText ( int dlgItem , int prefix , unsigned kb )
{
ULARGE_INTEGER kb64 ;
kb64 . QuadPart = kb ;
SetSizeText64 ( dlgItem , prefix , kb64 ) ;
}
2002-08-02 10:01:35 +00:00
2004-01-04 17:05:03 +00:00
static int NSISCALL _sumsecsfield ( int idx )
2003-11-14 21:08:51 +00:00
{
2004-10-14 21:33:33 +00:00
int total = 0 ;
int x = num_sections ;
section * s = g_sections ;
while ( x - - )
2003-11-14 21:08:51 +00:00
{
# ifdef NSIS_CONFIG_COMPONENTPAGE
2004-10-14 21:33:33 +00:00
if ( s - > flags & SF_SELECTED )
2003-11-14 21:08:51 +00:00
# endif
2004-10-14 21:33:33 +00:00
total + = ( ( int * ) s ) [ idx ] ;
s + + ;
2003-11-14 21:08:51 +00:00
}
return total ;
}
2004-01-04 17:05:03 +00:00
# define sumsecsfield(x) _sumsecsfield(SECTION_OFFSET(x))
2013-09-06 23:48:59 +00:00
static INT_PTR CALLBACK DirProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
2004-01-04 17:05:03 +00:00
static int dontsetdefstyle ;
2003-11-24 17:05:10 +00:00
page * thispage = g_this_page ;
2010-03-24 17:22:56 +00:00
TCHAR * dir = g_usrvars [ thispage - > parms [ 4 ] ] ;
2003-11-24 17:05:10 +00:00
int browse_text = thispage - > parms [ 3 ] ;
2010-03-29 14:24:47 +00:00
2003-02-07 23:04:25 +00:00
if ( uMsg = = WM_NOTIFY_INIGO_MONTOYA )
2002-08-02 10:01:35 +00:00
{
2004-01-04 17:05:03 +00:00
GetUIText ( IDC_DIR , dir ) ;
2003-09-04 18:25:57 +00:00
validate_filename ( dir ) ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_LOG
2006-01-27 17:53:00 +00:00
# if !defined(NSIS_CONFIG_LOG_ODS) && !defined(NSIS_CONFIG_LOG_STDOUT)
2002-08-02 10:01:35 +00:00
build_g_logfile ( ) ;
2003-11-24 14:22:50 +00:00
# endif
2005-04-08 14:36:19 +00:00
if ( GetUIItem ( IDC_CHECK1 ) ! = NULL )
log_dolog = IsDlgButtonChecked ( hwndDlg , IDC_CHECK1 ) ;
2002-08-02 10:01:35 +00:00
# endif
}
if ( uMsg = = WM_INITDIALOG )
{
2005-09-02 11:35:45 +00:00
HWND hDir = GetUIItem ( IDC_DIR ) ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_LOG
if ( GetAsyncKeyState ( VK_SHIFT ) & 0x8000 )
{
2002-09-23 19:27:42 +00:00
HWND h = GetUIItem ( IDC_CHECK1 ) ;
2003-09-04 18:25:57 +00:00
SetUITextFromLang ( IDC_CHECK1 , LANG_LOG_INSTALL_PROCESS ) ;
2002-08-02 10:01:35 +00:00
ShowWindow ( h , SW_SHOWNA ) ;
}
# endif
2003-09-26 21:12:43 +00:00
if ( validpathspec ( dir ) & & ! skip_root ( dir ) )
addtrailingslash ( dir ) ;
2006-01-13 19:56:03 +00:00
// workaround for bug #1209843
//
// m_curwnd is only updated once WM_INITDIALOG returns.
// my_SetWindowText triggers an EN_CHANGE message that
// triggers a WM_IN_UPDATEMSG message that uses m_curwnd
// to get the selected directory (GetUIText).
// because m_curwnd is still outdated, dir varialble is
// filled with an empty string. by default, dir points
// to $INSTDIR.
//
// to solve this, m_curwnd is manually set to the correct
// window handle.
m_curwnd = hwndDlg ;
2005-09-02 11:35:45 +00:00
my_SetWindowText ( hDir , dir ) ;
2003-09-04 18:25:57 +00:00
SetUITextFromLang ( IDC_BROWSE , this_page - > parms [ 2 ] ) ;
SetUITextFromLang ( IDC_SELDIRTEXT , this_page - > parms [ 1 ] ) ;
2005-09-02 11:35:45 +00:00
SetActiveCtl ( hDir ) ;
{
typedef HRESULT ( WINAPI * SHAutoCompletePtr ) ( HWND , DWORD ) ;
SHAutoCompletePtr fSHAutoComplete ;
2007-04-20 20:32:04 +00:00
fSHAutoComplete = ( SHAutoCompletePtr ) myGetProcAddress ( MGA_SHAutoComplete ) ;
2005-09-02 11:35:45 +00:00
if ( fSHAutoComplete )
{
fSHAutoComplete ( hDir , SHACF_FILESYSTEM ) ;
}
}
2002-08-02 10:01:35 +00:00
}
if ( uMsg = = WM_COMMAND )
{
int id = LOWORD ( wParam ) ;
if ( id = = IDC_DIR & & HIWORD ( wParam ) = = EN_CHANGE )
{
2002-11-30 13:15:49 +00:00
uMsg = WM_IN_UPDATEMSG ;
2002-08-02 10:01:35 +00:00
}
if ( id = = IDC_BROWSE )
{
2010-03-24 17:22:56 +00:00
static TCHAR bt [ NSIS_MAX_STRLEN ] ;
2003-09-15 22:05:06 +00:00
BROWSEINFO bi = { 0 , } ;
2014-02-11 01:34:11 +00:00
LPITEMIDLIST idlist ;
2002-08-02 10:01:35 +00:00
bi . hwndOwner = hwndDlg ;
2004-01-04 17:05:03 +00:00
bi . pszDisplayName = g_tmp ;
2003-09-15 22:05:06 +00:00
bi . lpfn = BrowseCallbackProc ;
2003-09-22 16:06:53 +00:00
bi . lParam = ( LPARAM ) dir ;
2006-06-16 13:15:01 +00:00
bi . lpszTitle = GetNSISString ( bt , browse_text ) ;
2002-08-02 10:01:35 +00:00
bi . ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE ;
2003-06-05 20:33:33 +00:00
idlist = SHBrowseForFolder ( & bi ) ;
2002-08-02 10:01:35 +00:00
if ( idlist )
{
2004-02-06 22:37:46 +00:00
// free idlist
2007-03-06 20:35:53 +00:00
CoTaskMemFree ( idlist ) ;
2002-08-02 10:01:35 +00:00
2005-11-26 13:06:08 +00:00
addtrailingslash ( dir ) ;
2007-01-24 13:08:18 +00:00
if ( g_header - > install_directory_auto_append & &
dir = = state_install_directory ) // only append to $INSTDIR (bug #1174184)
2002-08-02 10:01:35 +00:00
{
2010-03-24 17:22:56 +00:00
const TCHAR * post_str = ps_tmpbuf ;
2003-09-04 18:25:57 +00:00
GetNSISStringTT ( g_header - > install_directory_auto_append ) ;
2004-02-06 22:37:46 +00:00
// display name gives just the folder name
if ( lstrcmpi ( post_str , g_tmp ) )
2002-08-02 10:01:35 +00:00
{
2005-11-26 13:06:08 +00:00
mystrcat ( dir , post_str ) ;
2002-08-02 10:01:35 +00:00
}
}
2004-01-04 17:05:03 +00:00
dontsetdefstyle + + ;
2003-09-22 16:06:53 +00:00
SetUITextNT ( IDC_DIR , dir ) ;
2002-08-02 10:01:35 +00:00
}
2005-05-17 19:52:44 +00:00
else
{
uMsg = WM_IN_UPDATEMSG ;
}
2002-08-02 10:01:35 +00:00
}
}
2002-09-18 14:46:55 +00:00
if ( uMsg = = WM_IN_UPDATEMSG | | uMsg = = WM_NOTIFY_START )
2002-08-02 10:01:35 +00:00
{
2010-03-24 17:22:56 +00:00
static TCHAR s [ NSIS_MAX_STRLEN ] ;
2003-11-24 17:05:10 +00:00
int error = 0 ;
2015-05-14 18:41:06 +00:00
UINT total , available_set = FALSE ;
ULARGE_INTEGER available ;
2014-07-19 19:21:43 +00:00
2004-01-04 17:05:03 +00:00
GetUIText ( IDC_DIR , dir ) ;
2003-11-24 17:05:10 +00:00
if ( ! is_valid_instpath ( dir ) )
error = NSIS_INSTDIR_INVALID ;
2002-08-02 10:01:35 +00:00
2008-05-10 10:42:24 +00:00
/**
* This part is tricky . We need to make sure a few things :
*
* 1. GetDiskFreeSpaceEx is always called at least once for large HD .
* Even if skip_root ( ) returned NULL ( e . g . " C: " ) .
* Note that trimslashtoend ( ) will nullify " C: " .
* 2. GetDiskFreeSpaceEx is called with the deepest valid directory .
* e . g . C : \ drive when the user types C : \ drive \ folder1 \ folder2 .
* This makes sure NTFS mount points are treated properly ( # 1946112 ) .
* 3. ` s ' stays valid after the loop for GetDiskFreeSpace .
* This means there is no cutting beyond what skip_root ( ) returns .
2008-07-12 17:11:38 +00:00
* Or ` s ' could be recreated when GetDiskFreeSpace is called .
2008-05-10 10:42:24 +00:00
* 4. If GetDiskFreeSpaceEx doesn ' t exist , GetDiskFreeSpace is used .
2008-07-12 17:11:38 +00:00
* 5. Both functions require a trailing backslash
* 6. ` dir ' is never modified .
2008-05-10 10:42:24 +00:00
*
*/
2003-09-04 18:25:57 +00:00
mystrcpy ( s , dir ) ;
2002-08-02 10:01:35 +00:00
2004-03-06 12:31:26 +00:00
// Test for and use the GetDiskFreeSpaceEx API
2002-08-02 10:01:35 +00:00
{
2010-03-24 17:22:56 +00:00
BOOL ( WINAPI * GDFSE ) ( LPCTSTR , PULARGE_INTEGER , PULARGE_INTEGER , PULARGE_INTEGER ) =
2014-02-08 00:13:52 +00:00
# ifdef _WIN64
2014-03-03 18:10:53 +00:00
GetDiskFreeSpaceEx ;
2014-02-08 00:13:52 +00:00
# else
2014-03-03 18:10:53 +00:00
myGetProcAddress ( MGA_GetDiskFreeSpaceEx ) ;
2004-03-06 12:31:26 +00:00
if ( GDFSE )
2014-03-03 18:10:53 +00:00
# endif
2004-03-06 12:31:26 +00:00
{
2004-04-24 19:16:10 +00:00
ULARGE_INTEGER a , b ;
2015-05-14 18:41:06 +00:00
TCHAR * p , * pw = NULL ;
2010-03-29 14:24:47 +00:00
while ( pw ! = s ) // trimslashtoend() cut the entire string
2005-02-03 18:24:48 +00:00
{
2015-05-14 18:41:06 +00:00
if ( GDFSE ( s , & available , & a , & b ) )
2008-05-10 10:42:24 +00:00
{
2015-05-14 18:41:06 +00:00
available . QuadPart = NRT_U64Shr32 ( available . QuadPart , 10 ) ;
2008-05-10 10:42:24 +00:00
available_set + + ;
break ;
}
2008-07-12 17:11:38 +00:00
if ( pw )
// if pw was set, remove the backslash so trimslashtoend() will cut a new one
* pw = 0 ;
2008-07-12 16:40:04 +00:00
2008-07-12 17:11:38 +00:00
p = trimslashtoend ( s ) ; // trim last backslash
2010-03-29 14:24:47 +00:00
// bring it back, but make the next char null
pw = p ;
* pw = 0 ;
- - pw ;
* pw = _T ( ' \\ ' ) ;
2005-02-03 18:24:48 +00:00
}
2004-03-06 12:31:26 +00:00
}
}
2015-05-14 18:41:06 +00:00
# ifndef _WIN64
if ( ! available_set )
2004-03-06 12:31:26 +00:00
{
DWORD spc , bps , fc , tc ;
2010-03-24 17:22:56 +00:00
TCHAR * root ;
2008-05-10 10:42:24 +00:00
// GetDiskFreeSpaceEx accepts any path, but GetDiskFreeSpace accepts only the root
2008-07-12 17:11:38 +00:00
mystrcpy ( s , dir ) ;
root = skip_root ( s ) ;
2015-05-14 18:41:06 +00:00
if ( root ) * root = 0 ;
2008-05-10 10:42:24 +00:00
// GetDiskFreeSpaceEx is not available
2004-03-06 12:31:26 +00:00
if ( GetDiskFreeSpace ( s , & spc , & bps , & fc , & tc ) )
2005-02-03 18:24:48 +00:00
{
2015-05-14 18:41:06 +00:00
available . QuadPart = ( int ) MulDiv ( bps * spc , fc , 1 < < 10 ) ;
2005-02-03 18:24:48 +00:00
available_set + + ;
}
2002-08-02 10:01:35 +00:00
}
2012-09-08 02:50:09 +00:00
# endif
2015-05-14 18:41:06 +00:00
total = ( UINT ) sumsecsfield ( size_kb ) ;
if ( available_set )
if ( available . QuadPart < total )
error = NSIS_INSTDIR_NOT_ENOUGH_SPACE ;
2003-11-24 17:05:10 +00:00
2002-10-01 14:13:23 +00:00
if ( LANG_STR_TAB ( LANG_SPACE_REQ ) ) {
2005-09-16 16:05:12 +00:00
SetSizeText ( IDC_SPACEREQUIRED , LANG_SPACE_REQ , total ) ;
2005-02-25 14:19:00 +00:00
if ( available_set )
2015-05-14 18:41:06 +00:00
SetSizeText64 ( IDC_SPACEAVAILABLE , LANG_SPACE_AVAIL , available ) ;
2002-08-02 10:01:35 +00:00
else
2010-03-24 17:22:56 +00:00
SetUITextNT ( IDC_SPACEAVAILABLE , _T ( " " ) ) ;
2002-08-02 10:01:35 +00:00
}
2003-11-24 17:05:10 +00:00
g_exec_flags . instdir_error = error ;
2002-08-02 10:01:35 +00:00
# ifdef NSIS_SUPPORT_CODECALLBACKS
2003-11-24 17:05:10 +00:00
if ( ! error )
2004-08-06 11:05:48 +00:00
error = ExecuteCallbackFunction ( CB_ONVERIFYINSTDIR ) ;
2002-08-02 10:01:35 +00:00
# endif
2003-11-24 17:05:10 +00:00
if ( thispage - > flags & PF_DIR_NO_BTN_DISABLE )
error = 0 ;
2004-01-04 17:05:03 +00:00
EnableNext ( ! error ) ;
if ( ! error & & ! dontsetdefstyle )
SetNextDef ( ) ;
dontsetdefstyle = 0 ;
2002-08-02 10:01:35 +00:00
}
2002-08-21 19:15:00 +00:00
return HandleStaticBkColor ( ) ;
2002-08-02 10:01:35 +00:00
}
# ifdef NSIS_CONFIG_COMPONENTPAGE
2005-02-04 20:49:00 +00:00
static void FORCE_INLINE NSISCALL RefreshComponents ( HWND hwTree , HTREEITEM * items )
2003-04-05 12:56:57 +00:00
{
2005-01-11 16:38:48 +00:00
TVITEM item ;
int i , flags , state ;
2005-01-14 15:13:47 +00:00
section * sec ;
2004-01-04 17:05:03 +00:00
2005-01-11 16:38:48 +00:00
item . stateMask = TVIS_STATEIMAGEMASK | TVIS_EXPANDED | TVIS_BOLD ;
2004-01-04 17:05:03 +00:00
2005-01-14 15:13:47 +00:00
for ( i = 0 , sec = g_sections ; i < num_sections ; i + + , sec + + )
2003-04-05 12:56:57 +00:00
{
2005-01-11 16:38:48 +00:00
if ( ! items [ i ] )
{
continue ;
}
2003-04-05 12:56:57 +00:00
2005-01-14 15:13:47 +00:00
flags = sec - > flags ;
2003-04-05 12:56:57 +00:00
2005-01-11 16:38:48 +00:00
item . hItem = items [ i ] ;
2005-01-14 15:13:47 +00:00
item . mask = TVIF_STATE ;
2005-01-11 16:38:48 +00:00
2005-01-14 15:13:47 +00:00
if ( flags & SF_NAMECHG )
{
item . mask | = TVIF_TEXT ;
item . pszText = sec - > name ;
sec - > flags & = ~ SF_NAMECHG ;
}
2005-01-11 16:38:48 +00:00
if ( flags & SF_PSELECTED )
2003-04-05 12:56:57 +00:00
{
2005-01-11 16:38:48 +00:00
state = 3 ;
2003-04-05 12:56:57 +00:00
}
else
{
2005-01-11 16:38:48 +00:00
state = 1 + ( flags & SF_SELECTED ) ; // SF_SELECTED == 1
if ( flags & SF_RO ) state + = 3 ;
2003-04-05 12:56:57 +00:00
}
2006-01-14 16:03:53 +00:00
item . state = ( flags & SF_BOLD ) < < 1 ; // (SF_BOLD << 1) == 16 == TVIS_BOLD
item . state | = flags & SF_EXPAND ; // TVIS_EXPANDED == SF_EXPAND
2005-01-11 16:38:48 +00:00
item . state | = INDEXTOSTATEIMAGEMASK ( state ) ;
2003-04-05 12:56:57 +00:00
2006-01-14 15:42:15 +00:00
// TVE_COLLAPSE = 1, TVE_EXPAND = 2
TreeView_Expand ( hwTree , item . hItem , TVE_COLLAPSE + ( ( flags & SF_EXPAND ) / SF_EXPAND ) ) ;
2005-01-11 16:38:48 +00:00
TreeView_SetItem ( hwTree , & item ) ;
2003-04-05 12:56:57 +00:00
}
2006-01-14 15:22:49 +00:00
2020-06-28 21:55:37 +00:00
// workaround for bug #1397031 A.K.A #434
2006-01-14 15:32:56 +00:00
//
2020-06-28 21:55:37 +00:00
// Windows 95 & NT4 doesn't erase the background of the state image
// before it draws a new one. Because of this parts of the old
2006-01-14 15:32:56 +00:00
// state image will show where the new state image is masked.
//
2020-06-28 21:55:37 +00:00
// To solve this, the following line forces the background to
// be erased. sadly, this redraws the entire control. It might
2006-01-14 15:32:56 +00:00
// be a good idea to figure out where the state images are and
// redraw only those.
2020-06-28 21:55:37 +00:00
if ( IsWin95NT4 ( ) ) // Checking for < IE4 is probably better but more work
InvalidateRect ( hwTree , NULL , TRUE ) ;
2003-04-05 12:56:57 +00:00
}
2006-01-13 20:44:51 +00:00
int NSISCALL TreeGetSelectedSection ( HWND tree , BOOL mouse )
2003-04-05 12:56:57 +00:00
{
2006-01-13 20:44:51 +00:00
HTREEITEM hItem = TreeView_GetSelection ( tree ) ;
TVITEM item ;
if ( mouse )
{
TVHITTESTINFO ht ;
DWORD dwpos = GetMessagePos ( ) ;
2002-08-26 13:33:34 +00:00
2006-01-13 20:44:51 +00:00
ht . pt . x = GET_X_LPARAM ( dwpos ) ;
ht . pt . y = GET_Y_LPARAM ( dwpos ) ;
ScreenToClient ( tree , & ht . pt ) ;
2002-08-26 13:33:34 +00:00
2011-11-09 18:12:57 +00:00
{
const HTREEITEM UNUSED hDummy1 = TreeView_HitTest ( tree , & ht ) ;
}
2004-01-04 17:05:03 +00:00
2004-09-25 11:22:46 +00:00
# ifdef NSIS_CONFIG_COMPONENTPAGE_ALTERNATIVE
2006-01-13 20:44:51 +00:00
if ( ! ( ht . flags & TVHT_ONITEMSTATEICON ) )
2004-09-25 11:22:46 +00:00
# else
2006-01-13 20:44:51 +00:00
if ( ! ( ht . flags & ( TVHT_ONITEMSTATEICON | TVHT_ONITEMLABEL | TVHT_ONITEMRIGHT | TVHT_ONITEM ) ) )
2004-09-25 11:22:46 +00:00
# endif
2006-01-13 20:44:51 +00:00
return - 1 ;
2002-08-26 13:33:34 +00:00
2006-01-13 20:44:51 +00:00
hItem = ht . hItem ;
}
item . mask = TVIF_PARAM ;
item . hItem = hItem ;
TreeView_GetItem ( tree , & item ) ;
return ( int ) item . lParam ;
2002-08-26 13:33:34 +00:00
}
2011-11-20 22:03:21 +00:00
void NSISCALL ExecuteCallbackFunctionWithr0Int ( int num , int r0 )
{
mystrcpy ( g_tmp , g_usrvars [ 0 ] ) ;
myitoa ( g_usrvars [ 0 ] , r0 ) ;
ExecuteCallbackFunction ( num ) ;
mystrcpy ( g_usrvars [ 0 ] , g_tmp ) ;
}
2011-11-19 15:41:45 +00:00
static WNDPROC oldTreeWndProc ;
2006-11-25 10:51:00 +00:00
static LPARAM last_selected_tree_item ;
2014-02-08 00:13:52 +00:00
static LRESULT CALLBACK newTreeWndProc ( HWND hwnd , UINT uMsg , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
2005-01-11 16:38:48 +00:00
if ( uMsg = = WM_CHAR & & wParam = = VK_SPACE ) {
2004-01-04 17:05:03 +00:00
NotifyCurWnd ( WM_TREEVIEW_KEYHACK ) ;
2004-01-04 19:45:14 +00:00
return 0 ;
2002-08-02 10:01:35 +00:00
}
2002-11-01 20:34:55 +00:00
# if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
2004-09-25 11:22:46 +00:00
# ifndef NSIS_CONFIG_COMPONENTPAGE_ALTERNATIVE
2002-08-25 16:09:17 +00:00
if ( uMsg = = WM_MOUSEMOVE ) {
2004-01-04 17:05:03 +00:00
if ( IsWindowVisible ( hwnd ) ) {
2006-01-13 20:44:51 +00:00
lParam = TreeGetSelectedSection ( hwnd , TRUE ) ;
2003-05-24 13:50:24 +00:00
uMsg = WM_NOTIFY_SELCHANGE ;
2002-08-28 14:58:48 +00:00
}
}
2004-09-25 11:22:46 +00:00
# endif
2003-05-24 13:50:24 +00:00
if ( uMsg = = WM_NOTIFY_SELCHANGE ) {
2006-11-25 10:51:00 +00:00
if ( last_selected_tree_item ! = lParam )
2002-08-28 14:58:48 +00:00
{
2006-11-25 10:51:00 +00:00
last_selected_tree_item = lParam ;
2014-02-08 00:13:52 +00:00
ExecuteCallbackFunctionWithr0Int ( CB_ONMOUSEOVERSECTION , ( int ) lParam ) ;
2002-08-25 16:09:17 +00:00
}
}
2002-11-01 20:34:55 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
2011-11-19 15:41:45 +00:00
return CallWindowProc ( oldTreeWndProc , hwnd , uMsg , wParam , lParam ) ;
2002-08-02 10:01:35 +00:00
}
2013-09-06 23:48:59 +00:00
static INT_PTR CALLBACK SelProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
2011-11-20 22:03:21 +00:00
const int wParamSelChangeNotifyInstTypeChanged = - 1 ;
2002-08-02 10:01:35 +00:00
static HTREEITEM * hTreeItems ;
static HIMAGELIST hImageList ;
2002-09-23 19:27:42 +00:00
HWND hwndCombo1 = GetUIItem ( IDC_COMBO1 ) ;
HWND hwndTree1 = GetUIItem ( IDC_TREE1 ) ;
2011-11-20 22:03:21 +00:00
extern HWND g_SectionHack ; // TODO: Can we remove this?
2003-09-04 18:25:57 +00:00
section * sections = g_sections ;
2004-01-04 17:05:03 +00:00
int * install_types = g_header - > install_types ;
2002-08-02 10:01:35 +00:00
if ( uMsg = = WM_INITDIALOG )
{
int doLines = 0 ;
HTREEITEM Par ;
HBITMAP hBMcheck1 ;
2012-09-08 02:50:09 +00:00
int x , i , noCombo = 2 ;
2002-09-26 18:41:00 +00:00
g_SectionHack = hwndDlg ;
2005-09-09 16:08:44 +00:00
hTreeItems = ( HTREEITEM * ) GlobalAlloc ( GPTR , sizeof ( HTREEITEM ) * num_sections ) ;
2002-08-02 10:01:35 +00:00
2019-02-14 23:06:33 +00:00
hBMcheck1 = LoadImage ( g_hInstance , MAKEINTRESOURCE ( IDB_BITMAP1 ) , IMAGE_BITMAP , 0 , 0 , LR_DEFAULTCOLOR ) ; // LR_CREATEDIBSECTION required to load TopDown bitmaps but that breaks modern.bmp
2002-08-02 10:01:35 +00:00
2006-11-25 10:51:00 +00:00
last_selected_tree_item = - 1 ;
2011-11-19 15:41:45 +00:00
oldTreeWndProc = ( WNDPROC ) SetWindowLongPtr ( hwndTree1 , GWLP_WNDPROC , ( LONG_PTR ) newTreeWndProc ) ;
2002-09-20 17:08:34 +00:00
hImageList = ImageList_Create ( 16 , 16 , ILC_COLOR32 | ILC_MASK , 6 , 0 ) ;
ImageList_AddMasked ( hImageList , hBMcheck1 , RGB ( 255 , 0 , 255 ) ) ;
2002-08-02 10:01:35 +00:00
2011-11-09 18:12:57 +00:00
{
const HIMAGELIST UNUSED hDummy1 = TreeView_SetImageList ( hwndTree1 , hImageList , TVSIL_STATE ) ;
}
2002-08-02 10:01:35 +00:00
2005-10-25 14:32:34 +00:00
if ( TreeView_GetItemHeight ( hwndTree1 ) < 16 )
TreeView_SetItemHeight ( hwndTree1 , 16 ) ;
2003-10-30 00:08:21 +00:00
2002-08-02 10:01:35 +00:00
DeleteObject ( hBMcheck1 ) ;
2003-07-18 17:39:45 +00:00
for ( i = 0 ; i < NSIS_MAX_INST_TYPES + 1 ; i + + )
2003-05-24 13:50:24 +00:00
{
2004-01-04 17:05:03 +00:00
if ( install_types [ i ] )
2003-05-24 13:50:24 +00:00
{
2014-02-08 00:13:52 +00:00
LRESULT j ;
2003-09-04 18:25:57 +00:00
if ( i ! = NSIS_MAX_INST_TYPES ) noCombo = 0 ;
2004-10-14 21:33:33 +00:00
j = SendMessage ( hwndCombo1 , CB_ADDSTRING , 0 , ( LPARAM ) GetNSISStringTT ( install_types [ i ] ) ) ;
2003-05-24 13:50:24 +00:00
SendMessage ( hwndCombo1 , CB_SETITEMDATA , j , i ) ;
}
}
2003-09-04 18:25:57 +00:00
SetUITextFromLang ( IDC_TEXT1 , this_page - > parms [ 1 + noCombo ] ) ;
SetUITextFromLang ( IDC_TEXT2 , this_page - > parms [ 2 + noCombo ] ) ;
2002-08-02 10:01:35 +00:00
Par = NULL ;
2012-09-08 02:50:09 +00:00
for ( x = 0 ; x < num_sections ; x + + )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
section * sec = sections + x ;
2002-10-19 12:02:18 +00:00
2005-01-14 15:13:47 +00:00
if ( sec - > name [ 0 ] )
2002-08-02 10:01:35 +00:00
{
TVINSERTSTRUCT tv ;
2005-01-11 16:38:48 +00:00
tv . hParent = Par ;
tv . hInsertAfter = TVI_LAST ;
tv . item . mask = TVIF_PARAM | TVIF_TEXT | TVIF_STATE ;
tv . item . stateMask = TVIS_EXPANDED ;
tv . item . lParam = x ;
2005-01-14 15:13:47 +00:00
tv . item . pszText = sec - > name ;
2002-08-02 10:01:35 +00:00
2005-01-11 16:38:48 +00:00
tv . item . state = sec - > flags & SF_EXPAND ; // TVIS_EXPANDED == SF_EXPAND
2002-08-02 10:01:35 +00:00
2005-01-11 16:38:48 +00:00
if ( sec - > flags & SF_SECGRP )
2002-08-02 10:01:35 +00:00
{
2005-01-11 16:38:48 +00:00
tv . item . mask | = TVIF_CHILDREN ;
tv . item . cChildren = 1 ;
Par = hTreeItems [ x ] = TreeView_InsertItem ( hwndTree1 , & tv ) ;
doLines = 1 ;
2002-08-02 10:01:35 +00:00
}
2005-01-11 16:38:48 +00:00
else if ( sec - > flags & SF_SECGRPEND )
2002-08-02 10:01:35 +00:00
{
2005-01-11 16:38:48 +00:00
Par = TreeView_GetParent ( hwndTree1 , Par ) ;
2002-08-02 10:01:35 +00:00
}
else
{
2005-01-11 16:38:48 +00:00
hTreeItems [ x ] = TreeView_InsertItem ( hwndTree1 , & tv ) ;
2002-08-02 10:01:35 +00:00
}
}
}
2005-01-11 16:38:48 +00:00
2002-08-02 10:01:35 +00:00
if ( ! doLines )
{
2011-11-19 15:41:45 +00:00
SetWindowLongPtr ( hwndTree1 , GWL_STYLE , GetWindowLongPtr ( hwndTree1 , GWL_STYLE ) & ~ ( TVS_LINESATROOT ) ) ;
2002-08-02 10:01:35 +00:00
}
2004-01-04 17:05:03 +00:00
if ( ! noCombo )
{
ShowWindow ( hwndCombo1 , SW_SHOW ) ;
2004-03-06 12:31:26 +00:00
SetActiveCtl ( hwndCombo1 ) ;
2004-01-04 17:05:03 +00:00
}
else
2004-03-06 12:31:26 +00:00
SetActiveCtl ( hwndTree1 ) ;
2005-01-11 16:38:48 +00:00
}
2004-01-04 17:05:03 +00:00
2005-01-11 16:38:48 +00:00
if ( uMsg = = WM_NOTIFY_START )
{
wParam = 0 ;
lParam = 1 ;
uMsg = WM_IN_UPDATEMSG ;
2002-08-02 10:01:35 +00:00
}
2005-01-11 16:38:48 +00:00
2002-08-02 10:01:35 +00:00
if ( uMsg = = WM_NOTIFY | | uMsg = = WM_TREEVIEW_KEYHACK )
{
2002-08-11 18:56:30 +00:00
LPNMHDR lpnmh = ( LPNMHDR ) lParam ;
2002-08-02 10:01:35 +00:00
if ( uMsg = = WM_TREEVIEW_KEYHACK | | lpnmh - > idFrom = = IDC_TREE1 )
{
2003-09-04 18:25:57 +00:00
if ( ! ( g_flags & CH_FLAGS_NO_CUSTOM ) & & ( uMsg = = WM_TREEVIEW_KEYHACK | | lpnmh - > code = = NM_CLICK ) )
2002-08-02 10:01:35 +00:00
{
2006-01-13 20:44:51 +00:00
int secid = TreeGetSelectedSection ( hwndTree1 , uMsg ! = WM_TREEVIEW_KEYHACK ) ;
2002-08-11 18:56:30 +00:00
2006-01-13 20:44:51 +00:00
if ( secid > = 0 )
2002-08-02 10:01:35 +00:00
{
2006-01-13 20:44:51 +00:00
int flags = sections [ secid ] . flags ;
2005-01-11 16:38:48 +00:00
2006-01-13 20:44:51 +00:00
if ( ( flags & SF_RO ) = = 0 )
{
if ( ( flags & SF_PSELECTED ) )
2002-09-21 15:17:42 +00:00
{
2006-01-13 20:44:51 +00:00
flags ^ = SF_TOGGLED ;
if ( flags & SF_TOGGLED )
2005-01-11 16:38:48 +00:00
{
2006-01-13 20:44:51 +00:00
flags | = SF_SELECTED ;
2005-01-11 16:38:48 +00:00
}
else
{
2006-01-13 20:44:51 +00:00
flags & = ~ SF_SELECTED ;
2005-01-11 16:38:48 +00:00
}
2006-01-13 20:44:51 +00:00
}
else
{
flags ^ = SF_SELECTED ;
}
2005-01-11 16:38:48 +00:00
2006-01-13 20:44:51 +00:00
sections [ secid ] . flags = flags ;
2005-01-11 16:38:48 +00:00
2006-01-13 20:44:51 +00:00
SectionFlagsChanged ( secid ) ;
2005-01-11 16:38:48 +00:00
2011-11-20 22:03:21 +00:00
wParam = secid + 1 ;
2006-01-13 20:44:51 +00:00
lParam = ! ( g_flags & CH_FLAGS_COMP_ONLY_ON_CUSTOM ) ;
uMsg = WM_IN_UPDATEMSG ;
2005-01-11 16:38:48 +00:00
}
2002-08-02 10:01:35 +00:00
} // was valid click
} // was click or hack
2002-11-01 20:34:55 +00:00
# if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_ENHANCEDUI_SUPPORT)
2003-04-05 12:56:57 +00:00
if ( lpnmh )
{
if ( lpnmh - > code = = TVN_SELCHANGED )
2003-07-19 12:15:10 +00:00
{
2003-05-24 13:50:24 +00:00
SendMessage ( hwndTree1 , WM_NOTIFY_SELCHANGE , 0 , ( ( LPNMTREEVIEW ) lpnmh ) - > itemNew . lParam ) ;
2003-07-19 12:15:10 +00:00
}
2003-04-05 12:56:57 +00:00
if ( lpnmh - > code = = TVN_ITEMEXPANDED )
{
LPNMTREEVIEW pnmtv = ( LPNMTREEVIEW ) lpnmh ;
if ( pnmtv - > action = = TVE_EXPAND )
2003-09-04 18:25:57 +00:00
sections [ pnmtv - > itemNew . lParam ] . flags | = SF_EXPAND ;
2003-04-05 12:56:57 +00:00
else
2003-09-04 18:25:57 +00:00
sections [ pnmtv - > itemNew . lParam ] . flags & = ~ SF_EXPAND ;
2003-04-05 12:56:57 +00:00
}
2002-08-28 14:58:48 +00:00
}
2002-11-01 20:34:55 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_ENHANCEDUI_SUPPORT
2002-08-02 10:01:35 +00:00
}
}
2005-01-11 16:38:48 +00:00
if ( uMsg = = WM_COMMAND & & LOWORD ( wParam ) = = IDC_COMBO1 & & HIWORD ( wParam ) = = CBN_SELCHANGE )
2002-08-02 10:01:35 +00:00
{
2014-02-08 00:13:52 +00:00
LRESULT t = SendMessage ( hwndCombo1 , CB_GETCURSEL , 0 , 0 ) ;
2005-01-11 16:38:48 +00:00
if ( t ! = CB_ERR )
2002-08-02 10:01:35 +00:00
{
2014-02-08 00:13:52 +00:00
int whichcfg = ( int ) SendMessage ( hwndCombo1 , CB_GETITEMDATA , t , 0 ) ;
2003-05-24 13:50:24 +00:00
2005-01-11 16:38:48 +00:00
if ( whichcfg = = CB_ERR | | ! install_types [ whichcfg ] )
2003-05-24 13:50:24 +00:00
whichcfg = NSIS_MAX_INST_TYPES ;
2005-01-11 16:38:48 +00:00
SetInstType ( whichcfg ) ;
2003-05-24 13:50:24 +00:00
2005-03-19 11:56:23 +00:00
SendMessage ( hwndDlg , WM_NOTIFY_INSTTYPE_CHANGED , 0 , whichcfg ) ;
2011-11-20 22:03:21 +00:00
wParam = wParamSelChangeNotifyInstTypeChanged ;
2005-01-11 16:38:48 +00:00
lParam = 0 ;
2003-05-24 13:50:24 +00:00
uMsg = WM_IN_UPDATEMSG ;
2002-08-02 10:01:35 +00:00
}
}
2005-01-11 16:38:48 +00:00
if ( uMsg = = WM_MOUSEMOVE )
{
SendMessage ( hwndTree1 , WM_MOUSEMOVE , 0 , 0 ) ;
}
2003-02-07 23:04:25 +00:00
if ( uMsg = = WM_NOTIFY_INIGO_MONTOYA )
2002-08-02 10:01:35 +00:00
{
if ( hImageList ) ImageList_Destroy ( hImageList ) ;
if ( hTreeItems ) GlobalFree ( hTreeItems ) ;
2005-01-11 16:38:48 +00:00
hImageList = NULL ;
hTreeItems = NULL ;
g_SectionHack = NULL ;
2002-08-02 10:01:35 +00:00
}
2005-01-11 16:38:48 +00:00
2002-08-02 10:01:35 +00:00
if ( uMsg = = WM_IN_UPDATEMSG )
{
2005-02-04 20:45:02 +00:00
RefreshSectionGroups ( ) ;
2003-07-17 02:00:23 +00:00
2005-01-11 16:38:48 +00:00
# if defined(NSIS_SUPPORT_CODECALLBACKS) && defined(NSIS_CONFIG_COMPONENTPAGE)
2011-11-20 22:03:21 +00:00
if ( wParam ! = 0 )
2002-12-02 16:02:03 +00:00
{
2014-02-08 00:13:52 +00:00
int secid = ( int ) wParam ;
2011-11-20 22:03:21 +00:00
if ( wParamSelChangeNotifyInstTypeChanged ! = secid ) - - secid ;
ExecuteCallbackFunctionWithr0Int ( CB_ONSELCHANGE , secid ) ;
2002-12-02 16:02:03 +00:00
}
2005-01-11 16:38:48 +00:00
# endif //NSIS_SUPPORT_CODECALLBACKS && NSIS_CONFIG_COMPONENTPAGE
if ( lParam )
2002-12-02 16:02:03 +00:00
{
2005-03-19 11:56:23 +00:00
int i , cbi ;
int inst_type = GetInstType ( hTreeItems ) ;
SetInstType ( inst_type ) ;
2005-01-11 16:38:48 +00:00
2005-03-19 11:56:23 +00:00
for ( i = 0 , cbi = 0 ; i < inst_type ; i + + )
{
if ( install_types [ i ] )
2005-01-11 16:38:48 +00:00
{
2005-03-19 11:56:23 +00:00
cbi + + ;
2005-01-11 16:38:48 +00:00
}
}
2005-03-19 11:56:23 +00:00
SendMessage ( hwndCombo1 , CB_SETCURSEL , cbi , 0 ) ;
2003-05-24 13:50:24 +00:00
2005-03-19 11:56:23 +00:00
lParam = inst_type ;
uMsg = WM_NOTIFY_INSTTYPE_CHANGED ;
2005-01-11 16:38:48 +00:00
}
2002-12-02 15:51:33 +00:00
2005-02-04 20:45:02 +00:00
RefreshSectionGroups ( ) ;
2005-01-11 16:38:48 +00:00
RefreshComponents ( hwndTree1 , hTreeItems ) ;
2002-12-02 15:51:33 +00:00
2002-10-01 14:13:23 +00:00
if ( LANG_STR_TAB ( LANG_SPACE_REQ ) ) {
2005-09-16 16:05:12 +00:00
SetSizeText ( IDC_SPACEREQUIRED , LANG_SPACE_REQ , sumsecsfield ( size_kb ) ) ;
2002-08-02 10:01:35 +00:00
}
}
2003-07-13 22:31:33 +00:00
2005-03-19 11:56:23 +00:00
if ( uMsg = = WM_NOTIFY_INSTTYPE_CHANGED )
{
if ( g_flags & CH_FLAGS_COMP_ONLY_ON_CUSTOM )
{
int c = ( lParam = = NSIS_MAX_INST_TYPES ? 1 : 0 ) < < 3 ; // SW_SHOWNA=8, SW_HIDE=0
ShowWindow ( hwndTree1 , c ) ;
ShowWindow ( GetUIItem ( IDC_TEXT2 ) , c ) ;
}
}
2002-08-21 19:15:00 +00:00
return HandleStaticBkColor ( ) ;
2002-08-02 10:01:35 +00:00
}
# endif //NSIS_CONFIG_COMPONENTPAGE
# endif //NSIS_CONFIG_VISIBLE_SUPPORT
2010-03-24 17:22:56 +00:00
void NSISCALL update_status_text ( int strtab , const TCHAR * text ) {
static TCHAR tmp [ NSIS_MAX_STRLEN * 2 ] ;
2003-09-04 18:25:57 +00:00
LVITEM new_item ;
HWND linsthwnd = insthwnd ;
if ( linsthwnd )
2002-08-02 10:01:35 +00:00
{
2007-09-08 17:20:11 +00:00
int updateflag = g_exec_flags . status_update ;
2003-11-09 23:10:04 +00:00
int tmplen ;
2003-09-04 18:25:57 +00:00
2003-11-09 23:10:04 +00:00
if ( ! ( updateflag & 1 ) )
2003-09-04 18:25:57 +00:00
GetNSISString ( tmp , strtab ) ;
2003-11-09 23:10:04 +00:00
tmplen = mystrlen ( tmp ) ;
2003-09-04 18:25:57 +00:00
if ( text )
{
if ( tmplen + mystrlen ( text ) > = sizeof ( tmp ) ) return ;
2005-08-06 12:47:46 +00:00
mystrcat ( tmp , text ) ;
2003-09-04 18:25:57 +00:00
}
2007-09-21 18:20:12 +00:00
if ( ( updateflag & 4 ) = = 0 ) my_SetWindowText ( insthwnd2 , tmp ) ;
if ( ( updateflag & 2 ) = = 0 )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
new_item . mask = LVIF_TEXT ;
new_item . pszText = tmp ;
2003-11-14 21:08:51 +00:00
new_item . iItem = ListView_GetItemCount ( linsthwnd ) - ( updateflag & 1 ) ;
2003-09-04 18:25:57 +00:00
new_item . iSubItem = 0 ;
2006-01-14 15:42:15 +00:00
// LVM_INSERTITEM - LVM_SETITEM = 1
SendMessage ( linsthwnd , LVM_INSERTITEM - ( updateflag & 1 ) , 0 , ( LPARAM ) & new_item ) ;
2003-09-04 18:25:57 +00:00
ListView_EnsureVisible ( linsthwnd , new_item . iItem , 0 ) ;
2002-08-02 10:01:35 +00:00
}
2003-11-06 00:58:37 +00:00
2003-11-09 23:10:04 +00:00
if ( updateflag & 1 )
2003-11-14 21:08:51 +00:00
tmp [ tmplen ] = 0 ;
2002-08-02 10:01:35 +00:00
}
}
static DWORD WINAPI install_thread ( LPVOID p )
{
2004-10-14 21:33:33 +00:00
int m_inst_sec = num_sections ;
2003-09-04 18:25:57 +00:00
HWND progresswnd = ( HWND ) p ;
2004-10-14 21:33:33 +00:00
section * s = g_sections ;
2003-09-04 18:25:57 +00:00
# if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
extern HRESULT g_hres ;
g_hres | = OleInitialize ( NULL ) ;
2002-08-02 10:01:35 +00:00
}
# endif
2003-09-04 18:25:57 +00:00
2006-02-24 18:15:35 +00:00
// workaround for bug #1400995
//
// for an unexplained reason, MessageBox with MB_TOPMOST
// will fail, if no other messages were sent from this
// thread to the GUI thread before it.
//
// the source of the problem couldn't be found, so a
// WM_NULL is sent to work around it.
NotifyCurWnd ( WM_NULL ) ;
2004-10-14 21:33:33 +00:00
while ( m_inst_sec - - )
2003-09-04 18:25:57 +00:00
{
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_COMPONENTPAGE
2004-10-14 21:33:33 +00:00
if ( s - > flags & SF_SELECTED )
2002-08-02 10:01:35 +00:00
# endif
2003-09-04 18:25:57 +00:00
{
2010-03-24 17:22:56 +00:00
log_printf2 ( _T ( " Section: \" %s \" " ) , s - > name ) ;
2004-10-14 21:33:33 +00:00
if ( ExecuteCodeSegment ( s - > code , progresswnd ) )
2004-01-04 17:05:03 +00:00
{
g_exec_flags . abort + + ;
break ;
}
2003-09-04 18:25:57 +00:00
}
2002-08-02 10:01:35 +00:00
# ifdef NSIS_CONFIG_COMPONENTPAGE
2003-09-04 18:25:57 +00:00
else
{
2010-03-24 17:22:56 +00:00
log_printf2 ( _T ( " Skipping section: \" %s \" " ) , s - > name ) ;
2002-08-02 10:01:35 +00:00
}
# endif
2004-10-14 21:33:33 +00:00
s + + ;
2003-09-04 18:25:57 +00:00
}
2004-01-04 17:05:03 +00:00
NotifyCurWnd ( WM_NOTIFY_INSTPROC_DONE ) ;
2003-09-04 18:25:57 +00:00
# if defined(NSIS_SUPPORT_ACTIVEXREG) || defined(NSIS_SUPPORT_CREATESHORTCUT)
OleUninitialize ( ) ;
# endif
return g_exec_flags . abort ;
2002-08-02 10:01:35 +00:00
}
# ifdef NSIS_CONFIG_VISIBLE_SUPPORT
2003-12-08 22:30:27 +00:00
2013-09-06 23:48:59 +00:00
static INT_PTR CALLBACK InstProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
2003-09-04 18:25:57 +00:00
HWND linsthwnd = insthwnd ;
2002-08-02 10:01:35 +00:00
if ( uMsg = = WM_INITDIALOG )
{
2002-09-14 09:43:15 +00:00
RECT r ;
2003-12-08 22:30:27 +00:00
LVCOLUMN lvc = { LVCF_WIDTH , 0 , - 1 , 0 , 0 , - 1 } ;
2003-09-04 18:25:57 +00:00
int lb_bg = g_header - > lb_bg , lb_fg = g_header - > lb_fg ;
2002-08-02 10:01:35 +00:00
2002-09-23 19:27:42 +00:00
insthwndbutton = GetUIItem ( IDC_SHOWDETAILS ) ;
insthwnd2 = GetUIItem ( IDC_INTROTEXT ) ;
2003-09-04 18:25:57 +00:00
linsthwnd = insthwnd = GetUIItem ( IDC_LIST1 ) ;
2004-11-25 22:31:08 +00:00
SetActiveCtl ( insthwndbutton ) ;
2004-01-04 17:05:03 +00:00
progress_bar_len = sumsecsfield ( code_size ) ;
2003-09-04 18:25:57 +00:00
progress_bar_pos = 0 ;
2010-03-24 17:22:56 +00:00
log_printf3 ( _T ( " New install of \" %s \" to \" %s \" " ) , GetNSISStringTT ( LANG_NAME ) , state_install_directory ) ;
2003-09-04 18:25:57 +00:00
2003-12-08 22:30:27 +00:00
GetClientRect ( linsthwnd , & r ) ;
2015-06-25 20:38:20 +00:00
lvc . cx = r . right - GetSystemMetrics ( SM_CXVSCROLL ) ;
2003-09-04 18:25:57 +00:00
ListView_InsertColumn ( linsthwnd , 0 , & lvc ) ;
2003-12-08 22:30:27 +00:00
2003-09-04 18:25:57 +00:00
ListView_SetExtendedListViewStyleEx ( linsthwnd , LVS_EX_LABELTIP , LVS_EX_LABELTIP ) ;
2002-08-26 16:09:30 +00:00
if ( lb_bg > = 0 ) {
2003-09-04 18:25:57 +00:00
ListView_SetBkColor ( linsthwnd , lb_bg ) ;
ListView_SetTextBkColor ( linsthwnd , lb_bg ) ;
2002-08-26 16:09:30 +00:00
}
if ( lb_fg > = 0 ) {
2003-09-04 18:25:57 +00:00
ListView_SetTextColor ( linsthwnd , lb_fg ) ;
2002-08-26 16:09:30 +00:00
}
2003-09-04 18:25:57 +00:00
SetUITextFromLang ( IDC_SHOWDETAILS , this_page - > parms [ 1 ] ) ;
if ( g_flags & ( CH_FLAGS_DETAILS_SHOWDETAILS | CH_FLAGS_DETAILS_NEVERSHOW ) )
2002-08-02 10:01:35 +00:00
{
ShowWindow ( insthwndbutton , SW_HIDE ) ;
2003-09-04 18:25:57 +00:00
if ( ! ( g_flags & CH_FLAGS_DETAILS_NEVERSHOW ) ) ShowWindow ( linsthwnd , SW_SHOWNA ) ;
2002-08-02 10:01:35 +00:00
else insthwndbutton = NULL ;
2007-06-08 17:11:54 +00:00
SetActiveCtl ( insthwnd2 ) ;
2002-08-02 10:01:35 +00:00
}
{
2003-09-04 18:25:57 +00:00
HWND progresswnd = GetUIItem ( IDC_PROGRESS ) ;
SendMessage ( progresswnd , PBM_SETRANGE , 0 , MAKELPARAM ( 0 , 30000 ) ) ;
if ( g_flags & CH_FLAGS_PROGRESS_COLORED )
{
SendMessage ( progresswnd , PBM_SETBARCOLOR , 0 , lb_fg ) ;
SendMessage ( progresswnd , PBM_SETBKCOLOR , 0 , lb_bg ) ;
}
2002-08-02 10:01:35 +00:00
}
2003-03-29 17:16:09 +00:00
return FALSE ;
2002-09-18 14:46:55 +00:00
}
if ( uMsg = = WM_NOTIFY_START ) {
DWORD id ;
2003-09-04 18:25:57 +00:00
CloseHandle ( CreateThread ( NULL , 0 , install_thread , GetUIItem ( IDC_PROGRESS ) , 0 , & id ) ) ;
2002-08-02 10:01:35 +00:00
}
if ( uMsg = = WM_COMMAND & & LOWORD ( wParam ) = = IDC_SHOWDETAILS )
{
2003-09-04 18:25:57 +00:00
ShowWindow ( insthwndbutton , SW_HIDE ) ;
ShowWindow ( linsthwnd , SW_SHOWNA ) ;
2007-06-08 17:15:19 +00:00
SetActiveCtl ( linsthwnd ) ;
2002-08-02 10:01:35 +00:00
}
if ( uMsg = = WM_NOTIFY_INSTPROC_DONE )
{
2002-09-19 21:53:24 +00:00
if ( g_quit_flag )
2002-11-09 12:50:00 +00:00
{
2004-09-25 10:49:08 +00:00
m_retcode = 2 ;
2002-11-21 16:46:05 +00:00
outernotify ( NOTIFY_BYE_BYE ) ;
2002-11-09 12:50:00 +00:00
}
2003-04-04 12:27:58 +00:00
else
2002-08-02 10:01:35 +00:00
{
2002-11-01 20:34:55 +00:00
ShowWindow ( g_hwnd , SW_SHOWNA ) ;
2003-09-04 18:25:57 +00:00
if ( ! g_exec_flags . abort )
update_status_text ( g_this_page - > parms [ 2 ] , 0 ) ;
2002-11-01 20:34:55 +00:00
outernotify ( 1 ) ;
2002-08-02 10:01:35 +00:00
}
}
2002-08-30 19:51:05 +00:00
//>>>Ximon Eighteen aka Sunjammer 30th August 2002
2002-08-31 10:25:24 +00:00
//+++Popup "Copy Details To Clipboard" menu when RMB clicked in DetailView
2004-01-04 17:05:03 +00:00
if ( uMsg = = WM_CONTEXTMENU & & wParam = = ( WPARAM ) linsthwnd )
2002-08-30 19:51:05 +00:00
{
2003-09-04 18:25:57 +00:00
int count = ListView_GetItemCount ( linsthwnd ) ;
2002-08-30 19:51:05 +00:00
if ( count > 0 )
{
2002-08-31 10:25:24 +00:00
HMENU menu = CreatePopupMenu ( ) ;
2004-01-04 17:05:03 +00:00
POINT pt ;
2003-09-04 18:25:57 +00:00
AppendMenu ( menu , MF_STRING , 1 , GetNSISStringTT ( LANG_COPYDETAILS ) ) ;
2013-09-06 23:48:59 +00:00
pt . x = GET_X_LPARAM ( lParam ) , pt . y = GET_Y_LPARAM ( lParam ) ;
2016-03-23 22:55:08 +00:00
if ( lParam = = ( LPARAM ) ( ( INT_PTR ) - 1 ) )
2004-01-04 17:05:03 +00:00
{
RECT r ;
2013-09-06 23:48:59 +00:00
GetWindowRect ( linsthwnd , & r ) ;
pt . x = r . left , pt . y = r . top ;
2004-01-04 17:05:03 +00:00
}
2013-09-06 23:48:59 +00:00
if ( 1 = = TrackPopupMenu ( menu , TPM_NONOTIFY | TPM_RETURNCMD , pt . x , pt . y , 0 , hwndDlg , 0 ) )
2002-08-30 19:51:05 +00:00
{
2002-10-05 16:20:13 +00:00
int i , total = 1 ; // 1 for the null char
2002-08-31 10:25:24 +00:00
LVITEM item ;
HGLOBAL memory ;
2002-10-05 16:20:13 +00:00
LPTSTR ptr ; //,endPtr;
2002-08-31 10:25:24 +00:00
// 1st pass - determine clipboard memory required.
item . iSubItem = 0 ;
2004-01-04 17:05:03 +00:00
item . pszText = g_tmp ;
2016-06-26 15:32:44 +00:00
item . cchTextMax = COUNTOF ( g_tmp ) ;
2002-09-30 20:52:00 +00:00
i = count ;
while ( i - - )
2002-08-31 10:25:24 +00:00
// Add 2 for the CR/LF combination that must follow every line.
2014-02-08 00:13:52 +00:00
total + = 2 + ( int ) SendMessage ( linsthwnd , LVM_GETITEMTEXT , i , ( LPARAM ) & item ) ;
2002-08-30 21:41:54 +00:00
2002-08-31 10:25:24 +00:00
// 2nd pass - store detail view strings on the clipboard
// Clipboard MSDN docs say mem must be GMEM_MOVEABLE
OpenClipboard ( 0 ) ;
EmptyClipboard ( ) ;
2010-03-24 17:22:56 +00:00
memory = GlobalAlloc ( GHND , total * sizeof ( TCHAR ) ) ;
2002-08-31 10:25:24 +00:00
ptr = GlobalLock ( memory ) ;
2002-10-05 16:20:13 +00:00
//endPtr = ptr+total-2; // -2 to allow for CR/LF
2002-09-30 20:52:00 +00:00
i = 0 ;
do {
2003-12-08 22:30:27 +00:00
item . pszText = ptr ;
2006-11-25 10:28:32 +00:00
ptr + = SendMessage ( linsthwnd , LVM_GETITEMTEXT , i , ( LPARAM ) & item ) ;
2010-03-29 14:24:47 +00:00
* ptr + + = _T ( ' \r ' ) ;
* ptr + + = _T ( ' \n ' ) ;
2002-09-30 20:52:00 +00:00
} while ( + + i < count ) ;
2002-10-05 16:20:13 +00:00
// memory is auto zeroed when allocated with GHND - *ptr = 0;
2002-08-31 10:25:24 +00:00
GlobalUnlock ( memory ) ;
2010-03-29 14:24:47 +00:00
# ifdef _UNICODE
SetClipboardData ( CF_UNICODETEXT , memory ) ;
# else
2002-08-31 10:25:24 +00:00
SetClipboardData ( CF_TEXT , memory ) ;
2010-03-29 14:24:47 +00:00
# endif
2002-08-31 10:25:24 +00:00
CloseClipboard ( ) ;
2002-08-30 19:51:05 +00:00
}
}
2003-03-29 17:16:09 +00:00
return FALSE ;
2002-08-30 19:51:05 +00:00
}
//<<<
2002-08-21 19:15:00 +00:00
return HandleStaticBkColor ( ) ;
2002-08-02 10:01:35 +00:00
}
# endif //NSIS_CONFIG_VISIBLE_SUPPORT