退出 Inno Setup 安装程序时出现音乐故障

Music glitches when exiting Inno Setup installer

我在我的 Inno Setup 项目中使用了 Martin Prikryl 的代码。这是他的代码的link:

我对它进行了一些调整,但问题是当我完成它时音乐出现故障。

例如,如果在安装某些东西时音乐在播放,当我最终完成设置时,我仍然听到大约 3 秒的故障音频!很烦人!

我认为问题在于我们需要在安装程序完成之前卸载 Music dll,就像我们处理皮肤一样。

希望您能理解我的情况,提前致谢!

这是我的完整代码(没整理好抱歉):

[Code]
{ RedesignWizardFormBegin } // Don't remove this line!
// Don't modify this section. It is generated automatically.
var
  OldEvent_NextButtonClick: TNotifyEvent;
  OldEvent_BackButtonClick: TNotifyEvent;
  Password: TNewStaticText;
  Website: TNewButton;

procedure _NextButtonClick(Sender: TObject); forward;
procedure _BackButtonClick(Sender: TObject); forward;
procedure PasswordClick(Sender: TObject); forward;
procedure Website1Click(Sender: TObject); forward;

procedure RedesignWizardForm;
begin
  with WizardForm.NextButton do
  begin
    OldEvent_NextButtonClick := OnClick;
    OnClick := @_NextButtonClick;
  end;

  with WizardForm.BackButton do
  begin
    OldEvent_BackButtonClick := OnClick;
    OnClick := @_BackButtonClick;
  end;

  with WizardForm.WizardBitmapImage do
  begin
    Left := ScaleX(1);
    Width := ScaleX(492);
    Height := ScaleY(313);
    Visible := False;
  end;

  with WizardForm.WelcomeLabel2 do
  begin
    Enabled := False;
    ParentShowHint := False;
    Visible := False;
    Left := ScaleX(96);
    Top := ScaleY(111);
    Width := ScaleX(69);
    Height := ScaleY(47);
  end;

  with WizardForm.WelcomeLabel1 do
  begin
    Enabled := False;
    ParentShowHint := False;
    Visible := False;
    Left := ScaleX(96);
    Top := ScaleY(71);
    Width := ScaleX(109);
    Height := ScaleY(39);
  end;

  with WizardForm.PasswordEdit do
  begin
    Hint := 'Write wave4tech';
    CharCase := ecLowerCase;
    ParentShowHint := False;
    Password := False;
    ShowHint := True;
  end;

  { Password }
  Password := TNewStaticText.Create(WizardForm);
  with Password do
  begin
    Name := 'Password';
    Parent := WizardForm.PasswordPage;
    Cursor := crHand;
    Caption := ' PASSWORD IS : wave4tech ';
    Color := clGrayText;
    Font.Color := clWhite;
    Font.Height := -16;
    Font.Name := 'Tahoma';
    Font.Style := [fsBold];
    ParentColor := False;
    ParentFont := False;
    ParentShowHint := False;
    ShowHint := False;
    OnClick := @PasswordClick;
    Left := ScaleX(0);
    Top := ScaleY(80);
    Width := ScaleX(232);
    Height := ScaleY(20);
  end;

  Password.TabOrder := 3;

  with WizardForm.WizardBitmapImage2 do
  begin
    Height := ScaleY(312);
    ExtractTemporaryFile('WizardForm.WizardBitmapImage2.bmp');
    Bitmap.LoadFromFile(ExpandConstant('{tmp}\WizardForm.WizardBitmapImage2.bmp'));
  end;

  { Website }
  Website := TNewButton.Create(WizardForm);
  with Website do
  begin
    Name := 'Website';
    Parent := WizardForm;
    Left := ScaleX(153);
    Top := ScaleY(327);
    Width := ScaleX(75);
    Height := ScaleY(23);
    OnClick := @Website1Click;
  end;

  Website.TabOrder := 5;

{ ReservationBegin }
  // This part is for you. Add your specialized code here.

{ ReservationEnd }
end;
// Don't modify this section. It is generated automatically.
{ RedesignWizardFormEnd } // Don't remove this line!

procedure PasswordClick(Sender: TObject);
begin
MsgBox('The Password of this Setup is based on our Website Name. Its wave4tech in SMALL LETTERS !!', mbInformation, mb_Ok);
end;

procedure _BackButtonClick(Sender: TObject);
begin
  OldEvent_BackButtonClick(Sender);
end;

procedure _NextButtonClick(Sender: TObject);
begin
  OldEvent_NextButtonClick(Sender);
end;

// Importing Browser Identifier
procedure OpenBrowser(Url: string);
var
  ErrorCode: Integer;
begin
  ShellExec('open', Url, '', '', SW_SHOWNORMAL, ewNoWait, ErrorCode);
end;

// Website Button Link
procedure Website1Click(Sender: TObject);
begin
OpenBrowser('https://wave4technology.blogspot.com/');
end;

// Importing LoadSkin API from ISSkin.DLL
procedure LoadSkin(lpszPath: String; lpszIniFileName: String);
external 'LoadSkin@files:isskin.dll stdcall';

// Importing UnloadSkin API from ISSkin.DLL
procedure UnloadSkin();
external 'UnloadSkin@files:isskin.dll stdcall';

// Importing ShowWindow Windows API from User32.DLL
function ShowWindow(hWnd: Integer; uType: Integer): Integer;
external 'ShowWindow@user32.dll stdcall';

function InitializeSetup(): Boolean;
begin
    ExtractTemporaryFile('VZ_Green.cjstyles');
    LoadSkin(ExpandConstant('{tmp}\VZ_Green.cjstyles'), '');
    Result := True;
end;

procedure DeinitializeSetup();
begin
  // Hide Window before unloading skin so user does not get
  // a glimpse of an unskinned window before it is closed.
  ShowWindow(StrToInt(ExpandConstant('{wizardhwnd}')), 0);
  UnloadSkin();
end;

// Music Stop-Pause/Resume
const
  BASS_SAMPLE_LOOP = 4;
  BASS_ACTIVE_STOPPED = 0;
  BASS_ACTIVE_PLAYING = 1;
  BASS_ACTIVE_STALLED = 2;
  BASS_ACTIVE_PAUSED  = 3;
  BASS_UNICODE = 000000;
  BASS_CONFIG_GVOL_STREAM = 5;
const
  #ifndef UNICODE
    EncodingFlag = 0;
  #else
    EncodingFlag = BASS_UNICODE;
  #endif
type
  HSTREAM = DWORD;

function BASS_Init(device: LongInt; freq, flags: DWORD;
  win: HWND; clsid: Cardinal): Boolean;
  external 'BASS_Init@files:bass.dll stdcall';
function BASS_StreamCreateFile(mem: Boolean; f: string; offset1: DWORD;
  offset2: DWORD; length1: DWORD; length2: DWORD; flags: DWORD): HSTREAM;
  external 'BASS_StreamCreateFile@files:bass.dll stdcall';
function BASS_ChannelPlay(handle: DWORD; restart: Boolean): Boolean;
  external 'BASS_ChannelPlay@files:bass.dll stdcall';
function BASS_ChannelPause(handle: DWORD): Boolean;
  external 'BASS_ChannelPause@files:bass.dll stdcall';
function BASS_SetConfig(option: DWORD; value: DWORD ): Boolean;
  external 'BASS_SetConfig@files:bass.dll stdcall';
function BASS_ChannelIsActive(handle: DWORD): DWORD;
  external 'BASS_ChannelIsActive@files:bass.dll stdcall';

var
  SoundStream: HSTREAM;
  PauseResumePlayButton: TNewButton;
  StopButton: TNewButton;

procedure ResumeButtonClick(Sender: TObject); forward;

procedure PauseButtonClick(Sender: TObject);
begin
  if BASS_ChannelPause(SoundStream) then
  begin
    PauseResumePlayButton.Caption := 'Resume';
    PauseResumePlayButton.OnClick := @ResumeButtonClick;
  end;
