杉宫竹苑工作室

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 2973|回复: 0

Inno setup 安装包界面设计

[复制链接]
发表于 2017-5-5 21:13:05 | 显示全部楼层 |阅读模式

正式会员享受无限制浏览网站功能和高速网盘下载,赶快加入本站吧!

您需要 登录 才可以下载或查看,没有账号?立即注册

x
        目标要求:
        1、 界面border去掉原本windows自带的对话框格式,采取扁平化设计;
        2、 简化安装流程,不要弹出那么多安装向导页,不要让用户一直点“下一步”,简洁人性化;
        3、 安装界面可加载漂亮的背景图片;
        4、 优化安装包安装时间。

开发工具:
        因为之前采用Inno setup设计,而且它拥有Pascal脚本引擎,功能算强大,故采用Inno setup。
        主要流程:
       1.jpg
        由图中可以清晰地看出,所有向导页之间都是通过“下一步”或者“上一步”进行驱动更换的。
        概要分析:
        这里需要调用两个美化插件动态库:botva2.dll和InnoCallback.dll,用于界面的美化和功能完善。这里就不全部把代码贴出来了,只针对其中的要点进行分析概括。
        在开始之前,先了解一下inno setup基本的过程和函数
  1. //该过程在开始的时候改变向导或者向导页,不要指望使用InitializeSetup函数实现改变向导页的功能,因为InitializeSetup函数触发时向导窗口并不存在。
  2. procedure InitializeWizard();

  3. //该函数在安装程序初始化时调用,返回False 将中断安装,True则继续安装.
  4. function InitializeSetup(): Boolean;

  5. //该过程在安装终止时被调用,注意及时在用户没有安装任何文件之前退出也会被调用。
  6. procedure DeinitializeSetup();

  7. //该过程提供用户完成预安装和安装之后的任务,更多的是提供了安装过程中的状态。参数CurStep=ssInstall是在程序实际安装前,CurStep=ssPostInstall是实际安装完成后,而CurStep=ssDone是在一次成功的安装完成后、安装程序终止前(即点击finish按钮后执行)。
  8. procedure CurStepChanged(CurStep: TSetupStep);

  9. //当用户单击下一步按钮时调用。如果返回True,向导将移到下一页;如果返回False,它仍保留在当前页。
  10. function NextButtonClick(CurPageID: Integer): Boolean;

  11. //向导调用这个事件函数确定是否在所有页或不在一个特殊页 (用PageID 指定) 显示。如果返回True,将跳过该页;如果你返回False,该页被显示。注意: 这个事件函数不被wpWelcome、wpPreparing 和wpInstalling 页调用,还有安装程序已经确定要跳过的页也不会调用 (例如,没有包含组件安装程序的wpSelectComponents)。
  12. function ShouldSkipPage(PageID: Integer): Boolean;

  13. //在新向导页 (由CurPageID 指定) 显示后调用。
  14. procedure CurPageChanged(CurPageID: Integer);
复制代码

1、 界面border去掉原本windows自带的对话框格式,采取扁平化设计
  1.     //设置欢迎向导页的尺寸大小:
  2.     WizardForm.Center
  3.     WizardForm.BorderStyle:=bsNone;  //去掉对话框border
  4.     WizardForm.ClientWidth:=601;
  5.     WizardForm.ClientHeight:=341;
  6.     WizardForm.InnerNotebook.Hide;
  7.     WizardForm.OuterNotebook.Hide;
  8.     wizardform.Color:=TransparentColor;
  9.     WizardForm.Bevel.Hide;
  10.     WizardForm.NextButton.Width:=0;
  11.     WizardForm.BackButton.Width:=0;
  12.     WizardForm.CancelButton.Width:=0;
  13.     WizardForm.OnMouseDown:=@WizardFormMouseDown;  //可拉动
