Как сделать кнопки остановки и паузы / возобновления / воспроизведения музыки в Inno Setup

Я хочу создать две кнопки рядом друг с другом в нижнем левом углу всех страниц, например, перезагрузить.

На первой кнопке отображаются команды Пауза и Возобновить (если я нажму Пауза, кнопка переключится на Возобновить автоматически).

Другая кнопка показывает команду Стоп (если я нажму Стоп, следующая кнопка автоматически переключится на Воспроизвести с начала)

Этот код просто добавляет кнопку Пауза / Возобновить / Воспроизведение с начала * и кнопку Стоп.

Проблема в том, что если я нажму кнопку Стоп, воспроизведение музыки прекратится навсегда, а кнопка Запуск формы никогда не появится.

    [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;

person Muhammad Gibriel    schedule 07.09.2016    source источник
comment
Вы не можете попросить помощи у конкретного пользователя, который не участвовал в обсуждении. Наберитесь терпения, и кто-нибудь поможет вам, когда сможет. Если вы не можете ждать, наймите подрядчика и заплатите ему, чтобы он разобрался за вас. (Мне всегда непонятно, почему люди хотят проигрывать музыку из установщика - его задача - устанавливать программное обеспечение, а не быть центром домашних развлечений. Вы вводите зависимость от Bass.DLL, чтобы быть установленная до вашего программного обеспечения, вы увеличиваете загрузку (тратя впустую полосу пропускания) и делаете установку намного медленнее, даже не считая дополнительной работы, которую вы делаете сейчас.)   -  person Ken White    schedule 09.09.2016
comment
Bass.DLL - это всего лишь 33,5 КБ, не так уж и много места. и загрузка действительно велика, поэтому несколько килобайт, добавленных к гигантским файлам, не повредят. установка займет не менее 15 минут, поэтому было бы неплохо включить музыку во время установки   -  person Muhammad Gibriel    schedule 09.09.2016
comment
Его также необходимо сначала установить, и вы также должны включить все звуковые файлы. Вы можете воспроизводить музыку, включив пару небольших файлов .wav, и воспроизводить их с помощью Windows MMAPI, не требуя установки. Пользователям не нужно приостанавливать, перематывать, запускать и останавливать звуки во время установки - это превращает ваш установщик в медиаплеер. Вы делаете то же самое, что создаете краску для нанесения на вещи, когда вы выбрасываете их в мусор - их не будет рядом, кроме нескольких минут, но, боже, они будут красивыми, пока они существуют! Используйте ваш установщик для установки.   -  person Ken White    schedule 09.09.2016


Ответы (2)


Не рекомендуется реализовывать это с помощью одного 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_StreamCreateFile, BASS_SetConfig и BASS_ChannelPlay с одними и теми же аргументами. Это не имеет смысла. Я снял второй комплект.
  • Я также изменил расположение кнопок.

Кнопки управления музыкой

person Martin Prikryl    schedule 09.09.2016
comment
ResumeButtonClick - это не проблема, это StopButtonClick, если я нажимаю кнопку остановки, музыка останавливается, а затем запускается мгновенно, нажимая кнопку воспроизведения см. мой обновленный код - person Muhammad Gibriel; 13.09.2016
comment
Ну, потому что ваш StopButtonClick не делает того, что показывает мой ответ. Вы звоните BASS_Play, поэтому вас не удивит, что ваша кнопка остановки начинает играть. - person Martin Prikryl; 13.09.2016
comment
так как это изменить? я хочу сделать следующее: если я нажму кнопку остановки, музыка не будет воспроизводиться, пока я не нажму кнопку воспроизведения помогите, пожалуйста - person Muhammad Gibriel; 13.09.2016
comment
Так что используйте код из моего ответа! Он делает то, о чем вы просите! - person Martin Prikryl; 13.09.2016
comment
нет. Если я нажму кнопку воспроизведения после нажатия кнопки остановки, песня не запустится с начала, сравните мой обновленный код с вашим, и вы увидите, что пауза / возобновление не работает должным образом, а кнопка остановки не запускает песню после того, как я нажмите кнопку воспроизведения - person Muhammad Gibriel; 13.09.2016
comment
Я не понимаю тебя. Извините. Я сдаюсь. - person Martin Prikryl; 13.09.2016
comment
вы можете скомпилировать код, и вы поймете, о чем я? - person Muhammad Gibriel; 13.09.2016
comment
Хорошо, теперь я понимаю, что вы имеете в виду, прежде чем использовать неправильный код, но теперь вы ссылаетесь на мой код. См. Мой обновленный ответ. - person Martin Prikryl; 14.09.2016

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;

и на кнопке. OnClick добавить вот так:

  YourButtonName.OnClick := @MusicButtonOnClick;
person Death GOD 7    schedule 06.01.2020