Subversion Repositories musikbox

Rev

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