Subversion Repositories musikbox

Rev

Blame | Last modification | View Log | RSS feed

  1. unit Main;
  2.  
  3. interface
  4.  
  5. uses
  6.   Windows, Messages, Forms, SysUtils, StdCtrls, IniFiles, MPlayer,
  7.   Gauges, ComCtrls, ImgList, Controls, Classes, ExtCtrls,
  8.   WaveControl, registry, Dialogs, math;
  9.  
  10. type
  11.   TStringDynArray = array of string;
  12.  
  13.   TMainForm = class(TForm)
  14.     lblOrdner: TLabel;
  15.     lstSongs: TListBox;
  16.     lblSongs: TLabel;
  17.     sbrCopyright: TStatusBar;
  18.     btnStart: TButton;
  19.     BtnStopp: TButton;
  20.     btnPause: TButton;
  21.     btnOrdner: TButton;
  22.     lstOrdner: TTreeView;
  23.     ImgList: TImageList;
  24.     MediaPlayer: TMediaPlayer;
  25.     plyTimer: TTimer;
  26.     grpPlayMode: TGroupBox;
  27.     chkRepeatSong: TCheckBox;
  28.     radPlayMode1: TRadioButton;
  29.     radPlayMode2: TRadioButton;
  30.     radPlayMode3: TRadioButton;
  31.     grpRunMode: TGroupBox;
  32.     radRunMode1: TRadioButton;
  33.     radRunMode2: TRadioButton;
  34.     radRunMode3: TRadioButton;
  35.     grpVolume: TGroupBox;
  36.     lblVolume: TLabel;
  37.     pgrVolume: TProgressBar;
  38.     btnBeenden: TButton;
  39.     ggeProgress: TProgressBar;
  40.     Status1: TLabel;
  41.     Status2: TLabel;
  42.     VolProc: TLabel;
  43.     procedure FormShow(Sender: TObject);
  44.     procedure lstSongsClick(Sender: TObject);
  45.     procedure plyTimerTimer(Sender: TObject);
  46.     procedure btnPauseClick(Sender: TObject);
  47.     procedure BtnStoppClick(Sender: TObject);
  48.     procedure btnStartClick(Sender: TObject);
  49.     procedure pgrVolumeDragOver(Sender, Source: TObject; X, Y: Integer;
  50.       State: TDragState; var Accept: Boolean);
  51.     procedure lstOrdnerChange(Sender: TObject; Node: TTreeNode);
  52.     procedure chkRepeatSongClick(Sender: TObject);
  53.     procedure sbrCopyrightClick(Sender: TObject);
  54.     procedure btnBeendenClick(Sender: TObject);
  55.     procedure btnOrdnerClick(Sender: TObject);
  56.     procedure FormResize(Sender: TObject);
  57.     procedure FormCreate(Sender: TObject);
  58.     procedure FormDestroy(Sender: TObject);
  59.     procedure FormCanResize(Sender: TObject; var NewWidth, NewHeight: Integer;
  60.       var Resize: Boolean);
  61.     procedure ggeProgressMouseDown(Sender: TObject; Button: TMouseButton;
  62.       Shift: TShiftState; X, Y: Integer);
  63.   public
  64.     // VCL-Ersatz start
  65.     volWave: TWaveVolumeSetting;
  66.     // VCL-Ersatz ende
  67.     ini: TIniFile;
  68.     MusikArray, FormatArray: TStringDynArray;
  69.     ExtentionsArray: array of string;
  70.     ActualPath: string;
  71.     Playing: boolean;
  72.     ActualVolume: integer;
  73.     procedure ListeOrdner(ArrayElement: integer; zusatz: string; node: TTreeNode);
  74.     procedure InitDirectories();
  75.     procedure SchreibeEinstellung();
  76.     procedure NextSong();
  77.     function MCIExtensions(): string;
  78.   end;
  79.  
  80. var
  81.   MainForm: TMainForm;
  82.  
  83. implementation
  84.  
  85. uses Info, Config;
  86.  
  87. {$R *.dfm}
  88.  
  89. {$R windowsxp.res}
  90.  
  91. // http://www.delphipraxis.net/post592358.html
  92. function IsFileDRMProtected(AFileName: String): Boolean;
  93. var lCheckProc: function(const AFileName: PWideChar; var AIsProtected: Bool): HRESULT; stdcall;
  94.     lLibHandle: Cardinal;
  95.     lWideChar   : PWideChar;
  96.     lRes        : HRESULT;
  97.     lIsProtected: Bool;
  98. begin
  99.   lLibHandle := LoadLibrary('wmvcore.dll');
  100.   if (lLibHandle > 0) then
  101.   begin
  102.     lCheckProc := GetProcAddress(lLibHandle, 'WMIsContentProtected');
  103.     if Assigned(lCheckProc) then
  104.     begin
  105.       GetMem(lWideChar, MAX_PATH * SizeOf(WideChar));
  106.       StringToWideChar(AFileName, lWideChar, MAX_PATH);
  107.       lRes := lCheckProc(lWideChar, lIsProtected);
  108.       case lRes of
  109.         S_OK: result := lIsProtected
  110.         else result := False;
  111.       end;
  112.     end
  113.     else
  114.       result := False;
  115.   end
  116.   else
  117.     result := False;
  118. end;
  119.  
  120. // http://www.luckie-online.de/Delphi/Sonstiges/Explode.html
  121. function Explode(const Separator, S: string; Limit: Integer = 0):
  122.   TStringDynArray;
  123. var
  124.   SepLen       : Integer;
  125.   F, P         : PChar;
  126.   ALen, Index  : Integer;
  127. begin
  128.   SetLength(Result, 0);
  129.   if (S = '') or (Limit < 0) then
  130.     Exit;
  131.   if Separator = '' then
  132.   begin
  133.     SetLength(Result, 1);
  134.     Result[0] := S;
  135.     Exit;
  136.   end;
  137.   SepLen := Length(Separator);
  138.   ALen := Limit;
  139.   SetLength(Result, ALen);
  140.  
  141.   Index := 0;
  142.   P := PChar(S);
  143.   while P^ <> #0 do
  144.   begin
  145.     F := P;
  146.     P := StrPos(P, PChar(Separator));
  147.     if (P = nil) or ((Limit > 0) and (Index = Limit - 1)) then
  148.       P := StrEnd(F);
  149.     if Index >= ALen then
  150.     begin
  151.       Inc(ALen, 5); // mehrere auf einmal um schneller arbeiten zu können
  152.       SetLength(Result, ALen);
  153.     end;
  154.     SetString(Result[Index], F, P - F);
  155.     Inc(Index);
  156.     if P^ <> #0 then
  157.       Inc(P, SepLen);
  158.   end;
  159.   if Index < ALen then
  160.     SetLength(Result, Index); // wirkliche Länge festlegen
  161. end;
  162.  
  163. procedure TMainForm.InitDirectories();
  164. var
  165.   i: integer;
  166.   mnod: TTreeNode;
  167. begin
  168.   if btnStopp.Enabled then btnStopp.Click;
  169.   btnStart.Enabled := false;
  170.   mediaplayer.FileName := '';
  171.  
  172.   lstSongs.Items.Clear;
  173.   lblSongs.Caption := 'Songs';
  174.  
  175.   ActualPath := '';
  176.   lstOrdner.Items.Clear;
  177.   for i := 0 to length(MusikArray)-1 do
  178.   begin
  179.     if DirectoryExists(MusikArray[i]) then
  180.     begin
  181.       mnod := lstOrdner.Items.Add(nil, MusikArray[i]);
  182.       ListeOrdner(i, '', mnod);
  183.       mnod.ImageIndex := 0;
  184.       mnod.Expand(false);
  185.     end;
  186.   end;
  187. end;
  188.  
  189. function TMainForm.MCIExtensions(): string;
  190. var
  191.   Reg: TRegistry;
  192.   inifile: TIniFile;
  193.   sl: TStringList;
  194.   WindowsDir: string;
  195.   WinDir: String;
  196.   WinLen: DWord;
  197.   i: integer;
  198. begin
  199.   sl := TStringList.Create();
  200.  
  201.   // Registry prüfen (ab Windows NT)
  202.   Reg := TRegistry.Create;
  203.   Reg.RootKey := HKEY_LOCAL_MACHINE;
  204.   if Reg.OpenKeyReadOnly('\SOFTWARE\Microsoft\Windows NT\CurrentVersion\MCI Extensions\') then
  205.     Reg.GetValueNames(sl)
  206.   else
  207.   begin
  208.     // Win.ini, wenn Registry fehlschlägt (ab Windows 95)
  209.     SetLength(WinDir, MAX_PATH);
  210.     WinLen := GetWindowsDirectory(PChar(WinDir), MAX_PATH);
  211.     if WinLen > 0 then
  212.     begin
  213.       SetLength(WinDir, WinLen);
  214.       WindowsDir := WinDir;
  215.     end
  216.     else
  217.       RaiseLastOSError;
  218.  
  219.     if fileexists(WindowsDir+'\win.ini') then
  220.     begin
  221.       inifile := TIniFile.Create(WindowsDir+'\win.ini');
  222.       try
  223.         if inifile.SectionExists('mci extensions') then
  224.           inifile.ReadSection('mci extensions', sl)
  225.         else
  226.           if inifile.SectionExists('MCI Extensions.BAK') then
  227.             inifile.ReadSection('MCI Extensions.BAK', sl);
  228.       finally
  229.         inifile.Free;
  230.       end;
  231.     end;
  232.   end;
  233.   Reg.CloseKey;
  234.   Reg.Free;
  235.  
  236.   if sl.count = 0 then
  237.   begin
  238.     showmessage('Warnung! Es konnten keine MCI-Erweiterungen gefunden werden. Das Programm wird beendet.');
  239.     close;
  240.   end
  241.   else
  242.   begin
  243.     result := '';
  244.     for i := 0 to sl.count-1 do
  245.       result := result + lowercase(sl.strings[i]) + '|';
  246.     result := copy(result, 0, length(result)-1);
  247.   end;
  248. end;
  249.  
  250. procedure TMainForm.FormShow(Sender: TObject);
  251. var
  252.   MusicPath, Formats: string;
  253.   PlayMode, RunMode: integer;
  254.   RepeatPlay: boolean;
  255. begin
  256.   // Lese INI-Einstellungen
  257.   ini := TIniFile.Create(extractfilepath(application.ExeName)+'Settings.ini');
  258.   try
  259.     MusicPath := ini.ReadString('Configuration', 'Path', '');
  260.     PlayMode := ini.ReadInteger('Configuration', 'PlayMode', 1);
  261.     RunMode := ini.ReadInteger('Configuration', 'RunMode', 1);
  262.     RepeatPlay := ini.ReadBool('Configuration', 'RepeatPlay', false);
  263.     ClientWidth := ini.ReadInteger('Configuration', 'ClientWidth', ClientWidth);
  264.     ClientHeight := ini.ReadInteger('Configuration', 'ClientHeight', ClientHeight);
  265.   finally
  266.     ini.Free;
  267.   end;
  268.  
  269.   // MCI-Erweiterungen lesen
  270.   Formats := MCIExtensions();
  271.  
  272.   // Anwenden von Einstellungen
  273.   if PlayMode = 1 then radPlayMode1.Checked := true;
  274.   if PlayMode = 2 then radPlayMode2.Checked := true;
  275.   if PlayMode = 3 then radPlayMode3.Checked := true;
  276.   if RunMode = 1 then radRunMode1.Checked := true;
  277.   if RunMode = 2 then radRunMode2.Checked := true;
  278.   if RunMode = 3 then radRunMode3.Checked := true;
  279.   chkRepeatSong.Checked := RepeatPlay;
  280.   chkRepeatSongClick(self);
  281.  
  282.   // Zerteile Verzeichnisliste
  283.   MusikArray := Explode('|', MusicPath);
  284.   FormatArray := Explode('|', Formats);
  285.  
  286.   InitDirectories();
  287. end;
  288.  
  289. procedure TMainForm.ggeProgressMouseDown(Sender: TObject; Button: TMouseButton;
  290.   Shift: TShiftState; X, Y: Integer);
  291. begin
  292.   if (mediaplayer.FileName <> '') and (not IsFileDRMProtected(mediaplayer.filename)) then
  293.   begin
  294.     btnstart.Click;
  295.     mediaplayer.Position := round(x / ggeProgress.Width * mediaplayer.length);
  296.     mediaplayer.play;
  297.   end;
  298. end;
  299.  
  300. procedure TMainForm.ListeOrdner(ArrayElement: integer; zusatz: string; node: TTreeNode);
  301. var
  302.   SR: TSearchRec;
  303.   RootFolder: string;
  304.   mnod: TTreeNode;
  305. begin
  306.   RootFolder := MusikArray[ArrayElement]+'\'+zusatz;
  307.  
  308.   if AnsiLastChar(RootFolder)^ <> '\' then
  309.     RootFolder := RootFolder + '\';
  310.  
  311.     if FindFirst(RootFolder + '*.*', faDirectory, SR) = 0 then
  312.     try
  313.       repeat
  314.         if ((SR.Attr and faDirectory) = faDirectory) and
  315.            (SR.Name <> '.') and (SR.Name <> '..') then
  316.         begin
  317.           mnod := lstOrdner.Items.AddChild(node, SR.Name);
  318.           ListeOrdner(ArrayElement, zusatz+SR.Name+'\', mnod);
  319.           mnod.ImageIndex := 1;
  320.           mnod.SelectedIndex := 1;
  321.           mnod.Expand(false);
  322.         end;
  323.       until FindNext(SR) <> 0;
  324.     finally
  325.       FindClose(SR);
  326.     end;
  327. end;
  328.  
  329. procedure TMainForm.lstSongsClick(Sender: TObject);
  330. begin
  331.   if mediaplayer.filename <> ActualPath+lstsongs.Items.Strings[lstSongs.ItemIndex]+ExtentionsArray[lstSongs.ItemIndex] then
  332.   begin
  333.     mediaplayer.filename := ActualPath+lstsongs.Items.Strings[lstSongs.ItemIndex]+ExtentionsArray[lstSongs.ItemIndex];
  334.     if BtnStopp.Enabled then BtnStopp.Click;
  335.     btnStart.Enabled := true;
  336.     if radRunMode2.Checked or radRunMode1.Checked then
  337.       BtnStart.Click;
  338.   end;
  339. end;
  340.  
  341. function zweinull(inp: integer): string;
  342. begin
  343.   if inp >= 10 then
  344.     result := inttostr(inp)
  345.   else
  346.     result := '0' + inttostr(inp);
  347. end;
  348.  
  349. // Millisekunden zu hh:mm:ss
  350. function mstotimestr(inp: integer): string;
  351. var
  352.   h, m, s: integer;
  353. begin
  354.   result := '';
  355.   m := (inp div 1000) div 60;
  356.   h := 0;
  357.   while m >= 60 do
  358.   begin
  359.     inc(h);
  360.     m := m - 60;
  361.   end;
  362.   s := (inp div 1000) - m * 60;
  363.   result := zweinull(h)+':'+zweinull(m)+':'+zweinull(s);
  364. end;
  365.  
  366. procedure TMainForm.plyTimerTimer(Sender: TObject);
  367. begin
  368.   pgrVolume.Position := 1000 - volWave.Position;
  369.   VolProc.Caption := inttostr(100 - round(volWave.Position / 1000 * 100))+'%';
  370.   if Playing then
  371.   begin
  372.     ggeProgress.Max := mediaplayer.Length;
  373.     ggeProgress.Position := mediaplayer.Position;
  374.     Status1.caption := mstotimestr(mediaplayer.Position) + ' / ' + mstotimestr(mediaplayer.Length);
  375.     Status2.caption := inttostr(floor(ggeprogress.Position / ggeprogress.Max * 100)) + '%';
  376.     if mediaplayer.Position >= mediaplayer.Length then
  377.     begin
  378.       mediaplayer.Rewind;
  379.       nextsong;
  380.     end;
  381.   end;
  382. end;
  383.  
  384. procedure TMainForm.btnPauseClick(Sender: TObject);
  385. begin
  386.   mediaplayer.Pause;
  387.   btnStart.Enabled := true;
  388.   btnPause.Enabled := false;
  389. end;
  390.  
  391. procedure TMainForm.BtnStoppClick(Sender: TObject);
  392. begin
  393.   Playing := false;
  394.  
  395.   mediaplayer.Stop;
  396.   mediaplayer.close;
  397.  
  398.   ggeProgress.Position := 0;
  399.   ggeProgress.Max := 0;
  400.   Status1.Caption := '00:00:00';
  401.   Status2.Caption := '0%';
  402.  
  403.   BtnStopp.Enabled := false;
  404.   BtnPause.Enabled := false;
  405.   BtnStart.Enabled := true;
  406. end;
  407.  
  408. // http://www.wer-weiss-was.de/theme159/article1483880.html
  409. procedure delay(nDelay: Integer);
  410. var
  411.   nStart : Integer;
  412. begin
  413.   nStart := GetTickCount;
  414.   while Integer(GetTickCount)-nStart < nDelay do
  415.   begin
  416.     Application.ProcessMessages;
  417.     Sleep(0);
  418.   end;
  419. end;
  420.  
  421. procedure TMainForm.btnStartClick(Sender: TObject);
  422. begin
  423.   if IsFileDRMProtected(mediaplayer.filename) then
  424.   begin
  425.     delay(250);
  426.     NextSong;
  427.   end
  428.   else
  429.   begin
  430.  
  431.   if btnStopp.Enabled then
  432.     mediaplayer.Play
  433.   else
  434.   begin
  435.     mediaplayer.Open;
  436.     mediaplayer.Play;
  437.     playing := true;
  438.   end;
  439.  
  440.   BtnStart.Enabled := false;
  441.   BtnPause.Enabled := true;
  442.   BtnStopp.Enabled := true;
  443.   end;
  444.  
  445. end;
  446.  
  447. procedure TMainForm.pgrVolumeDragOver(Sender, Source: TObject; X,
  448.   Y: Integer; State: TDragState; var Accept: Boolean);
  449. begin
  450.   pgrVolume.Position := round(pgrVolume.Max * (abs(x)/pgrVolume.Width));
  451.   ActualVolume := round(1000 * (abs(x)/pgrVolume.Width));
  452.   volWave.Position := 1000-ActualVolume;
  453. end;
  454.  
  455. procedure TMainForm.lstOrdnerChange(Sender: TObject; Node: TTreeNode);
  456. var
  457.   Path, ext: string;
  458.   Aktuell: TTreeNode;
  459.   sr: TSearchRec;
  460.   res, i: integer;
  461.   FCheck: boolean;
  462. begin
  463.   if BtnStopp.Enabled then BtnStopp.Click;
  464.   if BtnStart.Enabled then BtnStart.Enabled := false;
  465.  
  466.   // Pfad finden
  467.   Aktuell := lstOrdner.Selected;
  468.   lblSongs.caption := Aktuell.Text;
  469.   Path := Aktuell.Text+'\';
  470.   repeat
  471.     try
  472.       if Aktuell.Parent <> nil then
  473.       begin
  474.         Aktuell := Aktuell.Parent;
  475.         Path := Aktuell.Text+'\'+Path;
  476.       end
  477.       else
  478.         Break;
  479.     except end;
  480.   until false;
  481.  
  482.   if ActualPath <> Path then
  483.   begin
  484.     // Liste leeren
  485.     lstSongs.Items.Clear;
  486.     setlength(ExtentionsArray, 0);
  487.  
  488.     // Dateien auflisten
  489.     res := FindFirst(Path+'*.*', faAnyFile, sr);
  490.     try
  491.       while (res = 0) do
  492.       begin
  493.         if (sr.name <> '.') and (sr.name <> '..') then
  494.         begin
  495.           try
  496.             ext := lowercase(ExtractFileExt(sr.FindData.cFileName));
  497.             FCheck := false;
  498.             for i := 0 to length(FormatArray)-1 do
  499.               if ext = '.'+FormatArray[i] then
  500.                 FCheck := true;
  501.             if FCheck then
  502.             begin
  503.               setlength(ExtentionsArray, length(ExtentionsArray)+1);
  504.               ExtentionsArray[length(ExtentionsArray)-1] := ext;
  505.               lstSongs.items.Add(copy(sr.Name, 0, length(sr.name)-4));
  506.             end;
  507.           except
  508.           end;
  509.         end;
  510.         res := FindNext(sr);
  511.       end;
  512.     finally
  513.       FindClose(sr);
  514.     end;
  515.  
  516.     ActualPath := Path;
  517.   end;
  518.  
  519.   if (lstSongs.Items.Count > 0) and radRunMode1.Checked then
  520.   begin
  521.     lstSongs.ItemIndex := 0;
  522.     lstSongs.Selected[0] := true;
  523.     lstSongsClick(self);
  524.     if radRunMode1.Checked then
  525.       btnStart.Click;
  526.   end;
  527. end;
  528.  
  529. procedure TMainForm.chkRepeatSongClick(Sender: TObject);
  530. begin
  531.   radPlayMode1.Enabled := not chkRepeatSong.Checked;
  532.   radPlayMode2.Enabled := not chkRepeatSong.Checked;
  533.   radPlayMode3.Enabled := not chkRepeatSong.Checked;
  534. end;
  535.  
  536. procedure TMainForm.SchreibeEinstellung();
  537. var
  538.   PlayMode, RunMode, i: integer;
  539.   RepeatPlay: boolean;
  540.   MusicPath: string;
  541. begin
  542.   // Erkenne Eigenschaften
  543.   RepeatPlay := chkRepeatSong.Checked;
  544.   PlayMode := 1;
  545.   if radPlayMode1.Checked then PlayMode := 1;
  546.   if radPlayMode2.Checked then PlayMode := 2;
  547.   if radPlayMode3.Checked then PlayMode := 3;
  548.   RunMode := 1;
  549.   if radRunMode1.Checked then RunMode := 1;
  550.   if radRunMode2.Checked then RunMode := 2;
  551.   if radRunMode3.Checked then RunMode := 3;
  552.  
  553.   // Arrays zusammenfassen
  554.   MusicPath := '';
  555.   for i := 0 to length(MusikArray)-1 do
  556.     MusicPath := MusicPath + '|' + MusikArray[i];
  557.   MusicPath := copy(MusicPath, 2, length(MusicPath)-1);
  558.  
  559.   // Schreibe INI-Einstellungen
  560.   ini := TIniFile.Create(extractfilepath(application.ExeName)+'Settings.ini');
  561.   try
  562.     ini.WriteString('Configuration', 'Path', MusicPath);
  563.     ini.WriteInteger('Configuration', 'PlayMode', PlayMode);
  564.     ini.WriteInteger('Configuration', 'RunMode', RunMode);
  565.     ini.WriteBool('Configuration', 'RepeatPlay', RepeatPlay);
  566.     ini.WriteInteger('Configuration', 'ClientWidth', ClientWidth);
  567.     ini.WriteInteger('Configuration', 'ClientHeight', ClientHeight);
  568.   finally
  569.     ini.Free;
  570.   end;
  571. end;
  572.  
  573. procedure TMainForm.FormCanResize(Sender: TObject; var NewWidth,
  574.   NewHeight: Integer; var Resize: Boolean);
  575. begin
  576.   if NewHeight < (grpVolume.Top + grpVolume.Height + 8 + btnStart.height + 8 + sbrcopyright.height + GetSystemMetrics(sm_cYsize) + 8) then
  577.     NewHeight := (grpVolume.Top + grpVolume.Height + 8 + btnStart.height + 8 + sbrcopyright.height + GetSystemMetrics(sm_cYsize) + 8);
  578.  
  579.   if NewWidth <= 720 then NewWidth := 720;  
  580. end;
  581.  
  582. procedure TMainForm.FormCreate(Sender: TObject);
  583. begin
  584.   volWave := TWaveVolumeSetting.Create(self);
  585.   volWave.Parent := self;
  586.   volWave.Max := 1000;
  587.   volWave.Visible := false;
  588. end;
  589.  
  590. procedure TMainForm.FormDestroy(Sender: TObject);
  591. begin
  592.   volWave.Free;
  593.   ggeProgress.free;
  594. end;
  595.  
  596. procedure TMainForm.sbrCopyrightClick(Sender: TObject);
  597. begin
  598.   InfoForm.PopupParent := Screen.ActiveForm; // http://www.delphipraxis.net/topic75743,0,asc,0.html
  599.   InfoForm.showmodal();
  600. end;
  601.  
  602. procedure TMainForm.btnBeendenClick(Sender: TObject);
  603. begin
  604.   close;
  605. end;
  606.  
  607. procedure TMainForm.btnOrdnerClick(Sender: TObject);
  608. begin
  609.   ConfigForm.PopupParent := Screen.ActiveForm; // http://www.delphipraxis.net/topic75743,0,asc,0.html
  610.   ConfigForm.showmodal();
  611. end;
  612.  
  613. procedure TMainForm.FormResize(Sender: TObject);
  614. begin
  615.   // Höhenverwaltung
  616.   lstOrdner.Height := MainForm.ClientHeight - lstOrdner.Top - 2 * lstOrdner.Left - sbrCopyright.Height - btnBeenden.Height;
  617.   lstSongs.Height := lstOrdner.Height;
  618.   btnBeenden.Top := lstOrdner.Top + lstOrdner.Height + lstOrdner.Left;
  619.   btnOrdner.Top := btnBeenden.Top;
  620.   ggeProgress.Top := lstSongs.Top + lstSongs.Height + lstOrdner.Left;
  621.   btnStart.Top := ggeProgress.Top;
  622.   btnPause.Top := btnStart.Top;
  623.   btnStopp.Top := btnPause.Top;
  624.   status1.top := ggeProgress.Top + ggeProgress.Height + 2;
  625.   status2.top := status1.top;
  626.  
  627.   // Breitenverwaltung
  628.   lstSongs.Width := round((MainForm.ClientWidth - 4 * lstOrdner.Left - grpPlayMode.Width) / 2);
  629.   lstOrdner.Width := lstSongs.Width;
  630.   lstSongs.Left := 2 * lstOrdner.Left + lstOrdner.Width;
  631.   grpPlayMode.Left := lstOrdner.Left + lstSongs.Left + lstSongs.Width;
  632.   grpRunMode.Left := grpPlayMode.Left;
  633.   grpVolume.Left := grpPlayMode.Left;
  634.   lblSongs.Left := lstSongs.Left;
  635.   lblOrdner.Left := lstOrdner.Left;
  636.   btnBeenden.Width := round((lstOrdner.Width - btnBeenden.Left) / 2);
  637.   btnOrdner.Width := btnBeenden.Width;
  638.   btnOrdner.Left := 2 * btnBeenden.Left + btnBeenden.Width;
  639.   ggeProgress.Width := lstSongs.Width;
  640.   ggeProgress.Left := lstSongs.Left;
  641.   status1.left := ggeProgress.Left;
  642.   status2.left := ggeProgress.left + ggeProgress.Width - status2.width;
  643.   btnStart.Left := grpPlayMode.Left;
  644.   btnStart.Width := round((grpPlayMode.Width - 2 * lstOrdner.Left) / 100 * 50);
  645.   btnPause.Width := round((grpPlayMode.Width - 2 * lstOrdner.Left) / 100 * 25);
  646.   btnStopp.Width := round((grpPlayMode.Width - 2 * lstOrdner.Left) / 100 * 25);
  647.   btnPause.Left := btnBeenden.Left + btnStart.Left + btnStart.Width;
  648.   btnStopp.Left := btnBeenden.Left + btnPause.Left + btnPause.Width;
  649. end;
  650.  
  651. procedure TMainForm.NextSong();
  652. var
  653.   actrand: integer;
  654. begin
  655.   if chkRepeatSong.Checked then
  656.     mediaplayer.Play
  657.   else
  658.   begin
  659.     if radPlayMode2.Checked then
  660.     begin
  661.       randomize();
  662.       repeat
  663.         actrand := random(lstSongs.Items.Count);
  664.       until actrand <> lstSongs.ItemIndex;
  665.       lstSongs.ItemIndex := actrand;
  666.       lstSongs.Selected[lstSongs.ItemIndex] := true;
  667.       lstSongsClick(self);
  668.       btnStart.Click;
  669.     end;
  670.     if radPlayMode1.Checked then
  671.     begin
  672.       if lstSongs.ItemIndex+1 = lstSongs.Items.Count then
  673.         lstSongs.ItemIndex := 0
  674.       else
  675.         lstSongs.ItemIndex := lstSongs.ItemIndex+1;
  676.       lstSongs.Selected[lstSongs.ItemIndex] := true;
  677.       lstSongsClick(self);
  678.       btnStart.Click;
  679.     end;
  680.     if radPlayMode3.Checked then
  681.     begin
  682.       ggeProgress.Position := ggeProgress.Min;
  683.       BtnStart.Enabled := true;
  684.       BtnStopp.Enabled := false;
  685.       btnPause.Enabled := false;
  686.     end;
  687.   end;
  688. end;
  689.  
  690. end.
  691.