如何在 Inno Setup 中制作停止和暂停/恢复/播放音乐按钮

Posted

技术标签:

【中文标题】如何在 Inno Setup 中制作停止和暂停/恢复/播放音乐按钮【英文标题】:How to make Stop and Pause/Resume/Play music buttons in Inno Setup 【发布时间】:2017-01-14 21:38:01 【问题描述】:

我想在所有页面的左下角创建两个彼此相邻的按钮,例如重新加载。

第一个按钮显示PauseResume命令(如果我点击Pause,按钮会切换到Resume 自动)。

另一个按钮显示停止命令(如果我点击停止,下一个按钮会自动切换到从开始播放

这段代码只是添加了 Pause/Resume/Play from start* 按钮和 Stop 按钮

问题是:如果我按下 Stop 按钮,音乐将永久停止,并且 Play form start 按钮永远不会出现。

    [Setup]
AppName=Bass Audio Project
AppVersion=1.0
DefaultDirName=pf\Bass Audio Project

[Files]
Source: Bass.dll; Flags: dontcopy
Source: AudioFile.mp3; Flags: dontcopy


[Code]
const
  BASS_SAMPLE_LOOP = 4;
  BASS_ACTIVE_STOPPED = 0;
  BASS_ACTIVE_PLAYING = 1;
  BASS_ACTIVE_STALLED = 2;
  BASS_ACTIVE_PAUSED  = 3;
  BASS_UNICODE = $80000000;
  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): BOOL;
  external 'BASS_Init@files:bass.dll stdcall';
function BASS_StreamCreateFile(mem: BOOL; f: string; offset1: DWORD;
  offset2: DWORD; length1: DWORD; length2: DWORD; flags: DWORD): HSTREAM;
  external 'BASS_StreamCreateFile@files:bass.dll stdcall';
function BASS_Start: BOOL;
  external 'BASS_Start@files:bass.dll stdcall';
function BASS_Pause: BOOL;
  external 'BASS_Pause@files:bass.dll stdcall';
function BASS_Stop(): Boolean;
  external 'BASS_Stop@files:BASS.dll stdcall delayload';
function BASS_ChannelPlay(handle: DWORD; restart: BOOL): BOOL;
  external 'BASS_ChannelPlay@files:bass.dll stdcall';
function BASS_SetConfig(option: DWORD; value: DWORD ): BOOL;
  external 'BASS_SetConfig@files:bass.dll stdcall';
function BASS_ChannelIsActive(handle: DWORD): DWORD;
  external 'BASS_ChannelIsActive@files:bass.dll stdcall';
function BASS_Free: BOOL;
  external 'BASS_Free@files:bass.dll stdcall';

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

procedure ResumeButtonClick(Sender: TObject); forward;

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

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

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


procedure StopButtonClick(Sender: TObject);
begin
  if BASS_Stop then
  begin
    PauseResumePlayButton.Caption := 'Play';
    PauseResumePlayButton.OnClick := @PlayButtonClick;
  end;
       begin
       BASS_Free;
       end;
end;

procedure InitializeWizard();
begin
  ExtractTemporaryFile('AudioFile.mp3');
  if BASS_Init(-1, 44100, 0, 0, 0) then
  begin
    SoundStream :=
      BASS_StreamCreateFile(
        False, ExpandConstant('tmp\AudioFile.mp3'), 0, 0, 0, 0,
        EncodingFlag or BASS_SAMPLE_LOOP);
    BASS_SetConfig(BASS_CONFIG_GVOL_STREAM, 2500);
    BASS_ChannelPlay(SoundStream, False);

    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';
    StopButton.OnClick := @StopButtonClick;

    PauseResumePlayButton := TNewButton.Create(WizardForm);
    PauseResumePlayButton.Parent := WizardForm;
    PauseResumePlayButton.Left :=
      WizardForm.ClientWidth -
      WizardForm.NextButton.Left - WizardForm.NextButton.Width;
    PauseResumePlayButton.Top := WizardForm.CancelButton.Top;
    PauseResumePlayButton.Width :=  WizardForm.CancelButton.Width;
    PauseResumePlayButton.Height := WizardForm.CancelButton.Height;
    PauseResumePlayButton.Caption := 'Pause';
    PauseResumePlayButton.OnClick := @PauseButtonClick;
  end;
end;

procedure DeinitializeSetup;
begin
  BASS_Free;
end;

【问题讨论】:

您不能要求未参与该主题的特定用户提供帮助。要有耐心,有人会在可能的时候帮助你。如果您等不及,请聘请承包商并付钱让他们为您解决问题。 (我总是不清楚人们为什么要从安装程序播放音乐 - 它的工作是安装软件,而不是成为家庭娱乐中心。你引入了对 Bass.DLL 的依赖在您的软件之前安装,您正在使下载量更大(浪费带宽),并且使安装速度更慢,甚至不计算您现在正在做的额外工作。) Bass.DLL 只有 33.5kb,空间不大。并且下载量确实很大,因此添加到巨大文件中的几千字节不会受到伤害。安装至少需要 15 分钟才能完成,因此最好在安装过程中播放音乐 它也必须先安装,并且您还必须包含所有的声音文件。您可以通过包含几个小的 .wav 文件来播放音乐,并使用 Windows MMAPI 播放它们,而无需安装。用户无需在安装过程中暂停、倒带、开始和停止声音 - 这将您的安装程序变成了媒体播放器。当你把它们扔进垃圾箱时,你所做的相当于创造油漆来涂上东西——它们只会出现几分钟,但男孩们会在它们持续存在的时候变得漂亮!使用您的安装程序进行安装。 【参考方案1】:

使用单个 OnClick 处理程序来实现它不是一个好主意。

根据需要即时更改 OnClick 处理程序,以获得更直接的代码:

const
  BASS_SAMPLE_LOOP = 4;
  BASS_ACTIVE_STOPPED = 0;
  BASS_ACTIVE_PLAYING = 1;
  BASS_ACTIVE_STALLED = 2;
  BASS_ACTIVE_PAUSED  = 3;
  BASS_UNICODE = $80000000;
  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;  

procedure InitializeWizard();
begin
  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';
        StopButton.OnClick := @StopButtonClick;

        PauseResumePlayButton := TNewButton.Create(WizardForm);
        PauseResumePlayButton.Parent := WizardForm;
        PauseResumePlayButton.Left :=
          WizardForm.ClientWidth -
          WizardForm.NextButton.Left -  WizardForm.NextButton.Width;
        PauseResumePlayButton.Top := WizardForm.CancelButton.Top;
        PauseResumePlayButton.Width :=  WizardForm.CancelButton.Width;
        PauseResumePlayButton.Height := WizardForm.CancelButton.Height;
        PauseResumePlayButton.Caption := 'Pause';
        PauseResumePlayButton.OnClick := @PauseButtonClick;
      end;
    end;
  end;
end;
请注意,您使用相同的参数调用了两次BASS_StreamCreateFileBASS_SetConfigBASS_ChannelPlay。它没有任何意义。我已经删除了第二组。 我还调整了按钮的位置。

【讨论】:

ResumeButtonClick 不是问题,它是 StopButtonClick 如果我单击停止按钮,音乐停止然后立即运行白屏,单击播放按钮查看我更新的代码 好吧,因为您的 StopButtonClick 没有按照我的回答显示。你打电话给BASS_Play,所以你不会对你的停止按钮开始播放感到惊讶。 那么如何改变呢? 我想做的是:如果我点击停止按钮,除非我点击播放按钮,否则音乐不会播放请帮助 所以使用我回答中的代码!它可以满足您的要求! 没有。如果我在单击停止后单击播放,则歌曲不会从开头开始将我更新的代码与您的代码进行比较,您会看到暂停/恢复无法正常工作,并且停止按钮不会在我之后开始播放歌曲点击播放按钮【参考方案2】:
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_ChannelIsActive(handle: DWORD): DWORD;
  external 'BASS_ChannelIsActive@files:bass.dll stdcall';

procedure MusicButtonOnClick(Sender: TObject);
begin
  if (BASS_ChannelIsActive(SoundStream) = 3)
 then
  BASS_ChannelPlay(SoundStream, False)
 else
  BASS_ChannelPause(SoundStream) 
end;

然后在 button.OnClick 上添加如下:

  YourButtonName.OnClick := @MusicButtonOnClick;

【讨论】:

以上是关于如何在 Inno Setup 中制作停止和暂停/恢复/播放音乐按钮的主要内容,如果未能解决你的问题,请参考以下文章

inno setup安装包制作问题?

如何使用Inno Setup Compiler制作安装软件包

如何使用Inno Setup Compiler制作安装软件包

如何使用Inno Setup Compiler制作安装软件包

如何使用Inno Setup Compiler制作安装软件包

Inno Setup 5 安装包制作!reg2iss,Inno Setup 问题。Inno Setup 怎么批量导入reg文件,(像nsis