2003-03-11 13:29:38 +00:00
/*********************************************************
2002-09-05 22:22:26 +00:00
*
2003-03-11 13:29:38 +00:00
* InstallOptions version 2.0 - Plugin for custom pages
2002-08-02 10:01:35 +00:00
*
2003-03-11 13:29:38 +00:00
* See Readme . html for documentation and license
2002-08-02 10:01:35 +00:00
*
2003-03-11 13:29:38 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-08-02 10:01:35 +00:00
# include <windows.h>
# include <windowsx.h>
# include <shlobj.h>
# include <commdlg.h>
2003-06-02 14:26:15 +00:00
# include <cderr.h>
2002-08-02 10:01:35 +00:00
# include "resource.h"
2005-03-17 21:26:59 +00:00
# include "shellapi.h"
2002-08-02 10:01:35 +00:00
2003-06-07 10:59:11 +00:00
# define popstring dontuseme
2005-03-17 21:26:59 +00:00
# include "../ExDLL/exdll.h"
2003-06-07 10:59:11 +00:00
# undef popstring
2004-01-04 14:06:39 +00:00
// Use for functions only called from one place to possibly reduce some code
// size. Allows the source code to remain readable by leaving the function
// intact.
# ifdef _MSC_VER
# define INLINE __forceinline
# else
# define INLINE inline
# endif
2003-12-04 22:12:25 +00:00
void * WINAPI MALLOC ( int len ) { return ( void * ) GlobalAlloc ( GPTR , len ) ; }
void WINAPI FREE ( void * d ) { if ( d ) GlobalFree ( ( HGLOBAL ) d ) ; }
2004-01-12 23:23:36 +00:00
void WINAPI popstring ( char * str )
2003-06-07 10:59:11 +00:00
{
2004-01-12 23:23:36 +00:00
if ( g_stacktop & & * g_stacktop )
{
stack_t * th = * g_stacktop ;
* g_stacktop = th - > next ;
if ( str )
lstrcpy ( str , th - > text ) ;
FREE ( th ) ;
}
2003-06-07 10:59:11 +00:00
}
2002-08-02 10:01:35 +00:00
# define strcpy(x,y) lstrcpy(x,y)
2003-12-04 22:12:25 +00:00
//#define strncpy(x,y,z) lstrcpyn(x,y,z)
2002-08-02 10:01:35 +00:00
# define strdup(x) STRDUP(x)
# define stricmp(x,y) lstrcmpi(x,y)
//#define abs(x) ((x) < 0 ? -(x) : (x))
2003-11-01 00:17:19 +00:00
char * WINAPI STRDUP ( const char * c )
2002-08-02 10:01:35 +00:00
{
char * t = ( char * ) MALLOC ( lstrlen ( c ) + 1 ) ;
2003-06-02 14:26:15 +00:00
return lstrcpy ( t , c ) ;
2002-08-02 10:01:35 +00:00
}
2004-01-31 19:54:45 +00:00
// Turn a pair of chars into a word
// Turn four chars into a dword
# ifdef __BIG_ENDIAN__ // Not very likely, but, still...
# define CHAR2_TO_WORD(a,b) (((WORD)(b))|((a)<<8))
# define CHAR4_TO_DWORD(a,b,c,d) (((DWORD)CHAR2_TO_WORD(c,d))|(CHAR2_TO_WORD(a,b)<<16))
# else
# define CHAR2_TO_WORD(a,b) (((WORD)(a))|((b)<<8))
# define CHAR4_TO_DWORD(a,b,c,d) (((DWORD)CHAR2_TO_WORD(a,b))|(CHAR2_TO_WORD(c,d)<<16))
# endif
2004-01-05 21:53:06 +00:00
// Field types
// NB - the order of this list is important - see below
2003-09-21 16:22:34 +00:00
# define FIELD_INVALID (0)
2002-09-10 20:04:54 +00:00
# define FIELD_LABEL (1)
# define FIELD_ICON (2)
# define FIELD_BITMAP (3)
# define FIELD_BROWSEBUTTON (4)
2004-01-05 21:53:06 +00:00
# define FIELD_LINK (5)
# define FIELD_BUTTON (6)
# define FIELD_GROUPBOX (7)
# define FIELD_CHECKBOX (8)
# define FIELD_RADIOBUTTON (9)
# define FIELD_TEXT (10)
# define FIELD_FILEREQUEST (11)
# define FIELD_DIRREQUEST (12)
# define FIELD_COMBOBOX (13)
# define FIELD_LISTBOX (14)
# define FIELD_SETFOCUS FIELD_CHECKBOX // First field that qualifies for having the initial keyboard focus
# define FIELD_CHECKLEN FIELD_TEXT // First field to have length of state value checked against MinLen/MaxLen
2002-08-02 10:01:35 +00:00
2003-07-07 21:08:26 +00:00
//---------------------------------------------------------------------
2003-07-05 16:55:54 +00:00
// settings
2003-07-07 21:08:26 +00:00
# define IO_ENABLE_LINK
//#define IO_LINK_UNDERLINED // Uncomment to show links text underlined
//---------------------------------------------------------------------
2003-07-05 16:55:54 +00:00
2004-01-04 14:06:39 +00:00
// Flags
// LBS_NOTIFY 0x00000001 // LISTBOX/CHECKBOX/RADIOBUTTON/BUTTON/LINK - Notify NSIS script when control is "activated" (exact meaning depends on the type of control)
// OFN_OVERWRITEPROMPT 0x00000002 // FILEREQUEST
// OFN_HIDEREADONLY 0x00000004 // FILEREQUEST
// LBS_MULTIPLESEL 0x00000008 // LISTBOX
# define FLAG_READONLY 0x00000010 // TEXT/FILEREQUEST/DIRREQUEST
// BS_LEFTTEXT 0x00000020 // CHECKBOX/RADIOBUTTON
2005-01-21 19:12:47 +00:00
# define TRANSPARENT_BMP 0x00000020 // BITMAP
2004-01-04 14:06:39 +00:00
# define FLAG_PASSWORD 0x00000040 // TEXT/FILEREQUEST/DIRREQUEST
# define FLAG_ONLYNUMBERS 0x00000080 // TEXT/FILEREQUEST/DIRREQUEST
# define FLAG_MULTILINE 0x00000100 // TEXT/FILEREQUEST/DIRREQUEST
# define FLAG_NOWORDWRAP 0x00000200 // TEXT/FILEREQUEST/DIRREQUEST - Disable word-wrap in multi-line text boxes
# define FLAG_WANTRETURN 0x00000400 // TEXT/FILEREQUEST/DIRREQUEST
// LBS_EXTENDEDSEL 0x00000800 // LISTBOX
// OFN_PATHMUSTEXIST 0x00000800 // FILEREQUEST
// OFN_FILEMUSTEXIST 0x00001000 // FILEREQUEST
// OFN_CREATEPROMPT 0x00002000 // FILEREQUEST
# define FLAG_DROPLIST 0x00004000 // COMBOBOX
# define FLAG_RESIZETOFIT 0x00008000 // BITMAP
// WS_TABSTOP 0x00010000 // *ALL*
// WS_GROUP 0x00020000 // *ALL*
# define FLAG_SAVEAS 0x00040000 // FILEREQUEST - Show "Save As" instead of "Open" for FileRequest field
// OFN_EXPLORER 0x00080000 // FILEREQUEST
// WS_HSCROLL 0x00100000 // *ALL*
// WS_VSCROLL 0x00200000 // *ALL*
// WS_DISABLED 0x08000000 // *ALL*
2007-01-23 17:33:31 +00:00
# define FLAG_FOCUS 0x10000000 // Controls that can receive focus
2003-06-10 13:18:07 +00:00
2002-08-02 10:01:35 +00:00
struct TableEntry {
char * pszName ;
2002-09-05 22:22:26 +00:00
int nValue ;
2002-08-02 10:01:35 +00:00
} ;
2003-11-01 00:17:19 +00:00
int WINAPI LookupToken ( TableEntry * , char * ) ;
int WINAPI LookupTokens ( TableEntry * , char * ) ;
2002-09-05 22:22:26 +00:00
2003-11-01 00:17:19 +00:00
void WINAPI ConvertNewLines ( char * str ) ;
2003-03-17 13:46:13 +00:00
2004-01-31 19:54:45 +00:00
// all allocated buffers must be first in the struct
// when adding more allocated buffers to FieldType, don't forget to change this define
# define FIELD_BUFFERS 6
2002-08-02 10:01:35 +00:00
struct FieldType {
2003-03-23 17:12:14 +00:00
char * pszText ;
char * pszState ;
char * pszRoot ;
2002-08-02 10:01:35 +00:00
2003-03-23 17:12:14 +00:00
char * pszListItems ;
char * pszFilter ;
2002-08-02 10:01:35 +00:00
2004-01-31 19:54:45 +00:00
char * pszValidateText ;
2003-03-23 17:12:14 +00:00
int nMinLength ;
int nMaxLength ;
2004-01-31 19:54:45 +00:00
int nType ;
RECT rect ;
2002-08-02 10:01:35 +00:00
2003-03-23 17:12:14 +00:00
int nFlags ;
2002-08-02 10:01:35 +00:00
2003-03-23 17:12:14 +00:00
HWND hwnd ;
UINT nControlID ;
2002-08-02 10:01:35 +00:00
2003-12-04 22:12:25 +00:00
int nParentIdx ; // this is used to store original windowproc for LINK
2003-07-21 19:48:48 +00:00
HANDLE hImage ; // this is used by image/icon field to save the handle to the image
2005-10-11 16:27:04 +00:00
int nField ; // field number in INI file
char * pszHwndEntry ; // "HWND" or "HWND2"
2007-02-06 20:54:05 +00:00
long wndProc ;
2002-08-02 10:01:35 +00:00
} ;
// initial buffer size. buffers will grow as required.
// use a value larger than MAX_PATH to prevent need for excessive growing.
2004-01-04 14:06:39 +00:00
# define BUFFER_SIZE 8192 // 8kb of mem is max char count in multiedit
2002-08-02 10:01:35 +00:00
char szBrowseButtonCaption [ ] = " ... " ;
HWND hConfigWindow = NULL ;
HWND hMainWindow = NULL ;
2002-11-08 16:51:26 +00:00
HWND hCancelButton = NULL ;
HWND hNextButton = NULL ;
HWND hBackButton = NULL ;
2002-11-15 15:07:09 +00:00
2002-08-02 10:01:35 +00:00
HINSTANCE m_hInstance = NULL ;
2003-06-08 13:41:48 +00:00
struct _stack_t * pFilenameStackEntry = NULL ;
2002-11-10 18:13:35 +00:00
char * pszFilename = NULL ;
char * pszTitle = NULL ;
2002-08-02 10:01:35 +00:00
char * pszCancelButtonText = NULL ;
2002-11-10 18:13:35 +00:00
char * pszNextButtonText = NULL ;
char * pszBackButtonText = NULL ;
2002-08-26 13:27:51 +00:00
2002-11-15 12:53:08 +00:00
int bBackEnabled = FALSE ;
int bCancelEnabled = FALSE ; // by ORTIM: 13-August-2002
int bCancelShow = FALSE ; // by ORTIM: 13-August-2002
2002-08-02 10:01:35 +00:00
2003-09-04 18:25:57 +00:00
int bRTL = FALSE ;
2002-08-02 10:01:35 +00:00
FieldType * pFields = NULL ;
2002-12-06 15:43:35 +00:00
# define DEFAULT_RECT 1018
2002-11-15 15:07:09 +00:00
int nRectId = 0 ;
2002-08-02 10:01:35 +00:00
int nNumFields = 0 ;
int g_done ;
2003-12-04 22:12:25 +00:00
int g_NotifyField ; // Field number of notifying control
2002-08-02 10:01:35 +00:00
2003-11-01 00:17:19 +00:00
int WINAPI FindControlIdx ( UINT id )
2003-07-10 00:28:05 +00:00
{
for ( int nIdx = 0 ; nIdx < nNumFields ; nIdx + + )
if ( id = = pFields [ nIdx ] . nControlID )
return nIdx ;
return - 1 ;
}
2002-08-02 10:01:35 +00:00
2003-12-04 22:12:25 +00:00
LRESULT WINAPI mySendMessage ( HWND hWnd , UINT Msg , WPARAM wParam , LPARAM lParam )
{
return SendMessage ( hWnd , Msg , wParam , lParam ) ;
2002-08-02 10:01:35 +00:00
}
2004-01-04 14:06:39 +00:00
void WINAPI mySetFocus ( HWND hWnd )
{
mySendMessage ( hMainWindow , WM_NEXTDLGCTL , ( WPARAM ) hWnd , TRUE ) ;
}
void WINAPI mySetWindowText ( HWND hWnd , LPCTSTR pszText )
{
if ( pszText )
SetWindowText ( hWnd , pszText ) ;
}
2002-08-02 10:01:35 +00:00
int CALLBACK BrowseCallbackProc ( HWND hwnd , UINT uMsg , LPARAM lp , LPARAM pData ) {
2004-01-04 14:06:39 +00:00
static TCHAR szDir [ MAX_PATH ] ;
2002-08-02 10:01:35 +00:00
2004-01-04 14:06:39 +00:00
if ( uMsg = = BFFM_INITIALIZED & &
GetWindowText ( pFields [ ( int ) pData ] . hwnd , szDir , MAX_PATH ) > 0 )
mySendMessage ( hwnd , BFFM_SETSELECTION , TRUE , ( LPARAM ) szDir ) ;
return 0 ;
2002-08-02 10:01:35 +00:00
}
2004-01-04 14:06:39 +00:00
bool INLINE ValidateFields ( ) {
2002-09-05 22:22:26 +00:00
int nIdx ;
2002-08-02 10:01:35 +00:00
int nLength ;
// In the unlikely event we can't allocate memory, go ahead and return true so we can get out of here.
// May cause problems for the install script, but no memory is problems for us.
for ( nIdx = 0 ; nIdx < nNumFields ; nIdx + + ) {
2003-12-04 22:12:25 +00:00
FieldType * pField = pFields + nIdx ;
2002-09-05 22:22:26 +00:00
// this if statement prevents a stupid bug where a min/max length is assigned to a label control
2003-03-16 09:56:33 +00:00
// where the user obviously has no way of changing what is displayed. (can you say, "infinite loop"?)
2004-01-05 21:53:06 +00:00
if ( pField - > nType > = FIELD_CHECKLEN ) {
2003-12-04 22:12:25 +00:00
nLength = mySendMessage ( pField - > hwnd , WM_GETTEXTLENGTH , 0 , 0 ) ;
2002-08-02 10:01:35 +00:00
2003-12-04 22:12:25 +00:00
if ( ( ( pField - > nMaxLength > 0 ) & & ( nLength > pField - > nMaxLength ) ) | |
( ( pField - > nMinLength > 0 ) & & ( nLength < pField - > nMinLength ) ) ) {
if ( pField - > pszValidateText ) {
2007-02-17 15:24:44 +00:00
char szTitle [ 1024 ] ;
GetWindowText ( hMainWindow , szTitle , sizeof ( szTitle ) ) ;
MessageBox ( hConfigWindow , pField - > pszValidateText , szTitle , MB_OK | MB_ICONWARNING ) ;
2002-08-02 10:01:35 +00:00
}
2004-01-04 14:06:39 +00:00
mySetFocus ( pField - > hwnd ) ;
2002-08-02 10:01:35 +00:00
return false ;
}
}
}
return true ;
}
2003-11-01 00:17:19 +00:00
bool WINAPI SaveSettings ( void ) {
2002-09-10 20:04:54 +00:00
static char szField [ 25 ] ;
2004-01-04 14:06:39 +00:00
int nBufLen = BUFFER_SIZE ;
2002-08-02 10:01:35 +00:00
char * pszBuffer = ( char * ) MALLOC ( nBufLen ) ;
if ( ! pszBuffer ) return false ;
2003-04-18 20:01:23 +00:00
2004-01-04 14:06:39 +00:00
int nIdx ;
int CurrField ;
for ( nIdx = 0 , CurrField = 1 ; nIdx < nNumFields ; nIdx + + , CurrField + + ) {
2003-12-04 22:12:25 +00:00
FieldType * pField = pFields + nIdx ;
HWND hwnd = pField - > hwnd ;
switch ( pField - > nType ) {
case FIELD_BROWSEBUTTON :
if ( g_NotifyField > CurrField )
- - g_NotifyField ;
2004-01-04 14:06:39 +00:00
- - CurrField ;
default :
2003-12-04 22:12:25 +00:00
continue ;
2004-01-04 14:06:39 +00:00
2002-08-02 10:01:35 +00:00
case FIELD_CHECKBOX :
case FIELD_RADIOBUTTON :
2003-12-04 22:12:25 +00:00
wsprintf ( pszBuffer , " %d " , ! ! mySendMessage ( hwnd , BM_GETCHECK , 0 , 0 ) ) ;
break ;
2004-01-04 14:06:39 +00:00
2002-08-02 10:01:35 +00:00
case FIELD_LISTBOX :
2004-01-04 14:06:39 +00:00
{
// Ok, this one requires a bit of work.
// First, we allocate a buffer long enough to hold every item.
// Then, we loop through every item and if it's selected we add it to our buffer.
// If there is already an item in the list, then we prepend a | character before the new item.
// We could simplify for single-select boxes, but using one piece of code saves some space.
int nLength = lstrlen ( pField - > pszListItems ) + 10 ;
if ( nLength > nBufLen ) {
FREE ( pszBuffer ) ;
nBufLen = nLength ;
pszBuffer = ( char * ) MALLOC ( nBufLen ) ;
if ( ! pszBuffer ) return false ;
}
char * pszItem = ( char * ) MALLOC ( nBufLen ) ;
if ( ! pszItem ) return false ;
* pszBuffer = ' \0 ' ;
int nNumItems = mySendMessage ( hwnd , LB_GETCOUNT , 0 , 0 ) ;
for ( int nIdx2 = 0 ; nIdx2 < nNumItems ; nIdx2 + + ) {
if ( mySendMessage ( hwnd , LB_GETSEL , nIdx2 , 0 ) > 0 ) {
if ( * pszBuffer ) lstrcat ( pszBuffer , " | " ) ;
mySendMessage ( hwnd , LB_GETTEXT , ( WPARAM ) nIdx2 , ( LPARAM ) pszItem ) ;
lstrcat ( pszBuffer , pszItem ) ;
2002-08-02 10:01:35 +00:00
}
2004-01-04 14:06:39 +00:00
}
2002-08-02 10:01:35 +00:00
2004-01-04 14:06:39 +00:00
FREE ( pszItem ) ;
break ;
}
case FIELD_TEXT :
case FIELD_FILEREQUEST :
case FIELD_DIRREQUEST :
case FIELD_COMBOBOX :
{
int nLength = mySendMessage ( pField - > hwnd , WM_GETTEXTLENGTH , 0 , 0 ) ;
if ( nLength > nBufLen ) {
FREE ( pszBuffer ) ;
// add a bit extra so we do this less often
nBufLen = nLength + 20 ;
pszBuffer = ( char * ) MALLOC ( nBufLen ) ;
if ( ! pszBuffer ) return false ;
2002-08-02 10:01:35 +00:00
}
2004-01-04 14:06:39 +00:00
* pszBuffer = ' " ' ;
GetWindowText ( hwnd , pszBuffer + 1 , nBufLen - 1 ) ;
pszBuffer [ nLength + 1 ] = ' " ' ;
pszBuffer [ nLength + 2 ] = ' \0 ' ;
2004-01-31 19:54:45 +00:00
if ( pField - > nType = = FIELD_TEXT & & ( pField - > nFlags & FLAG_MULTILINE ) )
2002-08-02 10:01:35 +00:00
{
2004-01-04 14:06:39 +00:00
char * pszBuf2 = ( char * ) MALLOC ( nBufLen * 2 ) ; // double the size, consider the worst case, all chars are \r\n
char * p1 , * p2 ;
2004-01-31 19:54:45 +00:00
for ( p1 = pszBuffer , p2 = pszBuf2 ; * p1 ; p1 = CharNext ( p1 ) , p2 = CharNext ( p2 ) )
{
2004-01-04 14:06:39 +00:00
switch ( * p1 ) {
case ' \t ' :
2004-01-31 19:54:45 +00:00
* ( LPWORD ) p2 = CHAR2_TO_WORD ( ' \\ ' , ' t ' ) ;
p2 + + ;
2004-01-04 14:06:39 +00:00
break ;
case ' \n ' :
2004-01-31 19:54:45 +00:00
* ( LPWORD ) p2 = CHAR2_TO_WORD ( ' \\ ' , ' n ' ) ;
p2 + + ;
2004-01-04 14:06:39 +00:00
break ;
case ' \r ' :
2004-01-31 19:54:45 +00:00
* ( LPWORD ) p2 = CHAR2_TO_WORD ( ' \\ ' , ' r ' ) ;
p2 + + ;
2004-01-04 14:06:39 +00:00
break ;
case ' \\ ' :
* p2 + + = ' \\ ' ;
default :
2004-01-31 19:54:45 +00:00
lstrcpyn ( p2 , p1 , CharNext ( p1 ) - p1 + 1 ) ;
break ;
2003-06-10 13:18:07 +00:00
}
}
2004-01-04 14:06:39 +00:00
* p2 = 0 ;
nBufLen = nBufLen * 2 ;
FREE ( pszBuffer ) ;
pszBuffer = pszBuf2 ;
2002-08-02 10:01:35 +00:00
}
2004-01-04 14:06:39 +00:00
break ;
}
2002-09-05 22:22:26 +00:00
}
2003-12-04 22:12:25 +00:00
wsprintf ( szField , " Field %d " , CurrField ) ;
WritePrivateProfileString ( szField , " State " , pszBuffer , pszFilename ) ;
2002-08-02 10:01:35 +00:00
}
2003-12-04 22:12:25 +00:00
// Tell NSIS which control was activated, if any
wsprintf ( pszBuffer , " %d " , g_NotifyField ) ;
WritePrivateProfileString ( " Settings " , " State " , pszBuffer , pszFilename ) ;
2002-08-02 10:01:35 +00:00
FREE ( pszBuffer ) ;
return true ;
}
2003-03-17 13:46:13 +00:00
# define BROWSE_WIDTH 15
2003-07-29 20:25:42 +00:00
2003-09-28 15:24:55 +00:00
static char szResult [ BUFFER_SIZE ] ;
2004-01-31 19:54:45 +00:00
char * pszAppName ;
2002-09-26 22:47:21 +00:00
2004-01-31 19:54:45 +00:00
DWORD WINAPI myGetProfileString ( LPCTSTR lpKeyName )
2002-09-26 22:47:21 +00:00
{
* szResult = ' \0 ' ;
2004-01-31 19:54:45 +00:00
return GetPrivateProfileString ( pszAppName , lpKeyName , " " , szResult , BUFFER_SIZE , pszFilename ) ;
2002-09-26 22:47:21 +00:00
}
2004-01-31 19:54:45 +00:00
char * WINAPI myGetProfileStringDup ( LPCTSTR lpKeyName )
2002-09-26 22:47:21 +00:00
{
2004-01-31 19:54:45 +00:00
int nSize = myGetProfileString ( lpKeyName ) ;
if ( nSize )
2002-09-26 22:47:21 +00:00
return strdup ( szResult ) ;
else
return NULL ;
}
2004-01-31 19:54:45 +00:00
UINT WINAPI myGetProfileInt ( LPCTSTR lpKeyName , INT nDefault )
2003-09-28 15:24:55 +00:00
{
2004-01-31 19:54:45 +00:00
return GetPrivateProfileInt ( pszAppName , lpKeyName , nDefault , pszFilename ) ;
2003-09-28 15:24:55 +00:00
}
2003-11-01 00:17:19 +00:00
int WINAPI ReadSettings ( void ) {
2002-09-10 20:04:54 +00:00
static char szField [ 25 ] ;
2003-07-21 19:48:48 +00:00
int nIdx , nCtrlIdx ;
2002-08-02 10:01:35 +00:00
2004-01-31 19:54:45 +00:00
pszAppName = " Settings " ;
pszTitle = myGetProfileStringDup ( " Title " ) ;
pszCancelButtonText = myGetProfileStringDup ( " CancelButtonText " ) ;
pszNextButtonText = myGetProfileStringDup ( " NextButtonText " ) ;
pszBackButtonText = myGetProfileStringDup ( " BackButtonText " ) ;
2002-08-02 10:01:35 +00:00
2004-01-31 19:54:45 +00:00
nNumFields = myGetProfileInt ( " NumFields " , 0 ) ;
2002-08-26 13:27:51 +00:00
2004-01-31 19:54:45 +00:00
nRectId = myGetProfileInt ( " Rect " , DEFAULT_RECT ) ;
2002-11-15 15:07:09 +00:00
2004-01-31 19:54:45 +00:00
bBackEnabled = myGetProfileInt ( " BackEnabled " , - 1 ) ;
2002-11-15 12:53:08 +00:00
// by ORTIM: 13-August-2002
2004-01-31 19:54:45 +00:00
bCancelEnabled = myGetProfileInt ( " CancelEnabled " , - 1 ) ;
bCancelShow = myGetProfileInt ( " CancelShow " , - 1 ) ;
2002-09-05 22:22:26 +00:00
2004-01-31 19:54:45 +00:00
bRTL = myGetProfileInt ( " RTL " , 0 ) ;
2003-09-04 18:25:57 +00:00
2002-08-02 10:01:35 +00:00
if ( nNumFields > 0 ) {
// make this twice as large for the worst case that every control is a browse button.
// the structure is small enough that this won't waste much memory.
// if the structure gets much larger, we should switch to a linked list.
pFields = ( FieldType * ) MALLOC ( sizeof ( FieldType ) * 2 * nNumFields ) ;
}
2003-12-04 22:12:25 +00:00
for ( nIdx = 0 , nCtrlIdx = 0 ; nCtrlIdx < nNumFields ; nCtrlIdx + + , nIdx + + ) {
2002-09-05 22:22:26 +00:00
// Control types
static TableEntry TypeTable [ ] = {
{ " LABEL " , FIELD_LABEL } ,
{ " TEXT " , FIELD_TEXT } ,
{ " PASSWORD " , FIELD_TEXT } ,
{ " LISTBOX " , FIELD_LISTBOX } ,
{ " COMBOBOX " , FIELD_COMBOBOX } ,
{ " DROPLIST " , FIELD_COMBOBOX } ,
{ " FILEREQUEST " , FIELD_FILEREQUEST } ,
{ " DIRREQUEST " , FIELD_DIRREQUEST } ,
{ " CHECKBOX " , FIELD_CHECKBOX } ,
{ " RADIOBUTTON " , FIELD_RADIOBUTTON } ,
{ " ICON " , FIELD_ICON } ,
{ " BITMAP " , FIELD_BITMAP } ,
2002-12-21 11:24:42 +00:00
{ " GROUPBOX " , FIELD_GROUPBOX } ,
2003-07-05 16:55:54 +00:00
# ifdef IO_ENABLE_LINK
2003-06-16 18:49:23 +00:00
{ " LINK " , FIELD_LINK } ,
2003-07-05 16:55:54 +00:00
# else
{ " LINK " , FIELD_LABEL } ,
# endif
2003-12-04 22:12:25 +00:00
{ " BUTTON " , FIELD_BUTTON } ,
2002-09-05 22:22:26 +00:00
{ NULL , 0 }
} ;
// Control flags
static TableEntry FlagTable [ ] = {
2004-01-04 14:06:39 +00:00
{ " NOTIFY " , LBS_NOTIFY } ,
2003-12-04 22:12:25 +00:00
{ " WARN_IF_EXIST " , OFN_OVERWRITEPROMPT } ,
2002-09-05 22:22:26 +00:00
{ " FILE_HIDEREADONLY " , OFN_HIDEREADONLY } ,
2004-01-04 14:06:39 +00:00
{ " MULTISELECT " , LBS_MULTIPLESEL } ,
{ " READONLY " , FLAG_READONLY } ,
{ " RIGHT " , BS_LEFTTEXT } ,
2003-12-04 22:12:25 +00:00
{ " PASSWORD " , FLAG_PASSWORD } ,
2003-05-30 13:35:47 +00:00
{ " ONLY_NUMBERS " , FLAG_ONLYNUMBERS } ,
2003-06-10 13:18:07 +00:00
{ " MULTILINE " , FLAG_MULTILINE } ,
2004-01-04 14:06:39 +00:00
{ " NOWORDWRAP " , FLAG_NOWORDWRAP } ,
{ " WANTRETURN " , FLAG_WANTRETURN } ,
{ " EXTENDEDSELCT " , LBS_EXTENDEDSEL } ,
2003-12-04 22:12:25 +00:00
{ " PATH_MUST_EXIST " , OFN_PATHMUSTEXIST } ,
2004-01-04 14:06:39 +00:00
{ " FILE_MUST_EXIST " , OFN_FILEMUSTEXIST } ,
2003-12-04 22:12:25 +00:00
{ " PROMPT_CREATE " , OFN_CREATEPROMPT } ,
{ " DROPLIST " , FLAG_DROPLIST } ,
{ " RESIZETOFIT " , FLAG_RESIZETOFIT } ,
2004-01-04 14:06:39 +00:00
{ " NOTABSTOP " , WS_TABSTOP } ,
{ " GROUP " , WS_GROUP } ,
2003-12-04 22:12:25 +00:00
{ " REQ_SAVE " , FLAG_SAVEAS } ,
{ " FILE_EXPLORER " , OFN_EXPLORER } ,
2004-01-04 14:06:39 +00:00
{ " HSCROLL " , WS_HSCROLL } ,
{ " VSCROLL " , WS_VSCROLL } ,
{ " DISABLED " , WS_DISABLED } ,
2005-01-21 19:12:47 +00:00
{ " TRANSPARENT " , TRANSPARENT_BMP } ,
2007-01-23 17:33:31 +00:00
{ " FOCUS " , FLAG_FOCUS } ,
2002-09-05 22:22:26 +00:00
{ NULL , 0 }
} ;
2003-12-04 22:12:25 +00:00
FieldType * pField = pFields + nIdx ;
2002-08-02 10:01:35 +00:00
2005-10-11 16:27:04 +00:00
pField - > nField = nCtrlIdx + 1 ;
pField - > pszHwndEntry = " HWND " ;
2003-07-21 19:48:48 +00:00
wsprintf ( szField , " Field %d " , nCtrlIdx + 1 ) ;
2004-01-31 19:54:45 +00:00
pszAppName = szField ;
2002-09-05 22:22:26 +00:00
// Get the control type
2004-01-31 19:54:45 +00:00
myGetProfileString ( " TYPE " ) ;
2003-12-04 22:12:25 +00:00
pField - > nType = LookupToken ( TypeTable , szResult ) ;
if ( pField - > nType = = FIELD_INVALID )
2002-08-02 10:01:35 +00:00
continue ;
2002-09-05 22:22:26 +00:00
// Lookup flags associated with the control type
2004-01-04 14:06:39 +00:00
pField - > nFlags = LookupToken ( FlagTable , szResult ) ;
2004-01-31 19:54:45 +00:00
myGetProfileString ( " Flags " ) ;
2004-01-04 14:06:39 +00:00
pField - > nFlags | = LookupTokens ( FlagTable , szResult ) ;
2002-09-26 22:47:21 +00:00
2003-08-05 15:30:31 +00:00
// pszState must not be NULL!
2004-01-31 19:54:45 +00:00
myGetProfileString ( " State " ) ;
2003-12-04 22:12:25 +00:00
pField - > pszState = strdup ( szResult ) ;
2002-08-02 10:01:35 +00:00
2004-01-04 14:06:39 +00:00
// ListBox items list
2002-09-26 22:47:21 +00:00
{
2004-01-31 19:54:45 +00:00
int nResult = myGetProfileString ( " ListItems " ) ;
2002-09-26 22:47:21 +00:00
if ( nResult ) {
// add an extra | character to the end to simplify the loop where we add the items.
2003-12-04 22:12:25 +00:00
pField - > pszListItems = ( char * ) MALLOC ( nResult + 2 ) ;
strcpy ( pField - > pszListItems , szResult ) ;
pField - > pszListItems [ nResult ] = ' | ' ;
pField - > pszListItems [ nResult + 1 ] = ' \0 ' ;
2002-09-26 22:47:21 +00:00
}
2002-09-05 22:22:26 +00:00
}
2002-08-02 10:01:35 +00:00
2004-01-04 14:06:39 +00:00
// Label Text - convert newline
2004-01-31 19:54:45 +00:00
pField - > pszText = myGetProfileStringDup ( " TEXT " ) ;
2004-01-04 14:06:39 +00:00
if ( pField - > nType = = FIELD_LABEL )
ConvertNewLines ( pField - > pszText ) ;
2003-09-28 15:24:55 +00:00
2004-01-04 14:06:39 +00:00
// Dir request - root folder
2004-01-31 19:54:45 +00:00
pField - > pszRoot = myGetProfileStringDup ( " ROOT " ) ;
2003-09-28 15:24:55 +00:00
2004-01-04 14:06:39 +00:00
// ValidateText - convert newline
2004-01-31 19:54:45 +00:00
pField - > pszValidateText = myGetProfileStringDup ( " ValidateText " ) ;
2004-01-04 14:06:39 +00:00
ConvertNewLines ( pField - > pszValidateText ) ;
2002-08-02 10:01:35 +00:00
2002-09-26 22:47:21 +00:00
{
int nResult = GetPrivateProfileString ( szField , " Filter " , " All Files|*.* " , szResult , sizeof ( szResult ) , pszFilename ) ;
if ( nResult ) {
2004-01-04 14:06:39 +00:00
// Convert the filter to the format required by Windows: NULL after each
// item followed by a terminating NULL
2003-12-04 22:12:25 +00:00
pField - > pszFilter = ( char * ) MALLOC ( nResult + 2 ) ;
strcpy ( pField - > pszFilter , szResult ) ;
char * pszPos = pField - > pszFilter ;
2004-01-31 19:54:45 +00:00
while ( * pszPos )
{
if ( * pszPos = = ' | ' )
* pszPos + + = 0 ;
else
pszPos = CharNext ( pszPos ) ;
2002-09-26 22:47:21 +00:00
}
2002-09-05 22:22:26 +00:00
}
}
2002-08-02 10:01:35 +00:00
2004-01-31 19:54:45 +00:00
pField - > rect . left = myGetProfileInt ( " LEFT " , 0 ) ;
pField - > rect . top = myGetProfileInt ( " TOP " , 0 ) ;
pField - > rect . right = myGetProfileInt ( " RIGHT " , 0 ) ;
pField - > rect . bottom = myGetProfileInt ( " BOTTOM " , 0 ) ;
pField - > nMinLength = myGetProfileInt ( " MinLen " , 0 ) ;
pField - > nMaxLength = myGetProfileInt ( " MaxLen " , 0 ) ;
2002-08-02 10:01:35 +00:00
2003-07-19 00:42:13 +00:00
// Text color for LINK control, default is pure blue
2004-01-31 19:54:45 +00:00
pField - > hImage = ( HANDLE ) myGetProfileInt ( " TxtColor " , RGB ( 0 , 0 , 255 ) ) ;
2003-07-19 00:42:13 +00:00
2003-12-04 22:12:25 +00:00
pField - > nControlID = 1200 + nIdx ;
if ( pField - > nType = = FIELD_FILEREQUEST | | pField - > nType = = FIELD_DIRREQUEST )
2003-07-21 19:48:48 +00:00
{
2003-09-04 18:25:57 +00:00
FieldType * pNewField = & pFields [ nIdx + 1 ] ;
pNewField - > nControlID = 1200 + nIdx + 1 ;
pNewField - > nType = FIELD_BROWSEBUTTON ;
2004-01-04 14:06:39 +00:00
pNewField - > nFlags = pField - > nFlags & ( WS_DISABLED | WS_TABSTOP ) ;
2003-09-04 18:25:57 +00:00
pNewField - > pszText = STRDUP ( szBrowseButtonCaption ) ; // needed for generic FREE
2003-12-04 22:12:25 +00:00
pNewField - > rect . right = pField - > rect . right ;
2003-09-04 18:25:57 +00:00
pNewField - > rect . left = pNewField - > rect . right - BROWSE_WIDTH ;
2003-12-04 22:12:25 +00:00
pNewField - > rect . bottom = pField - > rect . bottom ;
pNewField - > rect . top = pField - > rect . top ;
pField - > rect . right = pNewField - > rect . left - 3 ;
2005-10-11 16:27:04 +00:00
pNewField - > nField = nCtrlIdx + 1 ;
pNewField - > pszHwndEntry = " HWND2 " ;
2003-09-04 18:25:57 +00:00
nNumFields + + ;
nIdx + + ;
2003-07-21 19:48:48 +00:00
}
2002-08-02 10:01:35 +00:00
}
2003-08-05 15:05:49 +00:00
return nNumFields ;
2002-08-02 10:01:35 +00:00
}
2003-11-01 00:17:19 +00:00
LRESULT WINAPI WMCommandProc ( HWND hWnd , UINT id , HWND hwndCtl , UINT codeNotify ) {
2007-01-19 19:26:04 +00:00
int nIdx = FindControlIdx ( id ) ;
// Ignore if the dialog is in the process of being created
if ( g_done | | nIdx < 0 )
return 0 ;
2007-02-06 20:58:44 +00:00
switch ( pFields [ nIdx ] . nType )
2007-01-19 19:26:04 +00:00
{
2007-02-06 20:54:05 +00:00
case FIELD_BROWSEBUTTON :
2007-02-06 20:58:44 +00:00
- - nIdx ;
2007-02-06 20:54:05 +00:00
case FIELD_LINK :
case FIELD_BUTTON :
case FIELD_CHECKBOX :
case FIELD_RADIOBUTTON :
if ( codeNotify ! = BN_CLICKED )
return 0 ;
break ;
case FIELD_COMBOBOX :
case FIELD_LISTBOX :
if ( codeNotify ! = LBN_SELCHANGE ) // LBN_SELCHANGE == CBN_SELCHANGE
return 0 ;
break ;
default :
2007-01-19 19:26:04 +00:00
return 0 ;
}
2007-02-06 20:58:44 +00:00
FieldType * pField = pFields + nIdx ;
2007-01-19 19:26:04 +00:00
char szBrowsePath [ MAX_PATH ] ;
switch ( pField - > nType ) {
case FIELD_FILEREQUEST : {
OPENFILENAME ofn = { 0 , } ;
ofn . lStructSize = sizeof ( ofn ) ;
ofn . hwndOwner = hConfigWindow ;
ofn . lpstrFilter = pField - > pszFilter ;
ofn . lpstrFile = szBrowsePath ;
ofn . nMaxFile = sizeof ( szBrowsePath ) ;
ofn . Flags = pField - > nFlags & ( OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_CREATEPROMPT | OFN_EXPLORER ) ;
GetWindowText ( pField - > hwnd , szBrowsePath , sizeof ( szBrowsePath ) ) ;
tryagain :
GetCurrentDirectory ( BUFFER_SIZE , szResult ) ; // save working dir
if ( ( pField - > nFlags & FLAG_SAVEAS ) ? GetSaveFileName ( & ofn ) : GetOpenFileName ( & ofn ) ) {
mySetWindowText ( pField - > hwnd , szBrowsePath ) ;
SetCurrentDirectory ( szResult ) ; // restore working dir
// OFN_NOCHANGEDIR doesn't always work (see MSDN)
2003-12-04 22:12:25 +00:00
break ;
2007-01-19 19:26:04 +00:00
}
else if ( szBrowsePath [ 0 ] & & CommDlgExtendedError ( ) = = FNERR_INVALIDFILENAME ) {
szBrowsePath [ 0 ] = ' \0 ' ;
goto tryagain ;
}
2003-12-04 22:12:25 +00:00
2007-01-19 19:26:04 +00:00
break ;
}
2003-12-04 22:12:25 +00:00
2007-01-19 19:26:04 +00:00
case FIELD_DIRREQUEST : {
BROWSEINFO bi ;
2003-12-04 22:12:25 +00:00
2007-01-19 19:26:04 +00:00
bi . hwndOwner = hConfigWindow ;
bi . pidlRoot = NULL ;
bi . pszDisplayName = szBrowsePath ;
bi . lpszTitle = pField - > pszText ;
2003-12-04 22:12:25 +00:00
# ifndef BIF_NEWDIALOGSTYLE
# define BIF_NEWDIALOGSTYLE 0x0040
# endif
2007-01-19 19:26:04 +00:00
bi . ulFlags = BIF_STATUSTEXT | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE ;
bi . lpfn = BrowseCallbackProc ;
bi . lParam = nIdx ;
bi . iImage = 0 ;
if ( pField - > pszRoot ) {
LPSHELLFOLDER sf ;
ULONG eaten ;
LPITEMIDLIST root ;
int ccRoot = ( lstrlen ( pField - > pszRoot ) * 2 ) + 2 ;
LPWSTR pwszRoot = ( LPWSTR ) MALLOC ( ccRoot ) ;
MultiByteToWideChar ( CP_ACP , 0 , pField - > pszRoot , - 1 , pwszRoot , ccRoot ) ;
SHGetDesktopFolder ( & sf ) ;
sf - > ParseDisplayName ( hConfigWindow , NULL , pwszRoot , & eaten , & root , NULL ) ;
bi . pidlRoot = root ;
sf - > Release ( ) ;
FREE ( pwszRoot ) ;
}
//CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
LPITEMIDLIST pResult = SHBrowseForFolder ( & bi ) ;
if ( ! pResult )
break ;
2003-12-04 22:12:25 +00:00
2007-01-19 19:26:04 +00:00
if ( SHGetPathFromIDList ( pResult , szBrowsePath ) ) {
mySetWindowText ( pField - > hwnd , szBrowsePath ) ;
2003-12-04 22:12:25 +00:00
}
2007-01-19 19:26:04 +00:00
LPMALLOC pMalloc ;
if ( ! SHGetMalloc ( & pMalloc ) ) {
pMalloc - > Free ( pResult ) ;
2002-08-02 10:01:35 +00:00
}
2007-01-19 19:26:04 +00:00
break ;
2003-12-04 22:12:25 +00:00
}
2007-01-19 19:26:04 +00:00
case FIELD_LINK :
case FIELD_BUTTON :
// Allow the state to be empty - this might be useful in conjunction
// with the NOTIFY flag
if ( * pField - > pszState )
ShellExecute ( hMainWindow , NULL , pField - > pszState , NULL , NULL , SW_SHOWDEFAULT ) ;
break ;
}
if ( pField - > nFlags & LBS_NOTIFY ) {
// Remember which control was activated then pretend the user clicked Next
g_NotifyField = nIdx + 1 ;
mySendMessage ( hMainWindow , WM_NOTIFY_OUTER_NEXT , 1 , 0 ) ;
2003-12-06 20:45:35 +00:00
}
2007-01-19 19:26:04 +00:00
2003-12-06 20:45:35 +00:00
return 0 ;
2002-08-02 10:01:35 +00:00
}
static void * lpWndProcOld ;
2003-03-18 15:45:25 +00:00
int g_is_cancel , g_is_back ;
BOOL CALLBACK ParentWndProc ( HWND hwnd , UINT message , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
2003-03-18 15:45:25 +00:00
BOOL bRes ;
if ( message = = WM_NOTIFY_OUTER_NEXT & & wParam = = 1 )
2003-04-18 20:01:23 +00:00
{
2003-12-08 14:06:24 +00:00
// Don't call leave function if fields aren't valid
2003-12-13 17:17:03 +00:00
if ( ! g_NotifyField & & ! ValidateFields ( ) )
2003-12-08 14:06:24 +00:00
return 0 ;
2003-03-18 15:45:25 +00:00
// Get the settings ready for the leave function verification
SaveSettings ( ) ;
2003-12-08 14:06:24 +00:00
// Reset the record of activated control
g_NotifyField = 0 ;
2003-04-18 20:01:23 +00:00
}
2003-03-18 15:45:25 +00:00
bRes = CallWindowProc ( ( long ( __stdcall * ) ( struct HWND__ * , unsigned int , unsigned int , long ) ) lpWndProcOld , hwnd , message , wParam , lParam ) ;
if ( message = = WM_NOTIFY_OUTER_NEXT & & ! bRes )
2002-09-26 22:47:21 +00:00
{
2003-12-08 14:06:24 +00:00
// if leave function didn't abort (bRes != 0 in that case)
2007-03-11 15:58:46 +00:00
if ( wParam = = ( WPARAM ) - 1 )
2003-12-08 14:06:24 +00:00
g_is_back + + ;
if ( wParam = = NOTIFY_BYE_BYE )
g_is_cancel + + ;
g_done + + ;
PostMessage ( hConfigWindow , WM_CLOSE , 0 , 0 ) ;
2002-09-26 22:47:21 +00:00
}
2003-03-18 15:45:25 +00:00
return bRes ;
2002-08-02 10:01:35 +00:00
}
2003-12-06 20:45:35 +00:00
BOOL CALLBACK cfgDlgProc ( HWND hwndDlg , UINT uMsg , WPARAM wParam , LPARAM lParam )
2002-08-02 10:01:35 +00:00
{
switch ( uMsg )
{
2002-09-05 22:22:26 +00:00
HANDLE_MSG ( hwndDlg , WM_COMMAND , WMCommandProc ) ;
2003-07-07 21:08:26 +00:00
case WM_DRAWITEM :
{
2003-12-06 20:45:35 +00:00
DRAWITEMSTRUCT * lpdis = ( DRAWITEMSTRUCT * ) lParam ;
int nIdx = FindControlIdx ( lpdis - > CtlID ) ;
2003-07-07 21:08:26 +00:00
# ifdef IO_LINK_UNDERLINED
2003-12-06 20:45:35 +00:00
HFONT OldFont ;
LOGFONT lf ;
2003-07-07 21:08:26 +00:00
# endif
2003-09-07 14:36:03 +00:00
2003-12-06 20:45:35 +00:00
if ( nIdx < 0 )
break ;
FieldType * pField = pFields + nIdx ;
2003-09-07 14:36:03 +00:00
2003-07-07 21:08:26 +00:00
# ifdef IO_LINK_UNDERLINED
2003-12-06 20:45:35 +00:00
GetObject ( GetCurrentObject ( lpdis - > hDC , OBJ_FONT ) , sizeof ( lf ) , & lf ) ;
lf . lfUnderline = TRUE ;
OldFont = ( HFONT ) SelectObject ( lpdis - > hDC , CreateFontIndirect ( & lf ) ) ;
2003-07-07 21:08:26 +00:00
# endif
2003-12-06 20:45:35 +00:00
// We need lpdis->rcItem later
RECT rc = lpdis - > rcItem ;
// Calculate needed size of the control
DrawText ( lpdis - > hDC , pField - > pszText , - 1 , & rc , DT_VCENTER | DT_SINGLELINE | DT_CALCRECT ) ;
2003-12-13 17:17:03 +00:00
2004-01-04 14:06:39 +00:00
// Make some more room so the focus rect won't cut letters off
rc . right = min ( rc . right + 2 , lpdis - > rcItem . right ) ;
2003-12-06 20:45:35 +00:00
// Move rect to right if in RTL mode
if ( bRTL )
{
rc . left + = lpdis - > rcItem . right - rc . right ;
rc . right + = lpdis - > rcItem . right - rc . right ;
}
2004-01-04 14:06:39 +00:00
if ( lpdis - > itemAction & ODA_DRAWENTIRE )
{
// Get TxtColor unless the user has set another using SetCtlColors
if ( ! GetWindowLong ( lpdis - > hwndItem , GWL_USERDATA ) )
SetTextColor ( lpdis - > hDC , ( COLORREF ) pField - > hImage ) ;
2003-12-06 20:45:35 +00:00
2004-01-04 14:06:39 +00:00
// Draw the text
DrawText ( lpdis - > hDC , pField - > pszText , - 1 , & rc , DT_CENTER | DT_VCENTER | DT_SINGLELINE | ( bRTL ? DT_RTLREADING : 0 ) ) ;
}
2003-12-06 20:45:35 +00:00
// Draw the focus rect if needed
2004-01-04 14:06:39 +00:00
if ( ( ( lpdis - > itemState & ODS_FOCUS ) & & ( lpdis - > itemAction & ODA_DRAWENTIRE ) ) | | ( lpdis - > itemAction & ODA_FOCUS ) )
2003-12-06 20:45:35 +00:00
{
2004-01-04 14:06:39 +00:00
// NB: when not in DRAWENTIRE mode, this will actually toggle the focus
// rectangle since it's drawn in a XOR way
2003-12-06 20:45:35 +00:00
DrawFocusRect ( lpdis - > hDC , & rc ) ;
}
2003-12-23 16:29:16 +00:00
pField - > rect = rc ;
2003-07-07 21:08:26 +00:00
# ifdef IO_LINK_UNDERLINED
2003-12-06 20:45:35 +00:00
DeleteObject ( SelectObject ( lpdis - > hDC , OldFont ) ) ;
2003-07-07 21:08:26 +00:00
# endif
2003-12-06 20:45:35 +00:00
break ;
2003-07-07 21:08:26 +00:00
}
2002-11-01 20:34:55 +00:00
case WM_CTLCOLORSTATIC :
2003-03-20 20:49:13 +00:00
case WM_CTLCOLOREDIT :
2002-11-15 15:07:09 +00:00
case WM_CTLCOLORDLG :
2003-03-20 20:49:13 +00:00
case WM_CTLCOLORBTN :
case WM_CTLCOLORLISTBOX :
2003-12-29 14:27:33 +00:00
// let the NSIS window handle colors, it knows best
2004-01-04 14:06:39 +00:00
return mySendMessage ( hMainWindow , uMsg , wParam , lParam ) ;
2002-08-02 10:01:35 +00:00
}
2003-12-06 20:45:35 +00:00
return 0 ;
2002-08-02 10:01:35 +00:00
}
2003-07-05 16:55:54 +00:00
# ifdef IO_ENABLE_LINK
2003-12-21 21:00:37 +00:00
# ifndef IDC_HAND
# define IDC_HAND MAKEINTRESOURCE(32649)
# endif
2004-01-04 14:06:39 +00:00
# ifndef BS_TYPEMASK
# define BS_TYPEMASK 0x0000000FL
# endif
2003-06-16 18:49:23 +00:00
// pFields[nIdx].nParentIdx is used to store original windowproc
2005-07-22 18:47:44 +00:00
int WINAPI StaticLINKWindowProc ( HWND hWin , UINT uMsg , WPARAM wParam , LPARAM lParam )
2003-06-16 18:49:23 +00:00
{
2004-01-04 14:06:39 +00:00
int StaticField = FindControlIdx ( GetDlgCtrlID ( hWin ) ) ;
2003-09-07 14:36:03 +00:00
if ( StaticField < 0 )
return 0 ;
2003-12-04 22:12:25 +00:00
FieldType * pField = pFields + StaticField ;
2003-09-07 14:36:03 +00:00
2003-07-10 00:28:05 +00:00
switch ( uMsg )
2003-06-16 18:49:23 +00:00
{
2004-01-04 14:06:39 +00:00
case WM_GETDLGCODE :
// Pretend we are a normal button/default button as appropriate
return DLGC_BUTTON | ( ( pField - > nFlags & FLAG_WANTRETURN ) ? DLGC_DEFPUSHBUTTON : DLGC_UNDEFPUSHBUTTON ) ;
case BM_SETSTYLE :
// Detect when we are becoming the default button but don't lose the owner-draw style
if ( ( wParam & BS_TYPEMASK ) = = BS_DEFPUSHBUTTON )
pField - > nFlags | = FLAG_WANTRETURN ; // Hijack this flag to indicate default button status
else
pField - > nFlags & = ~ FLAG_WANTRETURN ;
wParam = ( wParam & ~ BS_TYPEMASK ) | BS_OWNERDRAW ;
break ;
case WM_NCHITTEST :
2003-06-16 18:49:23 +00:00
{
2003-12-23 16:29:16 +00:00
POINT pt = { GET_X_LPARAM ( lParam ) , GET_Y_LPARAM ( lParam ) } ;
2004-01-04 14:06:39 +00:00
MapWindowPoints ( 0 , hWin , & pt , 1 ) ;
2003-12-23 16:29:16 +00:00
if ( PtInRect ( & pField - > rect , pt ) )
return HTCLIENT ;
else
return HTNOWHERE ;
2003-07-10 00:28:05 +00:00
}
2004-01-04 14:06:39 +00:00
case WM_SETCURSOR :
2003-07-10 00:28:05 +00:00
{
2003-12-23 16:29:16 +00:00
if ( ( HWND ) wParam = = hWin & & LOWORD ( lParam ) = = HTCLIENT )
2003-06-16 18:49:23 +00:00
{
2003-07-10 00:28:05 +00:00
HCURSOR hCur = LoadCursor ( NULL , IDC_HAND ) ;
2003-12-23 16:29:16 +00:00
if ( hCur )
2003-06-16 18:49:23 +00:00
{
2003-07-10 00:28:05 +00:00
SetCursor ( hCur ) ;
return 1 ; // halt further processing
2003-06-16 18:49:23 +00:00
}
}
}
}
2003-12-04 22:12:25 +00:00
return CallWindowProc ( ( WNDPROC ) pField - > nParentIdx , hWin , uMsg , wParam , lParam ) ;
2003-06-16 18:49:23 +00:00
}
2003-07-05 16:55:54 +00:00
# endif
2003-06-16 18:49:23 +00:00
2007-02-06 20:54:05 +00:00
int WINAPI NumbersOnlyPasteWndProc ( HWND hWin , UINT uMsg , WPARAM wParam , LPARAM lParam )
{
int nIdx = FindControlIdx ( GetDlgCtrlID ( hWin ) ) ;
if ( nIdx < 0 )
return 0 ;
FieldType * pField = pFields + nIdx ;
if ( uMsg = = WM_PASTE )
{
if ( OpenClipboard ( hWin ) )
{
HGLOBAL hData = GetClipboardData ( CF_TEXT ) ;
if ( hData )
{
char * lpData = ( char * ) GlobalLock ( hData ) ;
if ( lpData )
{
int iLen = lstrlen ( lpData ) ;
char * lpFilteredData = ( char * ) MALLOC ( iLen + 1 ) ;
if ( lpFilteredData )
{
for ( int i = 0 , j = 0 ; i < iLen ; i + + )
{
if ( lpData [ i ] > = ' 0 ' & & lpData [ i ] < = ' 9 ' )
{
lpFilteredData [ j ] = lpData [ i ] ;
j + + ;
}
2007-02-17 09:12:15 +00:00
lpFilteredData [ j ] = 0 ;
2007-02-06 20:54:05 +00:00
}
SendMessage ( hWin , EM_REPLACESEL , TRUE , ( LPARAM ) lpFilteredData ) ;
FREE ( lpFilteredData ) ;
}
GlobalUnlock ( hData ) ;
}
}
CloseClipboard ( ) ;
return 0 ;
}
}
return CallWindowProc ( ( WNDPROC ) pField - > wndProc , hWin , uMsg , wParam , lParam ) ;
}
2002-11-01 20:34:55 +00:00
int old_cancel_visible ;
2003-11-01 00:17:19 +00:00
int WINAPI createCfgDlg ( )
2002-08-02 10:01:35 +00:00
{
2002-11-01 20:34:55 +00:00
g_is_back = 0 ;
g_is_cancel = 0 ;
2003-12-04 22:12:25 +00:00
HWND mainwnd = hMainWindow ;
if ( ! mainwnd )
2002-08-02 10:01:35 +00:00
{
popstring ( NULL ) ;
pushstring ( " error finding mainwnd " ) ;
2002-11-01 20:34:55 +00:00
return 1 ; // cannot be used in silent mode unfortunately.
2002-08-02 10:01:35 +00:00
}
2002-11-15 15:07:09 +00:00
if ( ! g_stacktop | | ! * g_stacktop | | ! ( pszFilename = ( * g_stacktop ) - > text ) | | ! pszFilename [ 0 ] | | ! ReadSettings ( ) )
2002-08-02 10:01:35 +00:00
{
popstring ( NULL ) ;
2002-11-15 15:07:09 +00:00
pushstring ( " error finding config " ) ;
2002-11-01 20:34:55 +00:00
return 1 ;
2002-08-02 10:01:35 +00:00
}
2003-12-04 22:12:25 +00:00
HWND childwnd = GetDlgItem ( mainwnd , nRectId ) ;
2002-11-15 15:07:09 +00:00
if ( ! childwnd )
2002-08-02 10:01:35 +00:00
{
popstring ( NULL ) ;
2002-11-15 15:07:09 +00:00
pushstring ( " error finding childwnd " ) ;
2002-11-01 20:34:55 +00:00
return 1 ;
2002-08-02 10:01:35 +00:00
}
2002-11-15 15:07:09 +00:00
2003-12-04 22:12:25 +00:00
hCancelButton = GetDlgItem ( mainwnd , IDCANCEL ) ;
2004-01-04 14:06:39 +00:00
hNextButton = GetDlgItem ( mainwnd , IDOK ) ;
2003-12-04 22:12:25 +00:00
hBackButton = GetDlgItem ( mainwnd , 3 ) ;
2002-09-05 22:22:26 +00:00
2004-01-04 14:06:39 +00:00
mySetWindowText ( hCancelButton , pszCancelButtonText ) ;
mySetWindowText ( hNextButton , pszNextButtonText ) ;
mySetWindowText ( hBackButton , pszBackButtonText ) ;
2002-08-02 10:01:35 +00:00
2003-09-28 15:24:55 +00:00
if ( bBackEnabled ! = - 1 ) EnableWindow ( hBackButton , bBackEnabled ) ;
if ( bCancelEnabled ! = - 1 ) EnableWindow ( hCancelButton , bCancelEnabled ) ;
if ( bCancelShow ! = - 1 ) old_cancel_visible = ShowWindow ( hCancelButton , bCancelShow ? SW_SHOWNA : SW_HIDE ) ;
2002-08-02 10:01:35 +00:00
2003-12-04 22:12:25 +00:00
HFONT hFont = ( HFONT ) mySendMessage ( mainwnd , WM_GETFONT , 0 , 0 ) ;
2002-08-02 10:01:35 +00:00
2004-01-12 23:23:36 +00:00
// Prevent WM_COMMANDs from being processed while we are building
g_done = 1 ;
2003-12-23 16:29:16 +00:00
int mainWndWidth , mainWndHeight ;
2003-12-04 22:12:25 +00:00
hConfigWindow = CreateDialog ( m_hInstance , MAKEINTRESOURCE ( IDD_DIALOG1 ) , mainwnd , cfgDlgProc ) ;
2002-08-02 10:01:35 +00:00
if ( hConfigWindow )
{
2004-02-21 15:18:22 +00:00
RECT dialog_r ;
2002-08-02 10:01:35 +00:00
GetWindowRect ( childwnd , & dialog_r ) ;
2003-12-23 16:29:16 +00:00
MapWindowPoints ( 0 , mainwnd , ( LPPOINT ) & dialog_r , 2 ) ;
mainWndWidth = dialog_r . right - dialog_r . left ;
mainWndHeight = dialog_r . bottom - dialog_r . top ;
2003-09-04 18:25:57 +00:00
SetWindowPos (
hConfigWindow ,
0 ,
dialog_r . left ,
dialog_r . top ,
2003-12-23 16:29:16 +00:00
mainWndWidth ,
mainWndHeight ,
2003-09-04 18:25:57 +00:00
SWP_NOZORDER | SWP_NOACTIVATE
) ;
2002-08-02 10:01:35 +00:00
// Sets the font of IO window to be the same as the main window
2003-12-04 22:12:25 +00:00
mySendMessage ( hConfigWindow , WM_SETFONT , ( WPARAM ) hFont , TRUE ) ;
2002-08-02 10:01:35 +00:00
}
else
{
popstring ( NULL ) ;
pushstring ( " error creating dialog " ) ;
2002-11-01 20:34:55 +00:00
return 1 ;
2002-08-02 10:01:35 +00:00
}
2004-01-04 14:06:39 +00:00
BOOL fFocused = FALSE ;
2007-01-23 17:33:31 +00:00
BOOL fFocusedByFlag = FALSE ;
2004-01-04 14:06:39 +00:00
2003-01-04 13:02:17 +00:00
# define DEFAULT_STYLES (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS)
2005-09-17 09:55:17 +00:00
# define RTL_EX_STYLES (WS_EX_RTLREADING | WS_EX_LEFTSCROLLBAR)
2002-11-14 21:21:45 +00:00
2003-09-08 13:54:01 +00:00
for ( int nIdx = 0 ; nIdx < nNumFields ; nIdx + + ) {
2002-09-10 20:04:54 +00:00
static struct {
char * pszClass ;
DWORD dwStyle ;
2003-09-04 18:25:57 +00:00
DWORD dwRTLStyle ;
2002-09-10 20:04:54 +00:00
DWORD dwExStyle ;
2003-09-04 18:25:57 +00:00
DWORD dwRTLExStyle ;
2002-09-10 20:04:54 +00:00
} ClassTable [ ] = {
{ " STATIC " , // FIELD_LABEL
2004-01-04 14:06:39 +00:00
DEFAULT_STYLES ,
DEFAULT_STYLES | SS_RIGHT ,
2003-09-04 18:25:57 +00:00
WS_EX_TRANSPARENT ,
2005-09-17 09:55:17 +00:00
WS_EX_TRANSPARENT | RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " STATIC " , // FIELD_ICON
2004-01-04 14:06:39 +00:00
DEFAULT_STYLES | SS_ICON ,
DEFAULT_STYLES | SS_ICON ,
2003-09-04 18:25:57 +00:00
0 ,
2005-09-17 09:55:17 +00:00
RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " STATIC " , // FIELD_BITMAP
2004-02-21 15:18:22 +00:00
DEFAULT_STYLES | SS_BITMAP ,
DEFAULT_STYLES | SS_BITMAP ,
2003-09-04 18:25:57 +00:00
0 ,
2005-09-17 09:55:17 +00:00
RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " BUTTON " , // FIELD_BROWSEBUTTON
2002-12-29 20:16:35 +00:00
DEFAULT_STYLES | WS_TABSTOP ,
2003-09-04 18:25:57 +00:00
DEFAULT_STYLES | WS_TABSTOP ,
0 ,
2005-09-17 09:55:17 +00:00
RTL_EX_STYLES } ,
2004-01-05 21:53:06 +00:00
{ " BUTTON " , // FIELD_LINK
DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW ,
DEFAULT_STYLES | WS_TABSTOP | BS_OWNERDRAW | BS_RIGHT ,
0 ,
2005-09-17 09:55:17 +00:00
RTL_EX_STYLES } ,
2004-01-05 21:53:06 +00:00
{ " BUTTON " , // FIELD_BUTTON
DEFAULT_STYLES | WS_TABSTOP ,
DEFAULT_STYLES | WS_TABSTOP ,
0 ,
2005-09-17 09:55:17 +00:00
RTL_EX_STYLES } ,
2004-01-05 21:53:06 +00:00
{ " BUTTON " , // FIELD_GROUPBOX
DEFAULT_STYLES | BS_GROUPBOX ,
DEFAULT_STYLES | BS_GROUPBOX | BS_RIGHT ,
WS_EX_TRANSPARENT ,
2005-09-17 09:55:17 +00:00
WS_EX_TRANSPARENT | RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " BUTTON " , // FIELD_CHECKBOX
2003-01-27 16:15:00 +00:00
DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTOCHECKBOX | BS_MULTILINE ,
2003-09-04 18:25:57 +00:00
DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTOCHECKBOX | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT ,
0 ,
2005-09-17 09:55:17 +00:00
RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " BUTTON " , // FIELD_RADIOBUTTON
2003-01-27 16:15:00 +00:00
DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTORADIOBUTTON | BS_MULTILINE ,
2003-09-04 18:25:57 +00:00
DEFAULT_STYLES | WS_TABSTOP | BS_TEXT | BS_VCENTER | BS_AUTORADIOBUTTON | BS_MULTILINE | BS_RIGHT | BS_LEFTTEXT ,
0 ,
2005-09-17 09:55:17 +00:00
RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " EDIT " , // FIELD_TEXT
2003-01-27 16:15:00 +00:00
DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL ,
2003-09-04 18:25:57 +00:00
DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT ,
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE ,
2005-09-17 09:55:17 +00:00
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " EDIT " , // FIELD_FILEREQUEST
2003-01-27 16:15:00 +00:00
DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL ,
2003-09-04 18:25:57 +00:00
DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT ,
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE ,
2005-09-17 09:55:17 +00:00
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " EDIT " , // FIELD_DIRREQUEST
2003-01-27 16:15:00 +00:00
DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL ,
2003-09-04 18:25:57 +00:00
DEFAULT_STYLES | WS_TABSTOP | ES_AUTOHSCROLL | ES_RIGHT ,
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE ,
2005-09-17 09:55:17 +00:00
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " COMBOBOX " , // FIELD_COMBOBOX
2002-11-14 21:21:45 +00:00
DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | CBS_AUTOHSCROLL | CBS_HASSTRINGS ,
2003-09-04 18:25:57 +00:00
DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | WS_CLIPCHILDREN | CBS_AUTOHSCROLL | CBS_HASSTRINGS ,
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE ,
2005-09-17 09:55:17 +00:00
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RIGHT | RTL_EX_STYLES } ,
2002-09-10 20:04:54 +00:00
{ " LISTBOX " , // FIELD_LISTBOX
2003-01-27 16:15:00 +00:00
DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT ,
2003-09-04 18:25:57 +00:00
DEFAULT_STYLES | WS_TABSTOP | WS_VSCROLL | LBS_DISABLENOSCROLL | LBS_HASSTRINGS | LBS_NOINTEGRALHEIGHT ,
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE ,
2005-09-17 09:55:17 +00:00
WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_RIGHT | RTL_EX_STYLES }
2002-09-10 20:04:54 +00:00
} ;
2002-08-02 10:01:35 +00:00
2003-12-04 22:12:25 +00:00
FieldType * pField = pFields + nIdx ;
2003-01-20 13:57:30 +00:00
2002-11-14 21:21:45 +00:00
# undef DEFAULT_STYLES
2003-12-04 22:12:25 +00:00
if ( pField - > nType < 1 | | pField - > nType > ( sizeof ( ClassTable ) / sizeof ( ClassTable [ 0 ] ) ) )
2002-09-10 20:04:54 +00:00
continue ;
2003-09-04 18:25:57 +00:00
DWORD dwStyle , dwExStyle ;
if ( bRTL ) {
2003-12-04 22:12:25 +00:00
dwStyle = ClassTable [ pField - > nType - 1 ] . dwRTLStyle ;
dwExStyle = ClassTable [ pField - > nType - 1 ] . dwRTLExStyle ;
2003-09-04 18:25:57 +00:00
}
else {
2003-12-04 22:12:25 +00:00
dwStyle = ClassTable [ pField - > nType - 1 ] . dwStyle ;
dwExStyle = ClassTable [ pField - > nType - 1 ] . dwExStyle ;
2003-09-04 18:25:57 +00:00
}
2002-08-02 10:01:35 +00:00
2003-03-11 13:29:38 +00:00
// Convert from dialog units
2002-09-10 20:04:54 +00:00
2004-02-21 15:18:22 +00:00
RECT rect = pField - > rect ;
// MapDialogRect uses the font used when a dialog is created, and ignores
// any subsequent WM_SETFONT messages (like we used above); so use the main
// NSIS window for the conversion, instead of this one.
MapDialogRect ( mainwnd , & rect ) ;
2002-12-14 00:10:29 +00:00
2003-12-04 22:12:25 +00:00
if ( pField - > rect . left < 0 )
2003-12-23 16:29:16 +00:00
rect . left + = mainWndWidth ;
2003-12-04 22:12:25 +00:00
if ( pField - > rect . right < 0 )
2003-12-23 16:29:16 +00:00
rect . right + = mainWndWidth ;
2003-12-04 22:12:25 +00:00
if ( pField - > rect . top < 0 )
2003-12-23 16:29:16 +00:00
rect . top + = mainWndHeight ;
2003-12-04 22:12:25 +00:00
if ( pField - > rect . bottom < 0 )
2003-12-23 16:29:16 +00:00
rect . bottom + = mainWndHeight ;
2002-09-10 20:04:54 +00:00
2003-09-04 18:25:57 +00:00
if ( bRTL ) {
int right = rect . right ;
2003-12-23 16:29:16 +00:00
rect . right = mainWndWidth - rect . left ;
rect . left = mainWndWidth - right ;
2003-09-04 18:25:57 +00:00
}
2003-12-04 22:12:25 +00:00
char * title = pField - > pszText ;
switch ( pField - > nType ) {
2003-10-30 23:51:44 +00:00
case FIELD_ICON :
case FIELD_BITMAP :
title = NULL ; // otherwise it is treated as the name of a resource
break ;
2002-09-10 20:04:54 +00:00
case FIELD_CHECKBOX :
case FIELD_RADIOBUTTON :
2004-01-04 14:06:39 +00:00
dwStyle ^ = pField - > nFlags & BS_LEFTTEXT ;
2002-08-02 10:01:35 +00:00
break ;
2003-12-04 22:12:25 +00:00
case FIELD_TEXT :
2002-08-02 10:01:35 +00:00
case FIELD_FILEREQUEST :
case FIELD_DIRREQUEST :
2003-12-04 22:12:25 +00:00
if ( pField - > nFlags & FLAG_PASSWORD )
2002-09-10 20:04:54 +00:00
dwStyle | = ES_PASSWORD ;
2003-12-04 22:12:25 +00:00
if ( pField - > nFlags & FLAG_ONLYNUMBERS )
2003-05-30 13:35:47 +00:00
dwStyle | = ES_NUMBER ;
2004-01-04 14:06:39 +00:00
if ( pField - > nFlags & FLAG_WANTRETURN )
dwStyle | = ES_WANTRETURN ;
if ( pField - > nFlags & FLAG_READONLY )
dwStyle | = ES_READONLY ;
title = pField - > pszState ;
2003-12-04 22:12:25 +00:00
if ( pField - > nFlags & FLAG_MULTILINE )
2003-06-10 13:18:07 +00:00
{
2003-09-28 15:24:55 +00:00
dwStyle | = ES_MULTILINE | ES_AUTOVSCROLL ;
// Enable word-wrap unless we have a horizontal scroll bar
2003-12-04 22:12:25 +00:00
// or it has been explicitly disallowed
2004-01-04 14:06:39 +00:00
if ( ! ( pField - > nFlags & ( WS_HSCROLL | FLAG_NOWORDWRAP ) ) )
2003-09-28 15:24:55 +00:00
dwStyle & = ~ ES_AUTOHSCROLL ;
2003-12-04 22:12:25 +00:00
ConvertNewLines ( pField - > pszState ) ;
2004-01-04 14:06:39 +00:00
// If multiline-readonly then hold the text back until after the
// initial focus has been set. This is so the text is not initially
// selected - useful for License Page look-a-likes.
if ( pField - > nFlags & FLAG_READONLY )
title = NULL ;
2003-06-10 13:18:07 +00:00
}
2002-08-02 10:01:35 +00:00
break ;
2002-09-05 22:22:26 +00:00
case FIELD_COMBOBOX :
2003-12-04 22:12:25 +00:00
dwStyle | = ( pField - > nFlags & FLAG_DROPLIST ) ? CBS_DROPDOWNLIST : CBS_DROPDOWN ;
title = pField - > pszState ;
2002-08-02 10:01:35 +00:00
break ;
case FIELD_LISTBOX :
2004-01-04 14:06:39 +00:00
dwStyle | = pField - > nFlags & ( LBS_NOTIFY | LBS_MULTIPLESEL | LBS_EXTENDEDSEL ) ;
2002-08-02 10:01:35 +00:00
break ;
}
2004-01-04 14:06:39 +00:00
dwStyle | = pField - > nFlags & ( WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_DISABLED ) ;
if ( pField - > nFlags & WS_TABSTOP ) dwStyle & = ~ WS_TABSTOP ;
2003-01-03 22:26:08 +00:00
2003-12-04 22:12:25 +00:00
HWND hwCtrl = pField - > hwnd = CreateWindowEx (
2002-08-26 13:27:51 +00:00
dwExStyle ,
2003-12-04 22:12:25 +00:00
ClassTable [ pField - > nType - 1 ] . pszClass ,
2002-08-26 13:27:51 +00:00
title ,
dwStyle ,
2002-09-10 20:04:54 +00:00
rect . left ,
rect . top ,
rect . right - rect . left ,
rect . bottom - rect . top ,
2002-08-26 13:27:51 +00:00
hConfigWindow ,
2003-12-04 22:12:25 +00:00
( HMENU ) pField - > nControlID ,
2002-08-26 13:27:51 +00:00
m_hInstance ,
NULL
) ;
2002-08-02 10:01:35 +00:00
2005-10-11 16:27:04 +00:00
{
char szField [ 64 ] ;
char szHwnd [ 64 ] ;
wsprintf ( szField , " Field %d " , pField - > nField ) ;
wsprintf ( szHwnd , " %d " , hwCtrl ) ;
WritePrivateProfileString ( szField , pField - > pszHwndEntry , szHwnd , pszFilename ) ;
}
2002-11-08 16:51:26 +00:00
if ( hwCtrl ) {
2002-08-02 10:01:35 +00:00
// Sets the font of IO window to be the same as the main window
2003-12-04 22:12:25 +00:00
mySendMessage ( hwCtrl , WM_SETFONT , ( WPARAM ) hFont , TRUE ) ;
2002-08-02 10:01:35 +00:00
// make sure we created the window, then set additional attributes
2003-12-04 22:12:25 +00:00
switch ( pField - > nType ) {
case FIELD_TEXT :
case FIELD_FILEREQUEST :
case FIELD_DIRREQUEST :
mySendMessage ( hwCtrl , EM_LIMITTEXT , ( WPARAM ) pField - > nMaxLength , ( LPARAM ) 0 ) ;
2007-02-06 20:54:05 +00:00
if ( dwStyle & ES_NUMBER )
{
pField - > wndProc = GetWindowLong ( hwCtrl , GWL_WNDPROC ) ;
SetWindowLong ( hwCtrl , GWL_WNDPROC , ( long ) NumbersOnlyPasteWndProc ) ;
}
2003-12-04 22:12:25 +00:00
break ;
case FIELD_CHECKBOX :
case FIELD_RADIOBUTTON :
if ( pField - > pszState [ 0 ] = = ' 1 ' )
mySendMessage ( hwCtrl , BM_SETCHECK , ( WPARAM ) BST_CHECKED , 0 ) ;
break ;
case FIELD_COMBOBOX :
case FIELD_LISTBOX :
// if this is a listbox or combobox, we need to add the list items.
if ( pField - > pszListItems ) {
UINT nAddMsg , nFindMsg , nSetSelMsg ;
if ( pField - > nType = = FIELD_COMBOBOX ) {
nAddMsg = CB_ADDSTRING ;
nFindMsg = CB_FINDSTRINGEXACT ;
nSetSelMsg = CB_SETCURSEL ;
2002-08-02 10:01:35 +00:00
}
2003-12-04 22:12:25 +00:00
else {
nAddMsg = LB_ADDSTRING ;
nFindMsg = LB_FINDSTRINGEXACT ;
nSetSelMsg = LB_SETCURSEL ;
}
char * pszStart , * pszEnd , * pszList ;
pszStart = pszEnd = pszList = STRDUP ( pField - > pszListItems ) ;
2004-01-31 19:54:45 +00:00
// pszListItems has a trailing pipe
while ( * pszEnd ) {
2003-12-04 22:12:25 +00:00
if ( * pszEnd = = ' | ' ) {
* pszEnd = ' \0 ' ;
2004-01-31 19:54:45 +00:00
if ( * pszStart )
mySendMessage ( hwCtrl , nAddMsg , 0 , ( LPARAM ) pszStart ) ;
pszStart = + + pszEnd ;
2003-01-19 16:56:10 +00:00
}
2004-01-30 20:37:43 +00:00
else
2004-01-31 19:54:45 +00:00
pszEnd = CharNext ( pszEnd ) ;
2003-01-19 16:56:10 +00:00
}
2003-12-04 22:12:25 +00:00
FREE ( pszList ) ;
if ( pField - > pszState ) {
2004-01-04 14:06:39 +00:00
if ( pField - > nFlags & ( LBS_MULTIPLESEL | LBS_EXTENDEDSEL ) & & nFindMsg = = LB_FINDSTRINGEXACT ) {
2007-03-11 15:58:46 +00:00
mySendMessage ( hwCtrl , LB_SETSEL , FALSE , ( LPARAM ) - 1 ) ;
2003-12-04 22:12:25 +00:00
pszStart = pszEnd = pField - > pszState ;
2004-01-31 19:54:45 +00:00
for ( ; ; ) {
char c = * pszEnd ;
if ( c = = ' | ' | | c = = ' \0 ' ) {
* pszEnd = ' \0 ' ;
if ( * pszStart )
{
2007-03-11 15:58:46 +00:00
int nItem = mySendMessage ( hwCtrl , LB_FINDSTRINGEXACT , ( WPARAM ) - 1 , ( LPARAM ) pszStart ) ;
2004-01-31 19:54:45 +00:00
if ( nItem ! = LB_ERR )
2003-12-04 22:12:25 +00:00
mySendMessage ( hwCtrl , LB_SETSEL , TRUE , nItem ) ;
}
2004-01-31 19:54:45 +00:00
if ( ! c )
break ;
pszStart = + + pszEnd ;
2003-12-04 22:12:25 +00:00
}
2004-01-31 19:54:45 +00:00
else
pszEnd = CharNext ( pszEnd ) ;
2003-12-04 22:12:25 +00:00
}
}
else {
2007-03-11 15:58:46 +00:00
int nItem = mySendMessage ( hwCtrl , nFindMsg , ( WPARAM ) - 1 , ( LPARAM ) pField - > pszState ) ;
2003-12-04 22:12:25 +00:00
if ( nItem ! = CB_ERR ) { // CB_ERR == LB_ERR == -1
mySendMessage ( hwCtrl , nSetSelMsg , nItem , 0 ) ;
}
}
2003-01-19 16:56:10 +00:00
}
2002-08-02 10:01:35 +00:00
}
2003-12-04 22:12:25 +00:00
break ;
case FIELD_ICON :
case FIELD_BITMAP :
{
WPARAM nImageType = pField - > nType = = FIELD_BITMAP ? IMAGE_BITMAP : IMAGE_ICON ;
LPARAM nImage = 0 ;
2005-01-21 19:12:47 +00:00
2003-12-04 22:12:25 +00:00
if ( pField - > pszText ) {
pField - > hImage = LoadImage (
m_hInstance ,
pField - > pszText ,
nImageType ,
( pField - > nFlags & FLAG_RESIZETOFIT )
? ( rect . right - rect . left )
: 0 ,
( pField - > nFlags & FLAG_RESIZETOFIT )
? ( rect . bottom - rect . top )
: 0 ,
LR_LOADFROMFILE
) ;
nImage = ( LPARAM ) pField - > hImage ;
}
else
nImage = ( LPARAM ) LoadIcon ( GetModuleHandle ( 0 ) , MAKEINTRESOURCE ( 103 ) ) ;
2005-01-21 19:12:47 +00:00
if ( ( pField - > nFlags & TRANSPARENT_BMP ) & & nImageType = = IMAGE_BITMAP )
{
// based on AdvSplash's SetTransparentRegion
BITMAP bm ;
HBITMAP hBitmap = ( HBITMAP ) nImage ;
if ( GetObject ( hBitmap , sizeof ( bm ) , & bm ) )
{
HDC dc ;
int x , y ;
HRGN region , cutrgn ;
BITMAPINFO bmi ;
int size = bm . bmWidth * bm . bmHeight * sizeof ( int ) ;
int * bmp = ( int * ) MALLOC ( size ) ;
if ( bmp )
{
bmi . bmiHeader . biBitCount = 32 ;
bmi . bmiHeader . biCompression = BI_RGB ;
bmi . bmiHeader . biHeight = bm . bmHeight ;
bmi . bmiHeader . biPlanes = 1 ;
bmi . bmiHeader . biSize = sizeof ( BITMAPINFOHEADER ) ;
bmi . bmiHeader . biWidth = bm . bmWidth ;
bmi . bmiHeader . biClrUsed = 0 ;
bmi . bmiHeader . biClrImportant = 0 ;
dc = CreateCompatibleDC ( NULL ) ;
SelectObject ( dc , hBitmap ) ;
x = GetDIBits ( dc , hBitmap , 0 , bm . bmHeight , bmp , & bmi , DIB_RGB_COLORS ) ;
region = CreateRectRgn ( 0 , 0 , bm . bmWidth , bm . bmHeight ) ;
int keycolor = * bmp & 0xFFFFFF ;
// Search for transparent pixels
for ( y = bm . bmHeight - 1 ; y > = 0 ; y - - ) {
for ( x = 0 ; x < bm . bmWidth ; ) {
if ( ( * bmp & 0xFFFFFF ) = = keycolor ) {
int j = x ;
while ( ( x < bm . bmWidth ) & & ( ( * bmp & 0xFFFFFF ) = = keycolor ) ) {
bmp + + , x + + ;
}
// Cut transparent pixels from the original region
cutrgn = CreateRectRgn ( j , y , x , y + 1 ) ;
CombineRgn ( region , region , cutrgn , RGN_XOR ) ;
DeleteObject ( cutrgn ) ;
} else {
bmp + + , x + + ;
}
}
}
// Set resulting region.
SetWindowRgn ( hwCtrl , region , TRUE ) ;
DeleteObject ( region ) ;
DeleteObject ( dc ) ;
FREE ( bmp ) ;
}
}
}
2003-12-04 22:12:25 +00:00
mySendMessage (
hwCtrl ,
STM_SETIMAGE ,
2002-09-04 18:14:34 +00:00
nImageType ,
2003-12-04 22:12:25 +00:00
nImage
2003-03-23 17:12:14 +00:00
) ;
2005-01-21 19:12:47 +00:00
2004-02-21 15:18:22 +00:00
if ( pField - > nType = = FIELD_BITMAP )
{
// Centre the image in the requested space.
// Cannot use SS_CENTERIMAGE because it behaves differently on XP to
// everything else. (Thank you Microsoft.)
RECT bmp_rect ;
GetClientRect ( hwCtrl , & bmp_rect ) ;
bmp_rect . left = ( rect . left + rect . right - bmp_rect . right ) / 2 ;
bmp_rect . top = ( rect . top + rect . bottom - bmp_rect . bottom ) / 2 ;
SetWindowPos ( hwCtrl , NULL , bmp_rect . left , bmp_rect . top , 0 , 0 ,
SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER ) ;
}
2005-01-21 19:12:47 +00:00
2003-12-04 22:12:25 +00:00
break ;
2003-03-23 17:12:14 +00:00
}
2003-12-04 22:12:25 +00:00
2003-07-05 16:55:54 +00:00
# ifdef IO_ENABLE_LINK
2003-12-04 22:12:25 +00:00
case FIELD_LINK :
pField - > nParentIdx = SetWindowLong ( hwCtrl , GWL_WNDPROC , ( long ) StaticLINKWindowProc ) ;
break ;
2003-07-05 16:55:54 +00:00
# endif
2003-12-04 22:12:25 +00:00
}
2004-01-04 18:14:18 +00:00
2007-01-23 17:33:31 +00:00
// Set initial focus to the first appropriate field ( with FOCUS flag)
if ( ! fFocusedByFlag & & ( dwStyle & ( WS_TABSTOP | WS_DISABLED ) ) = = WS_TABSTOP & & pField - > nType > = FIELD_SETFOCUS ) {
if ( pField - > nFlags & FLAG_FOCUS ) {
fFocusedByFlag = TRUE ;
}
if ( ! fFocused | | fFocusedByFlag ) {
fFocused = TRUE ;
mySetFocus ( hwCtrl ) ;
}
2004-01-04 18:14:18 +00:00
}
// If multiline-readonly then hold the text back until after the
// initial focus has been set. This is so the text is not initially
// selected - useful for License Page look-a-likes.
if ( ( pField - > nFlags & ( FLAG_MULTILINE | FLAG_READONLY ) ) = = ( FLAG_MULTILINE | FLAG_READONLY ) )
mySetWindowText ( hwCtrl , pField - > pszState ) ;
2002-08-02 10:01:35 +00:00
}
}
2004-01-04 14:06:39 +00:00
if ( ! fFocused )
mySetFocus ( hNextButton ) ;
mySetWindowText ( mainwnd , pszTitle ) ;
2003-06-08 13:41:48 +00:00
pFilenameStackEntry = * g_stacktop ;
2003-02-14 18:51:11 +00:00
* g_stacktop = ( * g_stacktop ) - > next ;
2003-12-04 22:12:25 +00:00
static char tmp [ 32 ] ;
2002-11-01 20:34:55 +00:00
wsprintf ( tmp , " %d " , hConfigWindow ) ;
pushstring ( tmp ) ;
return 0 ;
}
2002-08-02 10:01:35 +00:00
2003-11-01 00:17:19 +00:00
void WINAPI showCfgDlg ( )
2002-11-01 20:34:55 +00:00
{
2003-03-18 15:45:25 +00:00
lpWndProcOld = ( void * ) SetWindowLong ( hMainWindow , DWL_DLGPROC , ( long ) ParentWndProc ) ;
2002-11-08 16:51:26 +00:00
2003-07-10 00:28:05 +00:00
// Tell NSIS to remove old inner dialog and pass handle of the new inner dialog
2003-12-04 22:12:25 +00:00
mySendMessage ( hMainWindow , WM_NOTIFY_CUSTOM_READY , ( WPARAM ) hConfigWindow , 0 ) ;
2002-08-02 10:01:35 +00:00
ShowWindow ( hConfigWindow , SW_SHOWNA ) ;
2002-11-11 16:06:23 +00:00
2003-12-04 22:12:25 +00:00
g_done = g_NotifyField = 0 ;
2002-11-01 20:34:55 +00:00
2003-12-06 20:45:35 +00:00
while ( ! g_done ) {
2002-08-02 10:01:35 +00:00
MSG msg ;
2006-04-05 18:54:17 +00:00
GetMessage ( & msg , NULL , 0 , 0 ) ;
2004-02-21 15:18:22 +00:00
if ( ! IsDialogMessage ( hConfigWindow , & msg ) & & ! IsDialogMessage ( hMainWindow , & msg ) )
{
TranslateMessage ( & msg ) ;
2003-12-06 20:45:35 +00:00
DispatchMessage ( & msg ) ;
2004-02-21 15:18:22 +00:00
}
2003-12-06 20:45:35 +00:00
}
2002-08-02 10:01:35 +00:00
// we don't save settings on cancel since that means your installer will likely
// quit soon, which means the ini might get flushed late and cause crap. :) anwyay.
2002-09-26 22:47:21 +00:00
if ( ! g_is_cancel ) SaveSettings ( ) ;
2002-08-02 10:01:35 +00:00
2004-01-12 23:23:36 +00:00
SetWindowLong ( hMainWindow , DWL_DLGPROC , ( long ) lpWndProcOld ) ;
2002-08-02 10:01:35 +00:00
DestroyWindow ( hConfigWindow ) ;
2002-11-15 12:53:08 +00:00
// by ORTIM: 13-August-2002
2003-09-28 15:24:55 +00:00
if ( bCancelShow ! = - 1 ) ShowWindow ( hCancelButton , old_cancel_visible ? SW_SHOWNA : SW_HIDE ) ;
2002-08-02 10:01:35 +00:00
2003-06-08 13:41:48 +00:00
FREE ( pFilenameStackEntry ) ;
2002-08-02 10:01:35 +00:00
FREE ( pszTitle ) ;
FREE ( pszCancelButtonText ) ;
FREE ( pszNextButtonText ) ;
FREE ( pszBackButtonText ) ;
2003-06-02 14:26:15 +00:00
int i = nNumFields ;
while ( i - - ) {
2003-12-04 22:12:25 +00:00
FieldType * pField = pFields + i ;
2004-02-10 23:29:49 +00:00
2004-01-31 19:54:45 +00:00
int j = FIELD_BUFFERS ;
while ( j - - )
FREE ( ( ( char * * ) pField ) [ j ] ) ;
2003-12-04 22:12:25 +00:00
if ( pField - > nType = = FIELD_BITMAP ) {
DeleteObject ( pField - > hImage ) ;
2003-03-26 14:37:20 +00:00
}
2003-12-04 22:12:25 +00:00
if ( pField - > nType = = FIELD_ICON ) {
DestroyIcon ( ( HICON ) pField - > hImage ) ;
2003-03-26 14:37:20 +00:00
}
2002-08-02 10:01:35 +00:00
}
FREE ( pFields ) ;
2002-09-26 22:47:21 +00:00
pushstring ( g_is_cancel ? " cancel " : g_is_back ? " back " : " success " ) ;
2002-08-02 10:01:35 +00:00
}
2002-11-01 20:34:55 +00:00
int initCalled ;
2002-08-02 10:01:35 +00:00
2002-11-01 20:34:55 +00:00
extern " C " void __declspec ( dllexport ) dialog ( HWND hwndParent , int string_size ,
char * variables , stack_t * * stacktop )
{
hMainWindow = hwndParent ;
EXDLL_INIT ( ) ;
if ( initCalled ) {
pushstring ( " error " ) ;
return ;
}
2004-02-10 23:29:49 +00:00
if ( createCfgDlg ( ) )
2002-11-01 20:34:55 +00:00
return ;
popstring ( NULL ) ;
showCfgDlg ( ) ;
}
extern " C " void __declspec ( dllexport ) initDialog ( HWND hwndParent , int string_size ,
char * variables , stack_t * * stacktop )
{
hMainWindow = hwndParent ;
EXDLL_INIT ( ) ;
if ( initCalled ) {
pushstring ( " error " ) ;
return ;
}
2004-02-10 23:29:49 +00:00
if ( createCfgDlg ( ) )
return ;
2002-11-01 20:34:55 +00:00
initCalled + + ;
}
extern " C " void __declspec ( dllexport ) show ( HWND hwndParent , int string_size ,
char * variables , stack_t * * stacktop )
{
EXDLL_INIT ( ) ;
if ( ! initCalled ) {
pushstring ( " error " ) ;
return ;
}
initCalled - - ;
showCfgDlg ( ) ;
}
2002-08-02 10:01:35 +00:00
2002-12-16 16:53:26 +00:00
extern " C " BOOL WINAPI DllMain ( HANDLE hInst , ULONG ul_reason_for_call , LPVOID lpReserved )
2002-08-02 10:01:35 +00:00
{
m_hInstance = ( HINSTANCE ) hInst ;
2003-12-06 20:45:35 +00:00
return TRUE ;
2002-08-02 10:01:35 +00:00
}
2003-11-01 00:17:19 +00:00
int WINAPI LookupToken ( TableEntry * psTable_ , char * pszToken_ )
2002-09-05 22:22:26 +00:00
{
for ( int i = 0 ; psTable_ [ i ] . pszName ; i + + )
if ( ! stricmp ( pszToken_ , psTable_ [ i ] . pszName ) )
return psTable_ [ i ] . nValue ;
return 0 ;
}
2002-08-02 10:01:35 +00:00
2003-11-01 00:17:19 +00:00
int WINAPI LookupTokens ( TableEntry * psTable_ , char * pszTokens_ )
2002-09-30 22:22:16 +00:00
{
int n = 0 ;
char * pszStart = pszTokens_ ;
char * pszEnd = pszTokens_ ;
for ( ; ; ) {
2004-01-31 19:54:45 +00:00
char c = * pszEnd ;
if ( c = = ' | ' | | c = = ' \0 ' ) {
2002-09-30 22:22:16 +00:00
* pszEnd = ' \0 ' ;
n | = LookupToken ( psTable_ , pszStart ) ;
2004-01-31 19:54:45 +00:00
* pszEnd = c ;
if ( ! c )
break ;
pszStart = + + pszEnd ;
2002-09-30 22:22:16 +00:00
}
2004-01-31 19:54:45 +00:00
else
pszEnd = CharNext ( pszEnd ) ;
2002-09-30 22:22:16 +00:00
}
return n ;
}
2003-03-17 13:46:13 +00:00
2003-11-01 00:17:19 +00:00
void WINAPI ConvertNewLines ( char * str ) {
2004-01-31 19:54:45 +00:00
char * p1 , * p2 , * p3 ;
if ( ! str )
return ;
p1 = p2 = str ;
while ( * p1 )
{
switch ( * ( LPWORD ) p1 )
{
case CHAR2_TO_WORD ( ' \\ ' , ' t ' ) :
* p2 = ' \t ' ;
p1 + = 2 ;
p2 + + ;
break ;
case CHAR2_TO_WORD ( ' \\ ' , ' n ' ) :
* p2 = ' \n ' ;
p1 + = 2 ;
p2 + + ;
break ;
case CHAR2_TO_WORD ( ' \\ ' , ' r ' ) :
* p2 = ' \r ' ;
p1 + = 2 ;
p2 + + ;
break ;
case CHAR2_TO_WORD ( ' \\ ' , ' \\ ' ) :
* p2 = ' \\ ' ;
p1 + = 2 ;
p2 + + ;
break ;
default :
p3 = CharNext ( p1 ) ;
while ( p1 < p3 )
* p2 + + = * p1 + + ;
break ;
2003-03-17 13:46:13 +00:00
}
}
2004-01-31 19:54:45 +00:00
2003-03-17 13:46:13 +00:00
* p2 = 0 ;
2003-06-16 18:49:23 +00:00
}