我写了以下代码,以便在安装程序完成程序安装后逐渐淡出视频播放卷。
procedure CurPageChanged(CurPageID: Integer);
var
X: Integer;
begin
...
if CurPageID = wpFinished then
begin
VideoHandler.Release;
VideoHandler.Close;
DSSetVolume(-0);
X := 0;
repeat
DSSetVolume(X);
Log(IntToStr(X));
X = X - 1;
until X = -10000;
DSStopMediaPlay;
...
end;
...
end;
上面的代码输出X值,因为我希望逐渐减小音量,我可以在日志井中看到-1 , -2 ... -10000
。但是当这个重复过程开始时,
WizardForm
正常显示,但wpFinished
页面中未显示任何内容。只显示一个空表单。除WizardForm.Caption
之外,表格中没有任何内容。它表现得像冻结,直到重复过程(循环)结束。
音量永远不会正常降低或逐渐降序。
循环结束后,日志输出-10000
,WizardForm
正常显示,页面也正常显示。音量突然停止,因为我设置为DSStopMediaPlay
。
如何在没有任何冻结或异常的情况下正确执行上述过程(逐渐减少视频播放声音)?
更新
当用户的系统声音在Windows中的声音控制面板中设置为20%
时,以下代码可以提供最佳效果。
procedure VolumeFadeTimerProc(HandleW, msg, idEvent, TimeSys: LongWord);
begin
MPEGVideoVolume := MPEGVideoVolume - 15;
if MPEGVideoVolume < -4000 then
begin
DSStopMediaPlay;
KillTimer( 0, TimerID);
KillTimer( 0, VolumeFadeTimer);
Log('Volume Fade Timer has been reset.');
end
else
begin
Log('MPEG Video Volume has been set to: ' + IntToStr(MPEGVideoVolume));
DSSetVolume(MPEGVideoVolume);
end;
end;
减量量为15
最大减量量为-4000
当用户的系统声音在Windows中的声音控制面板中设置为100%
时,以下代码可以提供最佳效果。
procedure VolumeFadeTimerProc(HandleW, msg, idEvent, TimeSys: LongWord);
begin
MPEGVideoVolume := MPEGVideoVolume - 35;
if MPEGVideoVolume < -10000 then
begin
DSStopMediaPlay;
KillTimer( 0, TimerID);
KillTimer( 0, VolumeFadeTimer);
Log('Volume Fade Timer has been reset.');
end
else
begin
Log('MPEG Video Volume has been set to: ' + IntToStr(MPEGVideoVolume));
DSSetVolume(MPEGVideoVolume);
end;
end;
减量量为35
最大减少量金额为-10000
我是否需要根据用户系统声音设置的数量自动更改音量减少量和最大减少音量?
提前致谢。
答案 0 :(得分:1)
因为你在循环中停止了窗口消息泵。什么会冻结窗口,也可能会阻止音量淡出。
您必须使用计时器淡出音量而不冻结信息泵。
要实施计时器,请使用InnoCallback DLL。
[Files]
Source: InnoCallback.dll; Flags: dontcopy
[Code]
type
TTimerProc = procedure(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
function SetTimer(hWnd: longword; nIDEvent, uElapse: LongWord; lpTimerFunc: LongWord): LongWord; external 'SetTimer@user32.dll stdcall';
function WrapTimerProc(Callback: TTimerProc; ParamCount: Integer): LongWord; external 'wrapcallback@files:innocallback.dll stdcall';
var
Volume: Integer;
VolumeFadeTimer: LongWord;
procedure VolumeFadeTimerProc(H: LongWord; Msg: LongWord; IdEvent: LongWord; Time: LongWord);
begin
{ Fade by -1000 every 100 ms }
Volume := Volume - 1000;
if Volume <= -10000 then
begin
DSStopMediaPlay;
KillTimer(0, VolumeFadeTimer);
end
else
begin
DSSetVolume(Volume);
end;
end;
procedure CurPageChanged(CurPageID: Integer);
var
VolumeFadeCallback: LongWord;
begin
if CurPageID = wpFinished then
begin
VideoHandler.Release;
VideoHandler.Close;
Volume := 0;
VolumeFadeCallback := WrapTimerProc(@VolumeFadeTimerProc, 4);
{ call VolumeFadeCallback every 100 ms }
VolumeFadeTimer := SetTimer(0, 0, 100, VolumeFadeCallback);
DSSetVolume(Volume);
end;
end;