Inno Setup 自定義界面心得

由於項目須要,須要打 windows 安裝包,要求安裝界面徹底按照需求來。做爲沒接觸過這塊兒的服務端寶寶,在此期間踩了不少坑。windows

坑不提也罷,最終結果圓滿,記錄下與大部分網上PO出來的作法不太同樣的當心得,備忘。ide

網上搜到的自定義界面,都用的 botva2.dll ,我沒用。應該說,用過,但遇到了圖片變形的問題,短期內沒解決,因此最後全都用的 Inno Setup 原生類。Inno Setup 官方文檔很詳細,並且開源,因此原生用起來仍是很順利的。此前沒接觸過 Pascal 語言,但影響不大。函數

加載透明圖片或按鈕

網上多用 botva2.dll 來加載 png 圖片,以達到圓角效果。因爲遇到圖片變形,我開始在官方文檔裏找替代方案。spa

Inno Setup 自己提供一個類 TBitmapImage 來支持帶 alpha 通道的bmp 圖片,也就是 32 位的 bmp 圖片,支持透明效果。PhotoShop 中可經過添加 alpha 通道來生成 32 位 bmp 圖。操作系統

顯示圖片方法:code

val BmpImg : TBitmapImage;

BmpImg := TBitmapImage.Create(WizardForm); // 卸載時將 WizardForm 換爲 UninstallProgressForm 便可
with BmpImg do
begin
    Parent := WizardForm;                  // 卸載時將 WizardForm 換爲 UninstallProgressForm 便可
    Bitmap := TAlphaBitmap.Create;  
    Bitmap.AlphaFormat := afDefined;       // 須設置此值,才能讀取圖片的 alpha 通道,應在加載圖片文件前設置
    Bitmap.LoadFromFile(ExpandConstant('{tmp}\xxx.bmp'));
    BackColor := clNone;                   // 背景色應設置爲 clNone,不然默認透明處爲白色
OnClick := @some_procedure; // 按鈕的點擊回調,非按鈕圖片不須要
end;

按鈕的點擊回調形如:procedure some_procedure(sender: TObject);orm

設置 BmpImg.Enabled := False 可以使圖片的點擊事件失效。htm

 

富文本

Inno Setup 的類 TRichEditViewer 支持 .rtf 格式的富文本內容,可用於顯示許可協議或其餘說明文檔,使用以下:blog

val RichViewer : TRichEditViewer;
RichText : AnsiString;
LoadStringFromFile(ExpandConstant('{tmp}\xxx.rtf'), RichText);  // 讀取文件內容至 RichText
RichViewer :
= TRichEditViewer.Create(WizardForm); // 卸載時將 WizardForm 換爲 UninstallProgressForm 便可 with RichViewer do begin Parent := WizardForm; // 卸載時將 WizardForm 換爲 UninstallProgressForm 便可
    ReadOnly := true; // 只讀

    SCROLLBARS := ssVertical; // 滾動條類型
    BorderStyle := bsNone; // 邊框類型
    RTFText := licenseText;     // 內容
    UseRichEdit := True; // 須設置此值爲 True,纔會按照富文本方式讀取內容
end;

 

獲取磁盤空間

界面上須要顯示所需磁盤空間和剩餘磁盤空間。事件

所需磁盤空間,WizardForm.DiskSpaceLabel 中有對所需磁盤的描述,能夠將此描述經過 [Messages] 段設置 "DiskSpaceMBLabel=[mb]" 使之只剩下所需磁盤大小。而後經過 WizardForm.DiskSpaceLabel.Caption 可得到所需磁盤大小,字符串類型(如 "10.3" ),單位MB。

剩餘磁盤空間,調用 Inno Setup 提供的 GetSpaceOnDisk 函數便可,將第一個參數設置爲安裝所在磁盤號,如 "C:" 。

例子:

[Messages]
DiskSpaceMBLabel=[mb]

[Code]
function GetSpaceNeeded(); // 返回所需磁盤空間,字符串類型 "10.3",單位MB
begin
Result := WizardForm.DiskSpaceLabel.Caption;
end;

function GetSpaceLeft(); // 返回剩餘空間大小,整數類型,單位MB
var freeDiskSpace, totalDiskSpace : Cardinal;
begin
GetSpaceOnDisk(Copy(WizardForm.DirEdit.text, 1, 2), true, freeDiskSpace, totalDiskSpace)
Result := freeDiskSpace
end;

 

進度條

引入了外部依賴 user32.dll 的 SetTimer 來設置定時器,InnoCallback.dll 的 wrapcallback 來封裝函數。其中 user32.dll 爲操做系統自帶,InnoCallback.dll 須要自行下載。

在安裝或卸載進度變化的時候,WizardForm.ProgressGauge 和 UninstallProgressForm.ProgressBar 中的值會相應變化,定時讀取其中的值便可實現實時進度變化。

例子:

type
  TTimerProc = procedure(h:longword; msg:longword; idevent:longword; dwTime:longword);
      
function SetTimer(hWnd, nIDEvent, uElapse, lpTimerFunc: LongWord): LongWord; external 'SetTimer@user32.dll stdcall delayload';
function TimerCallBack(P: TTimerProc; ParamCount: integer):LongWord; external 'wrapcallback@{%TEMP}\InnoCallback.dll stdcall delayload';

procedure RefreshProgressBar(h, AMsg, IdEvent, dwTime: LongWord);  // 刷新進度條
  var
    i1, i2 : integer;
  begin
    i1 := WizardForm.ProgressGauge.Position - WizardForm.ProgressGauge.Min; // 卸載時 WizardForm.ProgressGauge 應替換爲 UninstallProgressForm.ProgressBar
    i2 := WizardForm.ProgressGauge.Max - WizardForm.ProgressGauge.Min; // 卸載時 WizardForm.ProgressGauge 應替換爲 UninstallProgressForm.ProgressBar
    ProgressImg.Width := Round(i1 * TotalWidthOfProgressImg / i2);
  end;

procedure CurPageChanged(CurPageID: Integer);
  begin
    if CurPageID = wpInstalling then // 安裝時在 wpInstalling 頁面調用定時器
      begin
    SetTimer(0, 0, 10, TimerCallBack(@TimerProc, 4));
end;
end;

procedure InitializeUninstallProgressForm(); // 卸載時在 InitializeUninstallProgressForm 中調用定時器
  begin
    SetTimer(0, 0, 10, TimerCallBack(@TimerProc, 4));
end;

 

其餘

一、安裝界面中要用到的圖片和資源,在 [Files] 段中應放到前面,由於安裝程序讀取資源時會先解壓排在該資源前的全部文件。若是安裝包界面資源在應用文件後面,安裝界面打開會很慢很慢很慢很慢。

二、去掉關閉安裝程序的二次確認框:

procedure CancelButtonClick(CurPageID: Integer; var Cancel, Confirm: Boolean);
  begin               
    Confirm := False;   
  end; 

三、手動觸發下一步

WizardForm.NextButton.OnClick(WizardForm)
相關文章
相關標籤/搜索