复制代码


       2、 简化安装包安装流程,不要用户一直点“下一步”,简洁人性化
        这里只有两个向导页,一个是选择安装目录和许可协议的界面,一个是正在安装的界面。用户只需点击“开始安装”即可安装,并有进度条和百分比显示,不用经常性地点击“下一步”。
        3、 安装界面可加载漂亮的图片和动画效果
  1. // 创建描述位图
  2. Bmp:= TBitmapImage.Create(WizardForm);
  3. Bmp.Top:=ScaleX(0);
  4. Bmp.Left:=ScaleX(0);
  5. Bmp.Width:=WizardForm.ClientWidth;
  6. Bmp.Height:=ScaleY(371);
  7. Bmp.BackColor:= WizardForm.Color;
  8. Bmp.Parent:= WizardForm;
  9. Bmp.Bitmap.LoadFromFile(ExpandConstant('{tmp}\bg.bmp'));
  10. Bmp.OnMouseDown := @WizardFormMouseDown;   //可拉动

  11. //动画效果
  12. AnimateWindow(StrToInt(ExpandConstant('{wizardhwnd}')), 400, AW_Center or AW_Activate);
  13. SetWindowLong(StrToInt(ExpandConstant('{wizardhwnd}')),GWL_Exstyle, WS_Ex_Layered);
  14. SetLayeredWindowAttributes(StrToInt(ExpandConstant('{wizardhwnd}')), 0, 240, LWA_Alpha);
复制代码

       4、 优化安装包安装时间。
        把不用的安装文件重新梳理了一遍,减少打包时的体积,不用多次调用读写注册表。

        难点分析:
        1、 如何跳过向导页?
  1. //主要是程序调用“下一步”,然后在ShouldSkipPage函数中进行跳过。
  2. function ShouldSkipPage(PageID: Integer): Boolean;
  3. begin
  4. if PageID=wpWelcome then
  5.   result := true;
  6. if PageID=wpSelectDir then
  7.   result := true;
  8. end;
复制代码

        2、 “下一步”如何调用?
  1. WizardForm.NextButton.OnClick(WizardForm);
复制代码

        3、 如何用鼠标拉动对话框?
  1. 重载WizardFormMouseDown过程,然后调用SendMessage(WizardForm.Handle, WM_SYSCOMMAND, $F012, 0);
复制代码

       4、 如何自定义浏览文件夹按钮?
  1. //记住,获得的路径要赋给WizardForm.DirEdit.Text,这是浏览文件夹向导页wpSelectDir的路径编辑框。
  2. procedure DirOnClick(hBtn:HWND);
  3. var
  4.   res: Boolean;
  5.   UserSelectDir,str: string;

  6. begin

  7.   UserSelectDir := Edit.Text;
  8.   res := BrowseForFolder('浏览文件夹', UserSelectDir, True);

  9.   if res then
  10.   begin
  11.     str:=Copy(UserSelectDir,Length(UserSelectDir),1);//取最后一个字符
  12.     if '\'=str then
  13.           Edit.Text := UserSelectDir
  14.       else
  15.           Edit.Text := UserSelectDir;

  16.   end;
  17.   //浏览文件夹向导页的文件夹路径
  18.   WizardForm.DirEdit.Text := Edit.Text;

  19. end;
复制代码

        5、 如何点击按钮显示“许可协议”?
  1. ShellExec('', ExpandConstant('{tmp}\license.txt'),'', '', SW_SHOW, ewNoWait, ErrorCode)。
复制代码

        6、 如何安装程序完成后自动运行程序?
  1. Exec(ExpandConstant('{app}\MySoftware.exe'), '', '', SW_SHOW, ewNoWait, RCode);
复制代码

       7、 如何删除文件夹?
  1. DelTree(ExpandConstant('{app}\文件夹名称'), True, True, False);
复制代码

       8、 如何关闭向导页?
  1. WizardForm.Close;
复制代码

       9、 如何自定义完成向导页的完成按钮?
