📄 cd.pas
字号:
{ Time Left on CD }
CDRemaining:=CurrentCD.CDLength - CDPosition;
{ Time Left on Track }
CurRemaining:=CurrentCD.TrackDetail[CurrentTrack].TrackLength -
TrackPosition;
end;
{ Update the timer display with the currently selected time }
procedure PositionDisplay;
var
TheTime: longint;
begin
{ Depending on the timer mode currently selected
Get the time to display }
case TimerMode of
tmTrackLeft: TheTime:=CurRemaining;
tmCDGone: TheTime:=CDPosition;
tmCDLeft: TheTime:=CDRemaining;
else { and tmTrackGone: }
TheTime:=TrackPosition;
end;
SetTimerTrack(TheTime Div 1000,CurrentTrack);
end;
{ Get the status of the CD Player, or leave it unchanged if unknown
mpNotReady,mpStopped,mpPlaying,mpRecording,
mpSeeking,mpPaused,mpOpen }
function GetPlayerStatus: CDStates;
begin
case CDForm.CDPanel.mode of
mpStopped:
if PlayerStatus=CDPaused then
GetPlayerStatus:=CDPaused
else
GetPlayerStatus:=CDStopped;
mpPlaying: GetPlayerStatus:=CDPlaying ;
mpPaused: GetPlayerStatus:=CDPaused ;
mpSeeking,mpOpen,
mpNotReady,mpRecording: GetPlayerStatus:=CDNotReady;
else
{ The only time this should occur is if the player is not opened
and a random(ish) result is returned }
GetPlayerStatus:=PlayerStatus;
end;
end;
{ To prevent the disk drive whirring that happens when the CD
is attempted to be open and there is no CD in, the timer
event is slown down unless the CD is playing }
procedure SetTimer(t: CDStates);
var
tm: integer;
begin
case t of
cdPlaying: tm:=200;
else
tm:=1000;
end;
if CDForm.Ticker.interval<>tm then
CDForm.Ticker.interval:=tm;
end;
{ Return the end position for a particular track }
function GetEndPosition(tracknum: integer): longint;
var
p: longint;
begin
p:=CurrentCD.TrackDetail[tracknum].TrackStart+
CurrentCD.TrackDetail[tracknum].TrackLength;
if tracknum=CurrentCD.TotalTracks then
p:=p-300;
GetEndPosition:=p;
end;
{ When the CD is Offline - i.e. Not yet opened }
procedure CDOfflineTimer;
begin
try
CDForm.CDPanel.open;
PlayerStatus:=GetPlayerStatus;
case PlayerStatus of
CDStopped,CDPlaying,CDPaused: preparefornewCD;
end;
setbuttons(Playerstatus);
if ParamStr(1)='/play' then CDForm.CDPanel.Play;
except
{ Do nothing if exception occurred }
end;
end;
{ Return the next track to play
0 means stop - no next track }
function GetNextTrack(ThisTrack:integer): integer;
begin
case PlayMode of
plTrackOnce: GetNextTrack:=0;
plTrackRepeat: GetNextTrack:=ThisTrack;
plCDRepeat:
if ThisTrack=CurrentCD.TotalTracks then
GetNextTrack:=1
else
GetNextTrack:=ThisTrack+1;
else { and plCDOnce: }
if ThisTrack=CurrentCD.TotalTracks then
GetNextTrack:=0
else
GetNextTrack:=ThisTrack+1;
end;
end;
{ When the CD is Playing }
procedure CDPlayingTimer;
var
LastTrackPlayed: integer;
NextTrack: integer;
begin
{ Get Current Positions }
LastTrackPlayed:=CurrentTrack;
GetPositions;
{ If the CD was already playing then this code will be hit }
if EndPosition=0 then
begin
EndPosition:=GetEndPosition(CurrentTrack);
UpdateTracklist(CurrentTrack);
end;
{ If at or past end position then handle this }
if CDPosition>=EndPosition then
begin
NextTrack:=GetNextTrack(LastTrackPlayed);
if NextTrack=0 then CDForm.CDPanel.Stop
else begin
{ If next track to play is next track on disk then we can leave
the player to carry on uninterrupted
This bit of code will easily allow random track selection etc..
in the GetNextTrack routine - nothing else need be changed}
if NextTrack<>LastTrackPlayed+1 then
begin
GotoTrack(NextTrack);
CDForm.CDPanel.Play;
end;
UpdateTracklist(NextTrack);
end;
{ Set EndPosition to be the end of the newly selected track }
EndPosition:=GetEndPosition(NextTrack);
end;
{ Status Changes by none button events, i.e. buttons on CD Hardware }
PlayerStatus:=GetPlayerStatus;
case PlayerStatus of
cdPlaying: PositionDisplay; { Update LEDs }
cdStopped: SetButtons(cdStopped); {End of CD ?}
cdNotReady: DisablePlayer; {Ejected etc..}
end;
end;
{Prepare for a new CD}
procedure preparefornewCD;
var
path: string;
begin
path:=CDForm.CDPanel.FileName+'\Track01.cda';
if FileExists(path) then
begin
SetUpNewCD;
EnablePlayer;
SetButtons(PlayerStatus);
end else PlayerStatus:=cdNotReady;
end;
{ When the CD is not ready - i.e. Tray Open }
procedure CDNotReadyTimer;
begin
{ Nothing to do while Not Ready }
PlayerStatus:=GetPlayerStatus;
case PlayerStatus of
{ The only probable mode change from notready is to stopped,
but these modes are all served the same anyway }
cdPlaying,cdStopped,cdPaused: preparefornewCD;
end;
end;
{ When the CD is Stopped }
procedure CDStoppedTimer;
begin
{ Nothing to do whilst stopped }
PlayerStatus:=GetPlayerStatus;
case PlayerStatus of
cdPlaying: SetButtons(PlayerStatus); { Stopped - Playing }
cdNotReady: DisablePlayer; {Ejected etc..}
end;
{ All other modes will be dealt with by their own timer routine }
end;
{ When the CD is Paused }
procedure CDPausedTimer;
begin
{ Nothing to do whilst paused }
PlayerStatus:=GetPlayerStatus;
case PlayerStatus of
cdStopped: SetButtons(PlayerStatus); { Stopped by panel ? }
cdPlaying: SetButtons(PlayerStatus); { Paused -> Playing }
cdNotReady: DisablePlayer; {Ejected etc..}
end;
{ All other modes will be dealt with by their own timer routine }
end;
{ CDStates=(CDOffline,CDPlaying,CDStopped,CDNotReady,CDPaused); }
procedure TCDForm.TickerTimer(Sender: TObject);
begin
case PlayerStatus of
cdOffLine: CDOfflineTimer;
cdPlaying: CDPlayingTimer;
cdNotReady: CDNotReadyTimer;
cdStopped: CDStoppedTimer;
cdPaused: CDPausedTimer;
end;
SetTimer(PlayerStatus);
SetVolumeScroller;
end;
procedure SetVolumeScroller;
var
readvol: Integer;
begin
try
auxGetVolume(CDDEVICE,@ReadVol);
CDForm.Volume.Position:=255-hi(readvol);
except
end;
end;
procedure TCDForm.VolumeChange(Sender: TObject);
var
v,t: Longint;
begin
t:=255-Volume.Position;
v:=((t shl 8) or (t shl 24));
auxsetvolume(CDDEVICE,v);
end;
// Enum Windows Routine
function LookAtAllWindows(Handle: HWND; Temp: LongInt): BOOL; stdcall;
var
WindowName, ClassName: Array[0..255] of Char;
begin
// Go get the windows class name
if GetClassName(Handle, ClassName, SizeOf(ClassName)) > 0 then
// Is the window class the same ?
if StrComp(ClassName, MyClassName) = 0 then
// Get its window caption
if GetWindowText(Handle, WindowName, SizeOf(WindowName)) > 0 then
// Does this have the same window title ?
if StrLComp(WindowName, MyAppName,StrLen(MyAppName)) = 0 then
begin
inc(NumFound);
// Are the handles different ?
if Handle <> Application.Handle then
// Save it so we can bring it to the top later.
LastFound := Handle;
end;
Result:=True;
end;
{ Set the CD player and Environment for the first time }
procedure TCDForm.FormCreate(Sender: TObject);
var
drive: string;
L: Integer;
SUI: TStartupInfo;
CDIniFile: TIniFile;
begin
NumFound := 0; LastFound := 0;
// First, determine what this application'name is.
//GetWindowText(Application.Handle, MyAppName, SizeOf(MyAppName));
MyAppName:='CD Player';
// Now determine the class name for this application
GetClassName(Application.Handle, MyClassName, SizeOf(MyClassName));
// Now count how many others out there are Delphi apps with this title
EnumWindows(@LookAtAllWindows, 0);
if NumFound > AllowedInstances then
// there is another instance running, bring it to the front !
begin
MyPopup := GetLastActivePopup(LastFound);
// Bring it to the top in the Z-Order
BringWindowToTop(LastFound);
// Is the window iconized ?
if IsIconic(MyPopup) then
// Restore it to its original position
ShowWindow(MyPopup, SW_RESTORE)
else
// Bring it to the front
SetForegroundWindow(MyPopup);
// Halt this instance
Halt;
end;
if CmdShow = SW_SHOWDEFAULT then begin
GetStartupInfo(SUI);
RealCmdShow := SUI.wShowWindow;
end else
RealCmdShow := CmdShow ;
if RealCmdShow = SW_SHOWMAXIMIZED then
WindowState := wsMaximized;
Application.Title:='CD Player';
CDIniFile:=TIniFile.Create('Win.Ini');
if CDIniFile<>Nil then
try
with CDIniFile do
begin
CDForm.Left:=ReadInteger('CDPlayer','LeftPos',100);
CDForm.Top:=ReadInteger('CDPlayer','TopPos',100);
CDForm.Height:=ReadInteger('CDPlayer','Height',221);
CDForm.Width:=ReadInteger('CDPlayer','Width',236);
OnTop:=ReadInteger('CDPlayer','OnTop',0);
DispType:=ReadInteger('CDPlayer','Display',0);
Free;
end;
except
CDIniFile.Free;
end;
if Ontop>0 then
begin
OntopButton.Down:=True;
OnTopButton.Click;
end;
SetDisp(Disptype);
For L := Ord('C') to Ord('Z') do begin
drive := Chr(L)+':\'+#0;
if GetDriveType(Pchar(drive)) = DRIVE_CDROM then
begin
CDForm.CDPanel.FileName:=Chr(L)+':';
break;
end;
end;
DisablePlayer; { Deactivate all controls etc.. }
PlayerStatus:=CDOffline; { CD isn't opened }
LastPlayerStatus:=CDOffLine;
TimerMode:=tmTrackGone; { Default mode of Track time }
PlayMode:=plCDOnce; {Default mode of play }
end;
procedure TCDForm.FormClose(Sender: TObject; var Action: TCloseAction);
var
CDIniFile: TIniFile;
begin
CDIniFile:=TIniFile.Create('Win.ini');
if CDIniFile<>Nil then
try
with CDIniFile do
begin
WriteInteger('CDPlayer','TopPos',CDForm.Top);
WriteInteger('CDPlayer','LeftPos',CDForm.Left);
WriteInteger('CDPlayer','Height',CDForm.Height);
WriteInteger('CDPlayer','Width',CDForm.Width);
WriteInteger('CDPlayer','Display',DispType);
WriteInteger('CDPlayer','OnTop',OnTop);
Free;
end;
except
CDIniFile.Free;
end;
end;
{ Move the currently displayed track }
procedure UpdateTracklist(l: integer);
begin
if CDForm.TrackList.Itemindex<>l-1 then
begin
CDForm.TrackList.ItemIndex:=l-1;
SetFormCaption(CurrentCD.TrackDetail[CurrentTrack].TrackTitle);
end;
end;
procedure SetFormCaption(s: string);
begin
if s<>'' then
CDForm.Caption:=s
else
CDForm.Caption:='Compact Disk Player';
end;
{ Intercept pressing a button on the CD panel and manually
perform the tasks }
procedure TCDForm.TrackListClick(Sender: TObject);
begin
if CurrentTrack<>TrackList.ItemIndex+1 then
begin
CurrentTrack:=TrackList.ItemIndex+1;
EndPosition:=GetEndPosition(CurrentTrack);
GotoTrack(CurrentTrack);
SetFormCaption(CurrentCD.TrackDetail[CurrentTrack].TrackTitle);
{ If currently playing then carry on playing }
if PlayerStatus=cdPlaying then
CDForm.CDpanel.Play
else
begin
{ Otherwise move to the track specified and update the display
so you know it has moved }
GotoTrack(CurrentTrack);
SetTimerTrack(0,CurrentTrack);
end;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -