在这里我总结的是用installshield 打包软件的时候自定义安装界面的问题,阅读下面的文章请确保您具有以下工具的使用经验:
spy++
installshield 12
visual studio 2005
熟悉以下语言:
vc++
installscript
并且熟悉windows的系统操作。
另外本文的例子是基于installscript 类型项目。
各种方法:
3, 利用函数显示对话框
添加一个函数, 并注册。
definition:
registry:
添加一个dialog并生成一个类:CECDialogsDLL ,这就是我们要在DisplayAskDestPathDlg这个函数里面调用的窗体了。你可以利用vc的强大功能为他添加各种各样的行为。
声明函数:
调用:
再调用的时候,也要先load进dll 文件,具体请参考上面的代码。
在查找setup status dialog 的最上面的图片控件的时候,笔者发现这个控件的ID 每次运行的时候都市不一样的,而且,每个空间的顺序随着系统的每次系统也是不一样的,所以没有办法用GetWindow来找他的ID, 所以笔者采用了一种比较 stupid的方式来处理。具体请察看函数GetTopBannerCtrlWnd( hWnd)
总结:
installshield 自定义窗体的方式确实很多,也很灵活,但是并不是每种方式都是power,effective, simple的,在不同的场合下我们需要应用不同的方式创建来满足需求。原则就是能用simple 的方式解决的尽量用simple的方式,如果不能,那就只能用其他的方式了。最重要的是能为客户带来一个愉快地安装过程。
相关资源:
Updating the Progress Bar - Macrovision Community
Changing Dialog Box Bitmaps
Macrovision Community - Editing text in STATUSEX dialog
http://helpnet.installshield.com/robo/projects/installshield11helplib/IHelpRelease_ReleasePackagerExe.htm
spy++
installshield 12
visual studio 2005
熟悉以下语言:
vc++
installscript
并且熟悉windows的系统操作。
另外本文的例子是基于installscript 类型项目。
各种方法:
1, 利用installshield的Dialogs面板工具。
这里不用复述,它像我们所用过的大多数软件开发工具一样提供了可见即可得的效果,我们可以轻松利用它的拖放操作自定义对话框。
2, 利用外部的资源文件
这里不用复述,它像我们所用过的大多数软件开发工具一样提供了可见即可得的效果,我们可以轻松利用它的拖放操作自定义对话框。
2, 利用外部的资源文件
- 制作资源文件
打开你的vs(笔者用的是2005),新建一个MFC DLL项目,在左边找到你的资源面板,添加一个dialog, 添加一些相应的控间,build.
- 引用资源文件
把你build出来得资源文件 resouce.dll 添加到installshield 的Support Files language independent 下面
打开installscript, 新建一个脚本文件,重命名为resouce.h 把你vc 项目里面的resouce.h 文件的内容复制过来, 然后再你的Setup.Rul 文件里面添加引用:
#include resource.h
添加如下代码:
打开installscript, 新建一个脚本文件,重命名为resouce.h 把你vc 项目里面的resouce.h 文件的内容复制过来, 然后再你的Setup.Rul 文件里面添加引用:
#include resource.h
添加如下代码:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->szResoucePath = SUPPORTDIR ^ "resource.dll"; // Load custom DLL.
if ( UseDLL( szResoucePath ) < 0 ) then
abort;
endif;
if ( UseDLL( szResoucePath ) < 0 ) then
abort;
endif;
显示窗体, 处理消息:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->nResult = DefineDialog( szDlgName,
hInstance,
szDLL,
IDD_DIALOG_ASKPATH,
"",
hwndParent,
HWND_INSTALL,
DLG_MSG_STANDARD | DLG_CENTERED );
if nResult then
// TODO: show error message then exit.
abort;
endif;
repeat // handle dialog message
nResult = WaitOnDialog( szDlgName ); // begin our message loop
switch ( nResult )
case DLG_CLOSE:
EndDialog (szDlgName);
ReleaseDialog (szDlgName);
abort;
case DLG_INIT:
CtrlSetText( szDlgName, IDC_EDIT_PATH, svdir );
CtrlSetState( szDlgName, IDC_CHECK_OFFICETOOLBAR, BUTTON_CHECKED );
CtrlSetState( szDlgName, IDC_CHECK_DESTOP, BUTTON_CHECKED );
CtrlSetState( szDlgName, IDC_CHECK_QUICKLAUNCH, BUTTON_CHECKED );
case IDC_BUTTON_BROWSE:
SelectDir ( "Choose Folder", "", svdir, TRUE );
CtrlSetText( szDlgName, IDC_EDIT_PATH, svdir );
case RES_PBUT_CANCEL:
Do( EXIT );
case RES_PBUT_NEXT:
CtrlGetText( szDlgName, IDC_EDIT_PATH, svdir ); // get ctrl's value
if ( CtrlGetState( szDlgName, IDC_CHECK_OFFICETOOLBAR ) = BUTTON_CHECKED ) then
bAddOfficeToolbar = TRUE;
else
bAddOfficeToolbar = FALSE;
endif;
if ( CtrlGetState( szDlgName, IDC_CHECK_DESTOP ) = BUTTON_CHECKED ) then
bDeskTopShortcut = TRUE;
else
bDeskTopShortcut = FALSE;
endif;
if ( CtrlGetState( szDlgName, IDC_CHECK_QUICKLAUNCH ) = BUTTON_CHECKED ) then
bQuickLuanchToolbar = TRUE;
else
bQuickLuanchToolbar = FALSE;
endif;
bDone = TRUE;
case RES_PBUT_BACK:
EndDialog( szDlgName );
ReleaseDialog( szDlgName );
goto Dlg_SdLicense2;
endswitch;
until bDone;
EndDialog( szDlgName ); // exit dialog
ReleaseDialog( szDlgName ); // release resouce
hInstance,
szDLL,
IDD_DIALOG_ASKPATH,
"",
hwndParent,
HWND_INSTALL,
DLG_MSG_STANDARD | DLG_CENTERED );
if nResult then
// TODO: show error message then exit.
abort;
endif;
repeat // handle dialog message
nResult = WaitOnDialog( szDlgName ); // begin our message loop
switch ( nResult )
case DLG_CLOSE:
EndDialog (szDlgName);
ReleaseDialog (szDlgName);
abort;
case DLG_INIT:
CtrlSetText( szDlgName, IDC_EDIT_PATH, svdir );
CtrlSetState( szDlgName, IDC_CHECK_OFFICETOOLBAR, BUTTON_CHECKED );
CtrlSetState( szDlgName, IDC_CHECK_DESTOP, BUTTON_CHECKED );
CtrlSetState( szDlgName, IDC_CHECK_QUICKLAUNCH, BUTTON_CHECKED );
case IDC_BUTTON_BROWSE:
SelectDir ( "Choose Folder", "", svdir, TRUE );
CtrlSetText( szDlgName, IDC_EDIT_PATH, svdir );
case RES_PBUT_CANCEL:
Do( EXIT );
case RES_PBUT_NEXT:
CtrlGetText( szDlgName, IDC_EDIT_PATH, svdir ); // get ctrl's value
if ( CtrlGetState( szDlgName, IDC_CHECK_OFFICETOOLBAR ) = BUTTON_CHECKED ) then
bAddOfficeToolbar = TRUE;
else
bAddOfficeToolbar = FALSE;
endif;
if ( CtrlGetState( szDlgName, IDC_CHECK_DESTOP ) = BUTTON_CHECKED ) then
bDeskTopShortcut = TRUE;
else
bDeskTopShortcut = FALSE;
endif;
if ( CtrlGetState( szDlgName, IDC_CHECK_QUICKLAUNCH ) = BUTTON_CHECKED ) then
bQuickLuanchToolbar = TRUE;
else
bQuickLuanchToolbar = FALSE;
endif;
bDone = TRUE;
case RES_PBUT_BACK:
EndDialog( szDlgName );
ReleaseDialog( szDlgName );
goto Dlg_SdLicense2;
endswitch;
until bDone;
EndDialog( szDlgName ); // exit dialog
ReleaseDialog( szDlgName ); // release resouce
3, 利用函数显示对话框
- 创建资源文件
添加一个函数, 并注册。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->extern "C"
LONG WINAPI DisplayAskDestPathDlg( HWND hWndParent, LPSTR lpszPath,
PBOOL pfAddOfficeToolbar, PBOOL pfDeskTopShortcut, PBOOL pfQuickLuanchToolbar)
{
LONG nReturn;
TRACE0( "Inside ECDialogs.DLL\n" );
CString csName = _T("");
LPSTR lpszLicense = NULL;
TRY
{
CECDialogsDLL dlg(CWnd::FromHandle(hWndParent), 0, pfAddOfficeToolbar, pfDeskTopShortcut, pfQuickLuanchToolbar, lpszPath, lpszLicense,
CECDialogsDLL::askPathDestDialog);
nReturn = (LONG) dlg.DoModal();
if( (nReturn == (LONG)RS_PBUT_RETRY ) ||
(nReturn == (LONG)RS_PBUT_BROWSE) ||
(nReturn == (LONG)RS_PBUT_CANCEL) )
return( nReturn );
}
CATCH_ALL(e)
{
// A failure caused an exception!
return FALSE;
}
END_CATCH_ALL
return( nReturn );
}
LONG WINAPI DisplayAskDestPathDlg( HWND hWndParent, LPSTR lpszPath,
PBOOL pfAddOfficeToolbar, PBOOL pfDeskTopShortcut, PBOOL pfQuickLuanchToolbar)
{
LONG nReturn;
TRACE0( "Inside ECDialogs.DLL\n" );
CString csName = _T("");
LPSTR lpszLicense = NULL;
TRY
{
CECDialogsDLL dlg(CWnd::FromHandle(hWndParent), 0, pfAddOfficeToolbar, pfDeskTopShortcut, pfQuickLuanchToolbar, lpszPath, lpszLicense,
CECDialogsDLL::askPathDestDialog);
nReturn = (LONG) dlg.DoModal();
if( (nReturn == (LONG)RS_PBUT_RETRY ) ||
(nReturn == (LONG)RS_PBUT_BROWSE) ||
(nReturn == (LONG)RS_PBUT_CANCEL) )
return( nReturn );
}
CATCH_ALL(e)
{
// A failure caused an exception!
return FALSE;
}
END_CATCH_ALL
return( nReturn );
}
definition:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->#ifdef __cplusplus
extern "C" {
#endif
LONG WINAPI DisplayAskDestPathDlg( HWND hWndParent, LPSTR lpszPath,
PBOOL pfAddOfficeToolbar, PBOOL pfDeskTopShortcut, PBOOL pfQuickLuanchToolbar);
#ifdef __cplusplus
}
#endif
extern "C" {
#endif
LONG WINAPI DisplayAskDestPathDlg( HWND hWndParent, LPSTR lpszPath,
PBOOL pfAddOfficeToolbar, PBOOL pfDeskTopShortcut, PBOOL pfQuickLuanchToolbar);
#ifdef __cplusplus
}
#endif
registry:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->LIBRARY "ECDialogs"
DESCRIPTION 'ECDialogs Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
DisplayAskDestPathDlg@1
DESCRIPTION 'ECDialogs Windows Dynamic Link Library'
EXPORTS
; Explicit exports can go here
DisplayAskDestPathDlg@1
添加一个dialog并生成一个类:CECDialogsDLL ,这就是我们要在DisplayAskDestPathDlg这个函数里面调用的窗体了。你可以利用vc的强大功能为他添加各种各样的行为。
- 应用
声明函数:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->prototype ECDIALOGS.DisplayAskDestPathDlg(INT, STRING, INT, INT, INT);
调用:
再调用的时候,也要先load进dll 文件,具体请参考上面的代码。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->prototype ECDIALOGS.DisplayAskDestPathDlg(INT, STRING, INT, INT, INT);
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->ReleasePackager.exe "C:\My InstallShield 11 Projects\My Project\Media\My Release\Disk Images" "C:\My InstallShield 11 Projects\My Project\Media\My Release\Package\MyPackage.exe" "C:\My Icon Files\MyIcons.dll" 2
4, 利用win api 修改installshield 内部对话框
在有些时候我们会发现,有些对话框我们是不能直接从installshield Dialogs面板直接修改,也不能用dll和调用外部函数来实现,比如说安装进度对话框(setup status dialog). 我们只能修改它。
这句代码的有效前提是你调用的是 STATUSEX 的setup status dialog.
还请注意,这个图片的大小是固定的哦。 那我要显示不一样大小的图片呢? 我要修改,去掉它上面那些该死的文字呢?
那你就跟我一起来使用windows api 吧。我们的思路是,利用窗体的title 找到当前这个窗口的handle, 利用SetWindowPos api修改窗口的属性。 mfc中所有的控件都是窗体哦。show 代码吧,估计你已经听我罗索的烦了。
如果你自己写的代码跑不通,看看这里,你有没有忘了声明系统api乐呢?
5, 直接修改installshield生成的资源文件。在我们启动安装程序的时候,会有一个preparing dialog,这个窗体的也是可以修改的。
在 你项目文件夹下搜索这个文件, _setup.dll ,它应该在你的 Media\<release name>\Disk Images\Disk1下面,直接用vs 就可以编辑修改。然后你双击这个文件夹下的setup.exe,你会惊喜的发现你的preparing dialog 已经被修改了。
但是,如果你需要的仅仅是一个单独的可执行文件呢?你再去用installshield rebuild的时候,你会很痛苦的发现_setup.dll 又被installshield改成它原来的了。这里installshield 为我们提供了一个exe ,他可以把media 下面的文件打包成一个self-extracting 的exe。 那就是 ReleasePackager.exe 它在<intall direcotry>\IS12\System 下面。 你可以用命令行执行它一次,如果没有参数,它会打印出帮助。具体参数说明如下:
给各例子吧,copy过来的:
如果你发现它生成了一个C:\My InstallShield 11 Projects\My Project\Media\My Release\Package\MyPackage.exe文件。那你就大功告成了。
遇到的问题:- 修改它的dialog title:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->SetDialogTitle( DLG_STATUS, "mimeo.com - setup" );
这句代码的有效前提是你调用的是 STATUSEX 的setup status dialog.
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->SetStatusWindow( 1, "" );
Enable( STATUSEX );
StatusUpdate( ON, 100 );
Enable( STATUSEX );
StatusUpdate( ON, 100 );
关闭它:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->Disable( STATUSEX );
- 修改它的top banner,就是它最上面的图片:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->DialogSetInfo(DLG_INFO_ALTIMAGE, SUPPORTDIR ^ "topbanner.bmp", TRUE);
请注意,这句代码会修改你所有的窗体的top banner 的图片, 什么时候调用? 你应该猜到了吧 :-)还请注意,这个图片的大小是固定的哦。 那我要显示不一样大小的图片呢? 我要修改,去掉它上面那些该死的文字呢?
那你就跟我一起来使用windows api 吧。我们的思路是,利用窗体的title 找到当前这个窗口的handle, 利用SetWindowPos api修改窗口的属性。 mfc中所有的控件都是窗体哦。show 代码吧,估计你已经听我罗索的烦了。
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->SetDialogTitle( DLG_STATUS, "mimeo.com - setup" );
SetStatusWindow( 1, "" );
Enable( STATUSEX );
StatusUpdate( ON, 100 );
// change the setup status dialog's UI
try
hWnd = FindWindow( "", "mimeo.com - setup" );
if (hWnd != NULL) then
HiddenDlgItem( hWnd, 50 );
// change the progress' position
hWndStatus = GetDlgItem( hWnd, 1500 );
if ( hWndStatus != NULL ) then
SetWindowPos( hWndStatus, 0, 49, 260, 400, 23, SWP_SHOWWINDOW );
endif;
// change the top banner's ctrl weight and height
hWndTopBanner = GetTopBannerCtrlWnd( hWnd );
if ( hWndTopBanner != NULL ) then
SetWindowPos( hWndTopBanner, 0, 0, 0, 498, 235, SWP_SHOWWINDOW );
endif;
// change botton line's position
//hWndStatus = GetDlgItem( hWnd, 1300 );
//if ( hWndStatus != NULL ) then
// SetWindowPos( hWndStatus, 1, 4, 290, 490, 2, SWP_SHOWWINDOW );
//endif;
User32.UpdateWindow( hWnd );
endif;
catch
endcatch;
SetStatusWindow( 1, "" );
Enable( STATUSEX );
StatusUpdate( ON, 100 );
// change the setup status dialog's UI
try
hWnd = FindWindow( "", "mimeo.com - setup" );
if (hWnd != NULL) then
HiddenDlgItem( hWnd, 50 );
// change the progress' position
hWndStatus = GetDlgItem( hWnd, 1500 );
if ( hWndStatus != NULL ) then
SetWindowPos( hWndStatus, 0, 49, 260, 400, 23, SWP_SHOWWINDOW );
endif;
// change the top banner's ctrl weight and height
hWndTopBanner = GetTopBannerCtrlWnd( hWnd );
if ( hWndTopBanner != NULL ) then
SetWindowPos( hWndTopBanner, 0, 0, 0, 498, 235, SWP_SHOWWINDOW );
endif;
// change botton line's position
//hWndStatus = GetDlgItem( hWnd, 1300 );
//if ( hWndStatus != NULL ) then
// SetWindowPos( hWndStatus, 1, 4, 290, 490, 2, SWP_SHOWWINDOW );
//endif;
User32.UpdateWindow( hWnd );
endif;
catch
endcatch;
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->function HiddenDlgItem(hWnd, nItemID) // hidden the ctrl by ctrl's ID
HWND hWndItem;
begin
hWndItem = GetDlgItem( hWnd, nItemID );
if ( hWndItem != NULL ) then
SetWindowPos( hWndItem, 1, 0, 0, 0, 0, SWP_HIDEWINDOW );
endif;
end;
INT nArray( 16 ); // save Ctrl's IDs of setup status dialog
function GetTopBannerCtrlWnd( hWnd)
INT nIndex, nPicID, nErrorCode;
HWND hWndItem, hWndPic;
begin
InitialDlgCtrlIDs( );
nIndex = 0;
while ( nIndex < 16 )
nPicID = nArray( nIndex );
hWndItem = GetDlgItem( hWnd, nPicID );
hWndPic = GetWindow( hWndItem, GW_HWNDNEXT );
if ( hWndPic != NULL ) then
nPicID = GetWindowLong( hWndPic, GWL_ID );
if ( IsPictureCtrlID( nPicID ) ) then
return hWndPic;
endif;
endif;
hWndItem = GetDlgItem( hWnd, nPicID );
hWndPic = GetWindow( hWndItem, GW_HWNDPREV );
if ( hWndPic != NULL ) then
nPicID = GetWindowLong( hWndPic, GWL_ID );
if ( IsPictureCtrlID( nPicID ) ) then
return hWndPic;
endif;
endif;
nIndex ++;
endwhile;
return NULL;
end;
function InitialDlgCtrlIDs( ) // 这些是该setup status 窗口中的所有控件ID, 怎么找到的, 用spy++啊。
begin
nArray(0) = 0x5dc;
nArray(1) = 0x34;
nArray(2) = 0x4b0;
nArray(3) = 0x2c6;
nArray(4) = 0x578;
nArray(5) = 0x32;
nArray(6) = 0x33;
nArray(7) = 0x7;
nArray(8) = 0x514;
nArray(9) = 0x2;
nArray(10) = 0x515;
nArray(11) = 0x4591;
nArray(12) = 0x4592;
nArray(13) = 0x4593;
nArray(14) = 0x4594;
nArray(15) = 0x5aa;
end;
function IsPictureCtrlID( nItem ) // is top pictrue ctrl's ID?
INT nIndex;
begin
nIndex = 0;
while ( nIndex < 16 )
if ( nItem = nArray( nIndex ) ) then
return FALSE;
endif;
nIndex ++;
endwhile;
return TRUE;
end;
HWND hWndItem;
begin
hWndItem = GetDlgItem( hWnd, nItemID );
if ( hWndItem != NULL ) then
SetWindowPos( hWndItem, 1, 0, 0, 0, 0, SWP_HIDEWINDOW );
endif;
end;
INT nArray( 16 ); // save Ctrl's IDs of setup status dialog
function GetTopBannerCtrlWnd( hWnd)
INT nIndex, nPicID, nErrorCode;
HWND hWndItem, hWndPic;
begin
InitialDlgCtrlIDs( );
nIndex = 0;
while ( nIndex < 16 )
nPicID = nArray( nIndex );
hWndItem = GetDlgItem( hWnd, nPicID );
hWndPic = GetWindow( hWndItem, GW_HWNDNEXT );
if ( hWndPic != NULL ) then
nPicID = GetWindowLong( hWndPic, GWL_ID );
if ( IsPictureCtrlID( nPicID ) ) then
return hWndPic;
endif;
endif;
hWndItem = GetDlgItem( hWnd, nPicID );
hWndPic = GetWindow( hWndItem, GW_HWNDPREV );
if ( hWndPic != NULL ) then
nPicID = GetWindowLong( hWndPic, GWL_ID );
if ( IsPictureCtrlID( nPicID ) ) then
return hWndPic;
endif;
endif;
nIndex ++;
endwhile;
return NULL;
end;
function InitialDlgCtrlIDs( ) // 这些是该setup status 窗口中的所有控件ID, 怎么找到的, 用spy++啊。
begin
nArray(0) = 0x5dc;
nArray(1) = 0x34;
nArray(2) = 0x4b0;
nArray(3) = 0x2c6;
nArray(4) = 0x578;
nArray(5) = 0x32;
nArray(6) = 0x33;
nArray(7) = 0x7;
nArray(8) = 0x514;
nArray(9) = 0x2;
nArray(10) = 0x515;
nArray(11) = 0x4591;
nArray(12) = 0x4592;
nArray(13) = 0x4593;
nArray(14) = 0x4594;
nArray(15) = 0x5aa;
end;
function IsPictureCtrlID( nItem ) // is top pictrue ctrl's ID?
INT nIndex;
begin
nIndex = 0;
while ( nIndex < 16 )
if ( nItem = nArray( nIndex ) ) then
return FALSE;
endif;
nIndex ++;
endwhile;
return TRUE;
end;
如果你自己写的代码跑不通,看看这里,你有没有忘了声明系统api乐呢?
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->prototype User32.SetDlgItemText( HWND, INT, STRING );
prototype Kernel32.GetLastError();
prototype User32.UpdateWindow( HWND );
注意哦, 系统api 的dll 是不用你自己再load的哦。 如果你又usedll 出现什么问题,别说我没告诉你哦。prototype Kernel32.GetLastError();
prototype User32.UpdateWindow( HWND );
- 修改文字:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->User32.SetDlgItemText(hWnd, nItemID, szStr);
5, 直接修改installshield生成的资源文件。在我们启动安装程序的时候,会有一个preparing dialog,这个窗体的也是可以修改的。
在 你项目文件夹下搜索这个文件, _setup.dll ,它应该在你的 Media\<release name>\Disk Images\Disk1下面,直接用vs 就可以编辑修改。然后你双击这个文件夹下的setup.exe,你会惊喜的发现你的preparing dialog 已经被修改了。
但是,如果你需要的仅仅是一个单独的可执行文件呢?你再去用installshield rebuild的时候,你会很痛苦的发现_setup.dll 又被installshield改成它原来的了。这里installshield 为我们提供了一个exe ,他可以把media 下面的文件打包成一个self-extracting 的exe。 那就是 ReleasePackager.exe 它在<intall direcotry>\IS12\System 下面。 你可以用命令行执行它一次,如果没有参数,它会打印出帮助。具体参数说明如下:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->ReleasePackager.exe "disk_images_folder" "package_file" ["icon_file" [icon_index]]
给各例子吧,copy过来的:
<!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>-->ReleasePackager.exe "C:\My InstallShield 11 Projects\My Project\Media\My Release\Disk Images" "C:\My InstallShield 11 Projects\My Project\Media\My Release\Package\MyPackage.exe" "C:\My Icon Files\MyIcons.dll" 2
如果你发现它生成了一个C:\My InstallShield 11 Projects\My Project\Media\My Release\Package\MyPackage.exe文件。那你就大功告成了。
在查找setup status dialog 的最上面的图片控件的时候,笔者发现这个控件的ID 每次运行的时候都市不一样的,而且,每个空间的顺序随着系统的每次系统也是不一样的,所以没有办法用GetWindow来找他的ID, 所以笔者采用了一种比较 stupid的方式来处理。具体请察看函数GetTopBannerCtrlWnd( hWnd)
总结:
installshield 自定义窗体的方式确实很多,也很灵活,但是并不是每种方式都是power,effective, simple的,在不同的场合下我们需要应用不同的方式创建来满足需求。原则就是能用simple 的方式解决的尽量用simple的方式,如果不能,那就只能用其他的方式了。最重要的是能为客户带来一个愉快地安装过程。
相关资源:
Updating the Progress Bar - Macrovision Community
Changing Dialog Box Bitmaps
Macrovision Community - Editing text in STATUSEX dialog
http://helpnet.installshield.com/robo/projects/installshield11helplib/IHelpRelease_ReleasePackagerExe.htm
相关推荐
本资源“android custom dialog src”似乎是一个包含自定义Dialog实现源码的压缩包,适合开发者参考学习或直接应用于项目中。在深入探讨之前,建议先阅读相关博客“UI效果(2): 自定义Dialog”,以便更好地理解和运用...
在IT行业中,自定义对话框(Custom Dialog)是一种常见的用户界面元素,用于向用户提供特定的信息或获取特定的输入。在Android开发中,我们经常会遇到需要根据应用需求设计独特外观和功能的对话框的情况,这就是...
`Custom_Dialog_Usage`这个主题正是关注如何在Android应用中创建并使用自定义对话框。通常,系统默认的Dialog样式可能无法满足我们所有的设计需求,这时我们就需要自定义Dialog来达到预期效果。 首先,我们要理解...
在Android开发中,Custom Dialog是一种常见且重要的用户交互方式,它允许开发者自定义对话框的样式、内容和功能,以提供更加个性化和丰富的用户体验。本文将深入探讨如何在Android应用中创建和使用自定义对话框。 ...
在Android开发中,我们经常会需要在android界面上弹出一些对话框,比如询问用户或者让用户选择。,但是只是给出了创建各种类型对话框的方法,并未给出如何获取用户在对话框中做出选择后的数据,即如何监听用户做出的...
本资源“安卓Dialog对话框相关-Custom-Dialog.zip”包含了一些自定义Dialog的示例代码,虽然可能无法全部验证其可用性,但它们提供了很好的学习和参考价值。 首先,我们来了解一下Android中的Dialog。Dialog是...
This is a custom dialog attached at the bottom Import At the moment the library is in my personal maven repo repositories { maven { url 'http://dl.bintray.com/raphaelbussa/maven' } } dependencies ...
Dialogue System for Unity 可以轻松地为您的游戏添加交互式对话和任务。 它是一个完整,强大的解决方案,包括基于可视节点的编辑器,对话UI,过场动画,任务日志,保存/加载等。 核心是一个精简,高效的会话系统。 ...
比如,我们可以创建一个`custom_dialog.xml`文件,其中包含一个有圆角的背景、自定义标题、内容区域以及按钮。可以使用`CardView`或者`LinearLayout`配合`shape` drawable来实现圆角效果。 ```xml android:layout...
:sparkles: flutter_custom_dialog [劳务~~] | 全局对话框函数封装,以语义方式填充对话框内部的内容,提供了当前函数 支持一些语义组件方法以在对话框中填充组件内容 支持自定义语义组件,以便开发人员在对话框中...
在Android开发中,自定义Dialog和Dialog加载动画是提升应用用户体验的重要手段。默认的Dialog样式虽然功能齐全,但在追求个性化和美观的今天,往往显得过于简单甚至有些过时。因此,开发者常常需要根据应用的设计...
dialog.setContentView(R.layout.custom_dialog); dialog.getWindow().getAttributes().windowAnimations = R.style.Dialog_Animations; // 其他设置... dialog.show(); ``` 其中,`R.style.Dialog_Animations`是...
最后,记得在布局文件(dialog_custom.xml)中设计Dialog的内容。你可以自由地添加所需的视图元素,如TextView、EditText等,并通过Java代码进行交互逻辑的处理。 通过以上步骤,你将成功地为你的Android应用创建了...
在这个例子中,`custom_dialog_layout`是XML布局文件,包含了自定义Dialog的UI元素。通过这种方式,我们能够完全控制Dialog的外观和行为。 接下来,我们讨论继承PopupWindow的方法。PopupWindow不是Dialog,但它...
android:background="@color/your_custom_color"> <!-- 在这里添加你的对话框元素,如TextView、EditText等 --> ``` 2. 创建Dialog类:然后,我们可以创建一个自定义的Dialog类,继承自`AlertDialog.Builder`...
dialog.setContentView(R.layout.custom_dialog); ViewGroup.LayoutParams layoutParams = dialog.getWindow().getAttributes(); layoutParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; layoutParams.height =...
《Dialog for PHP:开源命令行交互工具》 在IT领域,尤其是在PHP开发中,与用户进行交互是必不可少的。在命令行环境下,这种交互通常较为简单,但有时也需要更复杂的功能,比如输入验证、选择菜单等。这时,"Dialog...
4. **Custom Dialog**:开发者可以根据需求自定义Dialog的布局和行为,提供更加个性化的用户体验。 5. **BottomSheetDialog**:自Android Design Support Library引入,底部滑出的Dialog,适合展示一系列选项或操作...
1. **C_Dlg_Dial**: 这可能是项目的一个分类或者命名约定,可能指的是“Custom Dialog Dial”或者是“Custom Dialog for Changing”某些属性或功能。 2. **自定义对话框(Custom Dialog)**: 自定义对话框允许...
各种android弹出dialog效果以及各种dialog样式各种android弹出dialog效果以及各种dialog样式各种android弹出dialog效果以及各种dialog样式各种android弹出dialog效果以及各种dialog样式各种android弹出dialog效果...