procedure LoadBtnBmp( image: TImage; const name: string );
begin
image.Picture.Bitmap.LoadFromResourceName( HInstance, name );
end;
procedure TCDPlayerForm.GetTotalTime;
var
i: Integer;
begin
Player.TimeFormat := tfMSF;
TotalTime := 0;
for i := 1 to UserTracks do
begin
tmp := Player.TrackLength[TrackOrder[i]];
Inc( TotalTime, Lo(tmp) * 60 );
Inc( TotalTime, Hi(tmp) );
end;
Player.TimeFormat := tfTMSF;
LastTrack := (Player.TrackLength[TrackOrder[i]] shl 8) + TrackOrder[i];
end;
procedure TCDPlayerForm.ShowTimeMode;
var
x: Integer;
s: string;
begin
x := 550;
case TimeMode of
smTime: s := 'TIME';
smTotalTime: s := 'TOTAL TIME';
smRemaining: s := 'REMAINING TIME';
smTotalRemaining: s := 'TOTAL REMAINING TIME';
smTotal: s := 'TOTAL';
end;
with Canvas do
begin
Font.Height := -9;
Font.Size := 5;
Brush.Color := clBlack;
FillRect(Rect(550 - TextWidth( 'TOTAL REMAINING TIME' ), 18, 550, 27 ));
x := x - TextWidth( s );
Font.Color := clLime;
TextOut( x, 18, s );
end;
end;
procedure TCDPlayerForm.CloseDoor;
var
SetParm: TMCI_Set_Parms;
Flags: Longint;
FError: Longint;
begin
Flags := mci_Notify or mci_Set_Door_Closed;
SetParm.dwCallback := Player.Handle;
FError := mciSendCommand( Player.DeviceID, mci_Set, Flags, Longint(@SetParm) );
GetNewCDInfo;
end;
procedure TCDPlayerForm.CDPlay;
begin
if Player.Mode <> mpPlaying then
begin
GetTotalTime;
Player.Play;
PMode := mpPlaying;
ImagePlayArrow.Visible := True;
end;
end;
procedure TCDPlayerForm.CDPause;
begin
if PMode in [mpPlaying,mpPaused] then
begin
if PMode = mpPlaying then
begin
Player.Pause;
ImagePauseBtn.Hint := '恢复';
ImagePlayBtn.Hint := '恢复';
PMode := mpPaused;
end
else
begin
Player.Resume; // 无法再用 Pause 恢复播放, 要用 Resume
ImagePauseBtn.Hint := '暂停';
ImagePlayBtn.Hint := '播放';
PMode := mpPlaying;
end;
end;
end;
procedure TCDPlayerForm.CDStop;
begin
Player.Stop;
PlayTrack := TrackOrder[1];
if RandomMode then
begin
Player.StartPos := Player.TrackPosition[PlayTrack];
Player.Play;
Player.Stop;
end
else
Player.Rewind; // 记得要回到最前面
PMode := mpStopped;
ImagePlayArrow.Visible := False;
LoadBtnBmp( ImagePlayBtn, 'playbu' );
oldTrack := PlayTrack;
DrawTrack;
end;
function TCDPlayerForm.GetTrackBySecond(sec: Integer): Integer;
var
i: Integer;
tmp: Longint;
begin
for i := 1 to Player.Tracks do
begin
tmp := Player.TrackLength[i];
Dec( sec, Lo(tmp) * 60 );
Dec( sec, Hi(tmp) );
if sec <= 0 then
begin
Result := i;
Exit;
end;
end;
end;
procedure TCDPlayerForm.CDBack;
var
tt: Longint;
t: Integer;
f: boolean;
begin
if Player.Mode = mpPlaying then
begin
Player.TimeFormat := tfMilliseconds;
tmp := Player.Position;
if Player.Position < 10000 then // 预设倒退 10 秒
Player.StartPos := 0
else
Player.StartPos := Player.Position - 10000;
if RandomMode then
begin
f := False;
Player.TimeFormat := tfTMSF;
t := GetTrackBySecond( Player.StartPos div 1000 );
if (t <> PlayTrack) or (Player.StartPos = 0) then
begin
t := GetTrackIndex( PlayTrack );
if t = 1 then
begin
PlayTrack := TrackOrder[1];
if ImageRepeat.Visible = False then
f := True;
end
else
PlayTrack := TrackOrder[t - 1];
Player.StartPos := Player.TrackPosition[PlayTrack];
end
else
Player.TimeFormat := tfMilliseconds;
end
else
f := False;
Player.Play;
if f then
Player.Stop;
Player.TimeFormat := tfTMSF;
if not RandomMode then
PlayTrack := Lo( Player.Position );
end;
end;
procedure TCDPlayerForm.CDStep;
var
tt: Longint;
t: Integer;
f: boolean;
begin
if Player.Mode = mpPlaying then
begin
Player.TimeFormat := tfMilliseconds; // 预设前进 10 秒
tmp := Player.Position;
if Player.Position + 10000 > Player.Length then
Player.StartPos := Player.Length - 1000
else
Player.StartPos := Player.Position + 10000;
if RandomMode then
begin
f := False;
Player.TimeFormat := tfTMSF;
t := GetTrackBySecond( Player.StartPos div 1000 );
if t <> PlayTrack then // 播到第一音轨後若无连续播放毕须设
begin // 定停止旗标 f
t := GetTrackIndex( PlayTrack );
if t = UserTracks then
begin
PlayTrack := TrackOrder[1];
if ImageRepeat.Visible = False then
f := True;
end
else
PlayTrack := TrackOrder[t + 1];
Player.StartPos := Player.TrackPosition[PlayTrack];
end
else
Player.TimeFormat := tfMilliseconds;
end
else
f := False;
Player.Play;
if f then
Player.Stop;
Player.TimeFormat := tfTMSF;
if not RandomMode then
PlayTrack := Lo( Player.Position );
end;
end;
procedure TCDPlayerForm.CDPrev;
var
t: Integer;
begin
if RandomMode then
begin
t := GetTrackIndex( PlayTrack );
if t = 1 then
t := UserTracks
else
begin
if UserTracks > 1 then
Dec( t );
end;
PlayTrack := TrackOrder[t];
Player.StartPos := Player.TrackPosition[PlayTrack];
Player.Play;
if PMode <> mpPlaying then
Player.Stop;
end
else
begin
Player.Previous;
PlayTrack := Lo( Player.Position );
end;
end;
procedure TCDPlayerForm.CDNext;
var
t: Integer;
begin
if RandomMode then
begin
t := GetTrackIndex( PlayTrack );
if t = UserTracks then
t := 1
else
begin
if UserTracks > 1 then
Inc( t );
end;
PlayTrack := TrackOrder[t];
Player.StartPos := Player.TrackPosition[PlayTrack];
Player.Play;
if PMode <> mpPlaying then
Player.Stop;
end
else
begin
Player.Next;
PlayTrack := Lo( Player.Position );
end;
end;
procedure TCDPlayerForm.CDVolumeInc;
var
volume: Cardinal;
begin
auxGetVolume( Player.DeviceID, @volume );
if $FFFF - WORD(volume) < $1000 then
begin
volume := $FFFF;
volume := (volume shl 16) + $FFFF;
end
else
volume := volume + $10001000;
auxSetVolume( Player.DeviceID, volume );
end;
procedure TCDPlayerForm.CDVolumeDec;
var
volume: Cardinal;
begin
auxGetVolume( Player.DeviceID, @volume );
if WORD(volume) < $1000 then
volume := 0
else
volume := volume - $10001000;
auxSetVolume( Player.DeviceID, volume );
end;
procedure TCDPlayerForm.CDDoorCtrl;
begin
if Player.Mode = mpOpen then
begin
CloseDoor;
ImageEjectBtn.Hint := '退出';
end
else
begin
LoadBtnBmp( ImagePlayBtn, 'playbu' );
Player.Eject;
ImageEjectBtn.Hint := '进入';
end;
PMode := mpOpen;
end;
procedure TCDPlayerForm.CDTimeFormat;
begin
oldTime := 0;
if TimeMode >= smTotal then
TimeMode := smTime
else
Inc(TimeMode);
ShowTimeMode;
if TimeMode in [smTotalTime, smTotal, smTotalRemaining] then
GetTotalTime;
if PMode <> mpPlaying then
begin
OldTime := 0;
DrawTrackAndTime;
end;
end;
procedure TCDPlayerForm.CDRandom;
var
i, j, r, ts, f: Integer;
begin
ImageRandom.Visible := not ImageRandom.Visible;
RandomMode := ImageRandom.Visible;
ts := UserTracks;
if RandomMode = True then
begin
for i := 1 to ts do
TrackOrder[i] := 0;
for i := 1 to ts do
begin
repeat
f := 1;
r := Random( ts ) + 1;
for j := 1 to i do
if TrackOrder[j] = r then
begin
f := 0;
Break;
end;
until f = 1;
TrackOrder[i] := r;
end;
end
else
for i := 1 to ts do
TrackOrder[i] := i;
if PMode <> mpPlaying then
begin
Player.StartPos := Player.TrackPosition[TrackOrder[1]];
Player.Play;
Player.Stop;
end;
PlayTrack := Lo(Player.Position);
DrawTrackAndTime;
DrawTrack;
GetTotalTime;
end;
procedure TCDPlayerForm.CDPreview;
begin
ImagePreview.Visible := not ImagePreview.Visible;
PreviewMode := ImagePreview.Visible;
ImageRepeatOnce.Visible := False;
end;
procedure TCDPlayerForm.CDRepeat;
begin
ImageRepeat.Visible := not ImageRepeat.Visible;
ImageRepeatOnce.Visible := False;
end;
procedure TCDPlayerForm.CDRepeatOnce;
begin
ImageRepeatOnce.Visible := not ImageRepeatOnce.Visible;
ImagePreview.Visible := False;
ImageRepeat.Visible := False;
PreviewMode := False;
if ImageRepeatOnce.Visible then
RepeatTrack := Lo(Player.Position);
end;
function TCDPlayerForm.GetTrackTime( track: Integer ): Integer;
var
i, sec, n: Integer;
tmp: Longint;
begin
sec := 0;
n := GetTrackIndex(track) - 1;
for i := 1 to n do
begin
tmp := Player.TrackLength[TrackOrder[i]];
Inc( sec, Lo(tmp) * 60 );
Inc( sec, Hi(tmp) );
end;
Result := sec;
end;
procedure TCDPlayerForm.DrawTrackAndTime;
var
track, min, sec, t, ts: Integer;
tt: Longint;
begin
if FirstShow then
begin
FirstShow := False;
ShowTimeMode;
end;
if Player.Mode in [mpNotReady,mpStopped,mpPlaying,mpRecording,mpSeeking,mpPaused,mpOpen] then
begin
if (PMode = mpPlaying) and (Player.Mode in [mpOpen,mpNotReady]) then
begin
LoadBtnBmp( ImagePlayBtn, 'playbu' );
ImagePlayArrow.Visible := False;
PMode := mpOpen;
end;
if (Player.Mode in [mpOpen,mpNotReady]) and (mpPaused <> PMode) then
tmp := 0
else
tmp := Player.Position;
if oldTime <> tmp then
begin
track := Lo(tmp);
if (ImageRepeatOnce.Visible = True) and (track <> RepeatTrack) then
Exit;
if TimeMode in [smTotalRemaining,smTotalTime] then
t := GetTrackTime( track );
min := Hi(tmp);
sec := Lo(tmp shr 16);
with ImageLedLNum do
begin
if not TaskIconed then
begin
Draw(Canvas, 417, 34, track div 10 );
Draw(Canvas, 435, 34, track mod 10 );
end;
case TimeMode of
smTotalRemaining:
begin
ts := TotalTime - (t + min * 60 + sec);
min := ts div 60;
sec := ts mod 60;
end;
smTotalTime:
begin
ts := t + min * 60 + sec;
min := ts div 60;
sec := ts mod 60;
end;
smRemaining:
begin
tt := Player.TrackLength[track];
ts := Lo(tt) * 60 + Hi(tt) - min * 60 - sec;
min := ts div 60;
sec := ts mod 60;
end;
smTotal:
begin
min := TotalTime div 60;
sec := TotalTime mod 60;
end;
end;
if TaskIconed then
begin
Application.Title := Format( 'Solar HiFi [%2.2d] %2.2d:%2.2d', [track, min, sec] );
end
else
begin
Draw(Canvas, 474, 34, min div 10 );
Draw(Canvas, 492, 34, min mod 10 );
Draw(Canvas, 519, 34, sec div 10 );
Draw(Canvas, 537, 34, sec mod 10 );
end;
end;
oldTime := tmp;
if oldTrack <> track then
begin
oldTrack := track;
if not RandomMode then
PlayTrack := track;
DrawTrack;
end;
end;
end;
end;
procedure TCDPlayerForm.DrawTrack;
var
ot, rx, x, i: Integer;
s, rs: string;
m: TMPModes;
f: boolean;
begin
if TaskIconed then
Exit;
f := False;
{ tracks := Player.Tracks;}
if RandomMode then
begin
for i := 1 to UserTracks do
begin
if oldTrack = TrackOrder[i] then
begin
ot := i;
break;
end;
end;
end
else
ot := oldTrack;
startTrack := (ot - 1) div 12 * 12 + 1;
Canvas.Font.Height := -11;
Canvas.Font.Size := 6;
x := 340;
m := Player.Mode;
Canvas.Font.Color := clYellow;
for i := startTrack to startTrack + 11 do
begin
if (i > UserTracks) or (m in [mpOpen,mpNotReady]) then
s := ' '
else
s := Format( '%2d ', [TrackOrder[i]] );
if TrackOrder[i] = oldTrack then
begin
rx := x;
rs := Format( '%2d', [TrackOrder[i]] );
f := True;
end;
Canvas.TextOut( x, 68, s );
Inc( x, 18 );
end;
if f then
begin
Canvas.Font.Color := clRed;
Canvas.TextOut( rx, 68, rs );
end;
end;
procedure TCDPlayerForm.ImagePlayBtnMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Player.Mode = mpPlaying then
LoadBtnBmp( ImagePlayBtn, 'playbau' )
else
LoadBtnBmp( ImagePlayBtn, 'playbu' );
end;
procedure TCDPlayerForm.ImagePlayBtnMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Player.Mode = mpPlaying then
LoadBtnBmp( ImagePlayBtn, 'playbad' )
else
LoadBtnBmp( ImagePlayBtn, 'playbd' );
end;
function TCDPlayerForm.GetUserTracks: Integer;
begin
Result := Player.Tracks;
end;
procedure TCDPlayerForm.FormShow(Sender: TObject);
begin
if FirstShow then
begin
PreviewMode := False;
RandomMode := False;
Canvas.Font.Name := 'Arial';
Color := clWindowText;
{ Color := clNone;}
CDTimer.Enabled := True;
Player.TimeFormat := tfTMSF;
CDTimer.Enabled := False;
try
Player.Open;
except
on EMCIDeviceError do
begin
Application.MessageBox( '请关闭其他使用中的CD播放程式.', 'Solar HiFi',
MB_APPLMODAL + MB_ICONWARNING + MB_OK );
Application.Terminate;
end;
end;
CDTimer.Enabled := True;
UserTracks := GetUserTracks;
GetTotalTime;
oldTime := 0;
oldTrack := 0;
PMode := Player.Mode;
if Player.Mode = mpPlaying then
begin
LoadBtnBmp( ImagePlayBtn, 'playbau' );
ImagePlayArrow.Visible := True;
end
else
LoadBtnBmp( ImagePlayBtn, 'playbu' );
PlayTrack := Lo(Player.Position);
end;
end;
procedure TCDPlayerForm.PlayerNotify(Sender: TObject);
begin
DrawTrackAndTime;
Player.Notify := True;
end;
function TCDPlayerForm.GetTrackIndex(track: Integer): Integer;
var
i: Integer;
begin
for i := 1 to UserTracks do
begin
if track = TrackOrder[i] then
begin
Result := i;
Exit;
end;
end;
end;
procedure TCDPlayerForm.GetNewCDInfo;
begin
while ( Player.Mode in [mpOpen, mpNotReady]) do;
GetTotalTime;
UserTracks := GetUserTracks;
oldTime := 0;
oldTrack := 0;
PMode := Player.Mode;
if RandomMode then CDRandom;
DrawTrackAndTime;
DrawTrack;
end;
procedure TCDPlayerForm.CDTimerTimer(Sender: TObject);
var
t: Integer;
ff, f: boolean;
begin
if (PMode = mpOpen) and (Player.Mode <> mpOpen) then
GetNewCDInfo;
with Player do
begin
tmp := Position;
ff := ((PreviewMode) and ((Hi(tmp) > 1) or (Lo(tmp shr 16) >= 20)));
f := (PlayTrack = TrackOrder[UserTracks]);
{ if ( (PlayTrack = TrackOrder[UserTracks]) and ((PlayTrack <> Lo(tmp)) or (ff)) ) or
( (Position = LastTrack) or ( (ff) and (Lo(tmp) = TrackOrder[UserTracks])) ) then}
{ if ( (PlayTrack = TrackOrder[UserTracks]) and ((PlayTrack <> Lo(tmp)) or (ff)) ) or
( (Position = LastTrack) and (RandomMode = False) ) then}
if ( (f) and ((PlayTrack <> Lo(tmp)) or (ff)) ) or
( (PMode = mpPlaying) and (Player.Mode = mpStopped) ) then
begin
ff := False;
if RandomMode then
begin
t := GetTrackIndex( PlayTrack );
if t <> UserTracks then
StartPos := TrackPosition[TrackOrder[t + 1]]
else
StartPos := TrackPosition[TrackOrder[1]];
Play;
{ Stop;}
end
else
Rewind;
if ImageRepeat.Visible = True then
begin
ImagePlayArrow.Visible := True;
Play;
end
else
begin
Stop;
ImagePlayArrow.Visible := False;
LoadBtnBmp( ImagePlayBtn, 'playbu' );
PMode := mpStopped;
end;
PlayTrack := Lo(Position);
end;
if (ImageRepeatOnce.Visible = True) and (Lo(tmp) <> RepeatTrack) then
begin
StartPos := TrackPosition[RepeatTrack];
Play;
end;
{ if (RandomMode = True) and (Lo(tmp) <> PlayTrack) then}
if ff or ((RandomMode = True) and (Lo(tmp) <> PlayTrack)) then
begin
t := GetTrackIndex( PlayTrack );
PlayTrack := TrackOrder[t + 1];
StartPos := TrackPosition[PlayTrack];
Play;
end;
end;
DrawTrackAndTime;
{ if Player.Mode = mpPlaying then
begin
Top := Top + ddy;
ddy := ddy * -1;
end;}
end;
procedure TCDPlayerForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
CDTimer.Enabled := False;
Player.Close;
end;
procedure TCDPlayerForm.FormPaint(Sender: TObject);
begin
if TaskIconed then
begin
TaskIconed := False;
Application.Title := 'Solar HiFi';
oldTime := 0;
oldTrack := 0;
end;
Canvas.Draw( 0, 0, BackGround );
ShowTimeMode;
OldTime := 0;
DrawTrackAndTime;
DrawTrack;
end;
procedure TCDPlayerForm.FormCreate(Sender: TObject);
var
i: Integer;
hMenu: HMENU;
p: Cardinal;
ip: PTImage;
begin
ddy := 1;
for i := 1 to 40 do
TrackOrder[i] := i;
Randomize;
FirstShow := True;
BeginDrag := False;
TaskIconed := False;
BackGround := TBitmap.Create;
BackGround.LoadFromResourceName( HInstance, 'BACKGROUND' );
Screen.Cursors[crMyCursor] := LoadCursor( HInstance, 'CD_CURSOR' );
p := Cardinal( @ImagePlayBtn );
i := 0;
while p <= Cardinal( @ImageEjectBtn ) do
begin
PTImage( p )^.Cursor := crMyCursor;
PTImage( p )^.Tag := i;
Inc( i );
Inc( p, sizeof( PTImage ) );
end;
Application.OnMessage := AppMessage;
{ hMenu := GetSystemMenu( Application.handle, FALSE );
AppendMenu( hMenu, MF_SEPARATOR, 0, NIL );
AppendMenu( hMenu, MF_BITMAP, IDM_PLAY, PChar( ImagePlayArrow.Picture.Bitmap.Handle) );
}
end;
procedure TCDPlayerForm.FormDestroy(Sender: TObject);
begin
DestroyCursor( crMyCursor );
BackGround.Destroy;
end;
procedure TCDPlayerForm.FormMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
BeginDrag := True;
bx := x;
by := y;
end;
end;
procedure TCDPlayerForm.Move( dx: Integer; dy: Integer );
begin
Left := Left + dx;
Top := Top + dy;
Lf1.Left := Left + 7;
Lf1.Top := Top + 137;
Lf2.Left := Left;
Lf2.Top := Top + 136 + 4;
Rf1.Left := Left + 462;
Rf1.Top := Lf1.Top;
Rf2.Left := Left + 455;
Rf2.Top := Lf2.Top;
end;
procedure TCDPlayerForm.FormMouseMove(Sender: TObject; Shift: TShiftState;
X, Y: Integer);
begin
if BeginDrag then
Move( x - bx, y - by );
end;
procedure TCDPlayerForm.FormMouseUp(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
begin
if Button = mbLeft then
begin
BeginDrag := False;
ShowTimeMode;
DrawTrack;
Move( 0, 0 );
ddy := 1;
end;
end;
procedure TCDPlayerForm.AppMessage(var Msg: TMsg; var Handled: Boolean);
begin
if (Msg.message = WM_SYSCOMMAND) and (Msg.wParam = SC_MINIMIZE) and (Msg.hwnd = Application.Handle) then
begin
TaskIconed := True;
end;
end;
procedure TCDPlayerForm.ImageBtnMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
p: PTImage;
begin
p := PTImage( Cardinal(@ImagePlayBtn) + TImage(Sender).Tag * sizeof(PTImage) );
LoadBtnBmp( P^, btnResName2[p^.Tag] );
end;
procedure TCDPlayerForm.ImageBtnMouseUp(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var
p: PTImage;
begin
p := PTImage( Cardinal(@ImagePlayBtn) + TImage(Sender).Tag * sizeof(PTImage) );
LoadBtnBmp( P^, btnResName1[p^.Tag] );
end;