home *** CD-ROM | disk | FTP | other *** search
- unit CDUnit;
-
- interface
- {
-
- By default the AutoEnable property is set to True so that buttons are
- shown enabled (coloured) or disabled (grey out) as appropriate.
-
- However, there is a problem when you add your own buttons to control the
- MediaPlayer. These buttons can call methods such as Pl;ay and Rewind but the
- set of MediaPlayer buttons won't be reliably toggled in respons to these
- method calls.
-
- My simple fix for this (in my Rewind+Play method, DoRewind) is to disable
- the AutoEnabled property and disable the Play button by substracting it from
- the set of Enabled buttons:
- AutoEnable := false;
- EnabledButtons := EnabledButtons-[btPlay];
-
- The AutoEnabled property is re-anebled to deal with click-events on
- the MediaPlayer in the MediaPlayer1Click method:
- MediaPlayer1.AutoEnable := true;
-
- Limitations: Does not handle exception when some other Multimedia player
- (such as the Windows CD player) has already opened the CD device.
-
- Author: Huw Collingbourne
- }
- uses
- Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
- MPlayer, StdCtrls, ExtCtrls,
- MMSystem, ComCtrls, Buttons; { include MMSystem for access to Timing functions }
-
- type
- TForm1 = class(TForm)
- Timer1: TTimer;
- Panel1: TPanel;
- DisplayBox: TEdit;
- TrackTBar: TTrackBar;
- MediaPlayer1: TMediaPlayer;
- BitBtn1: TBitBtn;
- RewindBtn: TButton;
- StatusLabel: TLabel;
- procedure MediaPlayer1PostClick(Sender: TObject; Button: TMPBtnType);
- procedure Timer1Timer(Sender: TObject);
- procedure FormClose(Sender: TObject; var Action: TCloseAction);
- procedure FormActivate(Sender: TObject);
- procedure BitBtn1Click(Sender: TObject);
- procedure RewindBtnClick(Sender: TObject);
- procedure MediaPlayer1Click(Sender: TObject; Button: TMPBtnType;
- var DoDefault: Boolean);
- private
- { Private declarations }
- Track : integer;
- prevTrack : integer;
- public
- { Public declarations }
- procedure resetTrackBar( Pos : longint );
- procedure DecodeTMSFMinSec( TMSF : LongInt; Var Minutes, Seconds : longint );
- procedure DecodeMSFMinSec( MSF : LongInt; Var Minutes, Seconds : longint );
- function CurrTrack : longint;
- function TracklenStr : string;
- function CDlenStr : string;
- function CDReady( var errmsg : string) : boolean;
- procedure DoRewind;
- end;
-
- var
- Form1: TForm1;
-
- implementation
-
- {$R *.DFM}
-
- const
- CDDRIVE = 'D'; // Change this if the CD drive is some other letter!
- ModeStr: array[TMPModes] of string[10] = ('Not ready', 'Stopped', 'Playing',
- 'Recording', 'Seeking', 'Paused', 'Open');
-
-
- function AudioCD(Drive : char) : boolean;
- { Return True if an Audio CD is in the drive,
- else return False.
- Note: Refer to Win32 Programmers Reference for help on
- GetDriveType and GetVolumeInformation.
- Note: VolumeName = 'Audio CD' when an audio CD is loaded }
- var
- RootPathName : string;
- MaxComponentLength : DWORD;
- FileSystemFlags : DWORD;
- VolumeName : string;
- begin
- result := false;
- RootPathName := Drive + ':\';
- if GetDriveType(PChar(RootPathName)) = DRIVE_CDROM then
- begin
- SetLength(VolumeName, 64);
- GetVolumeInformation(PChar(RootPathName),
- PChar(VolumeName),
- Length(VolumeName),
- nil,
- MaxComponentLength,
- FileSystemFlags,
- nil,
- 0);
- if lStrCmp(PChar(VolumeName),'Audio CD') = 0 then
- result := true;
- end; { if DRIVE_CDROM }
- end;
-
- (* The two functions that follow decode a LongInt value into its Minutes
- and Seconds components. They are similar apart from the fact that
- they call different Win32 functions. Use them with care! *)
- procedure TForm1.DecodeTMSFMinSec( TMSF : LongInt; Var Minutes, Seconds : longint );
- { Input TMSF format int. Assign Minute and Second values to last 2 args }
- begin
- Minutes := MCI_TMSF_MINUTE(TMSF);
- Seconds := MCI_TMSF_SECOND(TMSF);
- end;
-
- procedure TForm1.DecodeMSFMinSec( MSF : LongInt; Var Minutes, Seconds : longint );
- { Input MSF format int. Assign Minute and Second values to last 2 args }
- begin
- Minutes := MCI_MSF_MINUTE(MSF);
- Seconds := MCI_MSF_SECOND(MSF);
- end;
-
-
- function TForm1.currTrack : longint;
- { return current track number, indexed from 1 for 1st track }
- begin
- result := MCI_TMSF_TRACK(MediaPlayer1.Position);
- end;
-
-
-
- function TForm1.TracklenStr : string;
- { Return tracklength as a string, 'Min:Sec' }
- var
- Min,Sec : longint;
- begin
- DecodeMSFMinSec(Mediaplayer1.Tracklength[currTrack], min, sec);
- result := Format('%.2d:%.2d', [min, sec]);
- end;
-
- function TForm1.CDlenStr : string;
- { Return total CD playing length as a string, 'Min:Sec' }
- var
- Min,Sec : longint;
- begin
- DecodeMSFMinSec( MediaPlayer1.Length, Min, Sec);
- result := Format('%.2d:%.2d', [min, sec]);
- end;
-
- procedure TForm1.DoRewind;
- begin
- with MediaPlayer1 do
- begin
- Stop; // More reliable to Stop before Rewinding Player
- Rewind;
- Play;
- // Disable Play button after Rewind. See comment at head of unit.
- AutoEnable := false;
- EnabledButtons := EnabledButtons-[btPlay];
- end;
- end;
-
- function TForm1.CDReady( var errmsg : string ) : boolean;
- { Checks that an Audio CD is in the drive. If so, return True.
- If not, return False and assign an error message to errmsg argument }
- var
- ok : boolean;
- txt : string;
- begin
- ok := false;
- txt := '';
- if MediaPlayer1.Error = 262 then{ a pre-defined'magic number' = empty drive }
- txt := 'The CD drive seems to be empty!'
- else if not (AudioCD( CDDRIVE )) then
- txt := 'Insert an audio CD!'
- else if MediaPlayer1.Error = 0 then
- ok := true
- else txt := MediaPlayer1.ErrorMessage;
- if not ok then
- errmsg := txt;
- result := ok;
- end;
-
-
- procedure TForm1.MediaPlayer1PostClick(Sender: TObject;
- Button: TMPBtnType);
- { check that CD is ready after the MediaPlayer has been clicked }
- var
- msg : string;
- begin
- msg := '';
- if not CDReady( msg ) then
- DisplayBox.Text := msg;
- end;
-
- procedure TForm1.Timer1Timer(Sender: TObject);
- { Timer object updates the Trackbar and time-display info }
- var
- Minutes : longint;
- Seconds : longint;
- msg : string;
- begin
- msg := '';
- StatusLabel.Caption := ModeStr[MediaPlayer1.Mode];
- if not CDReady( msg ) then
- begin
- Caption := msg;
- DisplayBox.Text := 'CD not ready!';
- end
- else //--- Main Block ---
- begin //--- if all is well execute this block to display track and CD info
- Track := currTrack;
- if Track <> prevTrack then { check for new track! }
- begin
- prevTrack := Track; { assign prevTrack variable to new track }
- resetTrackBar( 0 );
- end;
- { after each Timer event update time display }
- DecodeTMSFMinSec(MediaPlayer1.Position, Minutes, Seconds );
- DisplayBox.Text := Format('[%.2d] %.2d:%.2d', [Track,Minutes,Seconds]);
- Caption := Format('[Track %.2d] Length: %s | CD Length: %s, Tracks: %.2d',
- [Track,TrackLenStr,CDLenStr,MediaPlayer1.Tracks]);
- { finally, move the TrackBar }
- TrackTBar.Position := (60 * Minutes) + Seconds;
- end;
- end;
-
- procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
- begin
- MediaPlayer1.Stop; { stop playing track when the app is closed }
- end;
-
- procedure TForm1.FormActivate(Sender: TObject);
- { set Time Format and initialise prevTrack variable when App is loaded }
- begin
- Track := 0;
- prevTrack := 0;
- MediaPlayer1.TimeFormat := tfTMSF;
- MediaPlayer1.Open; // Open CD device. Add exception handling here if you wish.
- end;
-
- procedure TForm1.resetTrackBar( Pos : longint );
- { Reset the TrackBar (e.g. when a new Track starts playing) }
- var
- Minutes, Seconds, MaxLen : longint;
- begin
- DecodeMSFMinSec(Mediaplayer1.Tracklength[currTrack], Minutes, Seconds );
- MaxLen := (60 * Minutes) + Seconds;
- TrackTBar.Min := 0; { start pos }
- TrackTBar.Max := MaxLen; { end pos }
- TrackTBar.Position := 0; { current pos }
- end;
-
- procedure TForm1.BitBtn1Click(Sender: TObject);
- begin
- Close;
- end;
-
- procedure TForm1.RewindBtnClick(Sender: TObject);
- begin
- DoRewind;
- end;
-
- procedure TForm1.MediaPlayer1Click(Sender: TObject; Button: TMPBtnType;
- var DoDefault: Boolean);
- begin
- { When the MediaPlayer is clicked make sure that the buttons are automatically
- enabled and disabled as appropriate }
- MediaPlayer1.AutoEnable := true;
- end;
-
- end.
-