通过程序自行调用 WizardForm.NextButton.OnClick(WizardForm); 达到“下一步”的功能,然后通过函数ShouldSkipPage一直调到最后完成页wpFinished,最后调用WizardForm.NextButton.OnClick(WizardForm);完成。
        10、 如何在安装页面换背景图片?
  1. procedure CurPageChanged(CurPageID: Integer);
  2. begin
  3.         if CurPageID = wpInstalling then
  4.         begin
  5.             Bmp:= TBitmapImage.Create(WizardForm);
  6.             Bmp.Top:=ScaleX(0);
  7.             Bmp.Left:=ScaleX(0);
  8.             Bmp.Width:=WizardForm.ClientWidth;
  9.             Bmp.Height:=ScaleY(371);
  10.             Bmp.BackColor:= WizardForm.Color;
  11.             Bmp.Parent:= WizardForm;
  12.             Bmp.Bitmap.LoadFromFile(ExpandConstant('{tmp}\bg2.bmp'));
  13.             Bmp.OnMouseDown := @WizardFormMouseDown;
  14.             WizardForm.OnMouseDown:=@WizardFormMouseDown;
  15.         end;
  16. end;
复制代码

       11、 如何读写注册表?
  1. //读取信息
  2. RegQueryStringValue(HKLM, 'Software\***\***','Version',svValue)
  3. //写入信息
  4. RegWriteStringValue(HKLM, 'Software\***\***','Version', '4.0');
复制代码

       12、 安装前如何判断是否有进程正在进行?
  1. //安装前判断是否有进程正在运行
  2. function IsModuleLoaded(modulename: String ): Boolean;
  3. external 'IsModuleLoaded@files:psvince.dll stdcall setuponly';

  4. IsModuleLoaded('Mysoftware.exe');
复制代码

       13、 如何使用botva2.dll插件创建自定义按钮?
  1. /调用动态库函数
  2. function BtnCreate(hParent :HWND; Left, Top, Width, Height :integer; FileName :PAnsiChar; ShadowWidth :integer; IsCheckBtn :boolean) :HWND;
  3. external 'BtnCreate@files:botva2.dll stdcall';

  4. FinishBtnH := BtnCreate(WizardForm.Handle,ProgressBar.Left+ProgressBar.Width-83, ProgressBar.Top+ProgressBar.Height+ScaleX(10), ScaleX(83), ScaleY(28),ExpandConstant('{tmp}\Finish.png'),1,False);
  5. BtnSetEvent(FinishBtnH,BtnClickEventID,WrapBtnCallback(@FinishButtonClick,1));
  6. BtnSetVisibility(FinishBtnH,False);
复制代码

      14、 百分比如何确定?
  1. //百分比
  2. function PBProc(h:hWnd;Msg,wParam,lParam:Longint):Longint;
  3. var
  4.   pr,i1,i2 : Extended;
  5.   w : integer;
  6. begin
  7.   Result:=CallWindowProc(PBOldProc,h,Msg,wParam,lParam);
  8.   if (Msg=$402) and (WizardForm.ProgressGauge.Position>WizardForm.ProgressGauge.Min) then
  9.   begin
  10.     i1:=WizardForm.ProgressGauge.Position-WizardForm.ProgressGauge.Min;
  11.     i2:=WizardForm.ProgressGauge.Max-WizardForm.ProgressGauge.Min;

  12.     pr:=i1*100/i2;
  13.     PrLabel.Caption:=IntToStr(Round(pr))+'%';
  14.     w:=Round(110*pr/100);  //改变数值,达到百分比和进度条的同步
  15.     ProgressBar.Position := w;
  16.   end;
  17. end;
复制代码


        错误解决:
        对于某些电脑环境,安装时只要点击“退出”按钮或者安装完后总会遇到这个错误,弹出以下提示图片:
         2.jpg
        解决办法:
       因为调用WizardForm.Close或者WizardForm.NextButton.OnClick(WizardForm)退出时没有进行WizardForm的资源释放,所以导致了该错误。只要在退出或者完成前加上WizardForm.Release即可解决。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|手机版|Archiver|SgzyStudio

GMT+8, 2024-4-27 00:17 , Processed in 0.142898 second(s), 25 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表