end;

procedure ResumeButtonClick(Sender: TObject);
begin
  if BASS_ChannelPlay(SoundStream, False) then
  begin
    PauseResumePlayButton.Caption := 'Pause';
    PauseResumePlayButton.OnClick := @PauseButtonClick;
  end;
end;

procedure PlayButtonClick(Sender: TObject);
begin
  if BASS_ChannelPlay(SoundStream, True) then
  begin
    PauseResumePlayButton.Caption := 'Pause';
    PauseResumePlayButton.OnClick := @PauseButtonClick;
  end;
end;

procedure StopButtonClick(Sender: TObject);
begin
  if (BASS_ChannelIsActive(SoundStream) = BASS_ACTIVE_PAUSED) or
     BASS_ChannelPause(SoundStream) then
  begin
    PauseResumePlayButton.Caption := 'Play';
    PauseResumePlayButton.OnClick := @PlayButtonClick;
  end;
end;

// Splash Code 1
procedure ShowSplashScreen(p1:HWND;p2:string;p3,p4,p5,p6,p7:integer;p8:boolean;p9:Cardinal;p10:integer); external 'ShowSplashScreen@files:isgsg.dll stdcall delayload';

procedure InitializeWizard();
begin
  // Splash Code 2
  ExtractTemporaryFile('Splash.png');
  ShowSplashScreen(WizardForm.Handle,ExpandConstant('{tmp}\Splash.png'),1000,3000,1000,0,255,True,$FFFFFF,10);
  
  RedesignWizardForm;
  with WizardForm.WizardBitmapImage do
  begin
    Width := ScaleX(492);
    Visible := True;
  end;

  with WizardForm.WelcomeLabel2 do
  begin
    Visible := False;
  end;

  with WizardForm.WelcomeLabel1 do
  begin
    Visible := False;
  end;
  if BASS_Init(-1, 44100, 0, 0, 0) then
  begin
    ExtractTemporaryFile('AudioFile.mp3');
    SoundStream :=
      BASS_StreamCreateFile(
        False, ExpandConstant('{tmp}\AudioFile.mp3'), 0, 0, 0, 0,
        EncodingFlag or BASS_SAMPLE_LOOP);

    if SoundStream <> 0 then
    begin
      BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, 2500);

      if BASS_ChannelPlay(SoundStream, False) then
      begin
        StopButton := TNewButton.Create(WizardForm);
        StopButton.Parent := WizardForm;
        StopButton.Left :=
          WizardForm.ClientWidth -
          WizardForm.CancelButton.Left -  WizardForm.CancelButton.Width;
        StopButton.Top := WizardForm.CancelButton.Top;
        StopButton.Width :=  WizardForm.CancelButton.Width;
        StopButton.Height := WizardForm.CancelButton.Height;
        StopButton.Caption := 'Stop Music';
        StopButton.OnClick := @StopButtonClick;

        PauseResumePlayButton := TNewButton.Create(WizardForm);
        PauseResumePlayButton.Parent := WizardForm;
        PauseResumePlayButton.Left := ScaleX(80);
        PauseResumePlayButton.Top := ScaleY(327);
        PauseResumePlayButton.Width := ScaleX(75);
        PauseResumePlayButton.Height := ScaleY(23);
        PauseResumePlayButton.Caption := 'Pause Music';
        PauseResumePlayButton.OnClick := @PauseButtonClick;
      end;
    end;
  end;
end;

如果你想停止音乐,当安装程序关闭时,只需使用你已经StopButtonClick来自DeinitializeSetup的相同代码:

procedure DeinitializeSetup();
begin
  if (SoundStream <> 0) and
     (BASS_ChannelIsActive(SoundStream) <> BASS_ACTIVE_PAUSED) then
  begin
    BASS_ChannelPause(SoundStream);
  end;

  // Hide Window before unloading skin so user does not get
  // a glimpse of an unskinned window before it is closed.
  ShowWindow(StrToInt(ExpandConstant('{wizardhwnd}')), 0);
  UnloadSkin();
end;