Einzelnen Beitrag anzeigen

Amateurprofi

Registriert seit: 17. Nov 2005
Ort: Hamburg
1.087 Beiträge
 
Delphi XE2 Professional
 
#1

Noch ein Problem mit TMediaPlayer

  Alt 29. Jan 2025, 05:37
Ich hatte hier https://www.delphipraxis.net/216394-...diaplayer.html über ein Problem berichtet und nach Lösungen gesucht.
Ein weiteres Problem, das gelöst ist, das ich aber schildern nöchte, falls mal jemand ähnliche Erfahrungen macht:

Das Problem:
In meinem Programm zum Abspielen von .mp3's gibt es eine Option, dass beim Öffnen des Programms die .mp3, die vor dem letzem Schließen des Programms gespielt wurde, automatisch abgespielt wird.
Wenn die Option gesetzt ist, wird am Ende von Main.FormCreate das Abspielen dieser Datei veranlasst, und alles ist gut.
Ist dagegen die Option nicht gesetzt, wird keine .mp3 abgespielt.
Wenn ich später durch Doppelklick auf einen Eintrag in der Playerliste diese Datei abspielen will, kommt die Fehlermeldung
"Der Befehl erfordert einen Parameter. Geben Sie einen an."

Die Ursache:
In TMediaPlayer.Open wird ein
OpenParm.dwCallback := Handle; gemacht.
Vor Ausführung ist die Variable FFlags = 514 (MCI_OPEN_ELEMENT + mci_Wait)
Nach der Ausführung ist FFlags =258 (mci_Open_Shareable+ mci_Wait)
und im folgenden
FError := mciSendCommand(0, mci_Open, FFlags, UIntPtr(@OpenParm)); wird FError=273 gesetzt und dann mit
Delphi-Quellcode:
  if FError <> 0 then {problem opening device}
    raise EMCIDeviceError.Create(ErrorMessage)
die besagte Fehlermeldung ausgelöst.
Wohlgemerkt:
Das passiert nur, wenn nicht bereits im Main.FormCreate eine .mp3 abgespielt wurde, und nur beim ersten Versuch, eine .mp3 abzuspielen.
Nach tagelanger Suche habe ich herausgefunden, dass im
TMediaPlayer.GetMode: TMPModes; FFlags gesetzt wird.
M.E. ist es ein Fehler im Design, dass für FFlags keine lokale Variable verwendet wird.

Die Lösung des Problems:
Wenn im FormCreate nicht automatisch eine .mp3 abgespielt wird, mache ich ein
Dummy:=MPlayer.Player.Handle; was bewirkt, dass ein Handle existiert und bei OpenParm.dwCallback := Handle; nicht der im Aufrufstack gezeigte Rattenschwanz an Funktionsaufrufen gemacht wird.

Frage am Rande:
Gibt es (mit Bordmitteln) eine Möglichkeit eine bestimmte Speicherstelle zu überwachen und bei einer Änderung automatisch an der Stelle, die die Änderung durchführt anzuhalten.
Ich hatte mir so geholfen dass ich in der Liste der überwachten Ausdrücke
1) Die Adresse von FFlags ermittelte.
2) Einen Speicherauszug von der Adresse zeigen ließ.
und dann mit F7 solange weitergegangen bin, bis sich an dieser Adresse etwas geändert hat.
(war recht zeitaufwendig).

Der Übeltäter
Delphi-Quellcode:
function TMediaPlayer.GetMode: TMPModes;
var
  StatusParm: TMCI_Status_Parms;
begin
  FFlags := mci_Wait or mci_Status_Item;
  StatusParm.dwItem := mci_Status_Mode;
{$IF DEFINED(CLR)}
  FError := mciSendCommand( DeviceID, mci_Status, FFlags, StatusParm);
{$ELSE}
  FError := mciSendCommand( FDeviceID, mci_Status, FFlags, UIntPtr(@StatusParm));
{$IFEND}
  Result := TMPModes(StatusParm.dwReturn - 524); {MCI Mode #s are 524+enum}
end;

Der Aufrufstack
Code:
Vcl.MPlayer.TMediaPlayer.GetMode
Music_Player.TMPlayer.GetMode
Music_Main.TMain.FormCanResize($2966C50,1267,572,True)
Vcl.Controls.TControl.CanResize(???,???)
Vcl.Controls.TWinControl.CanResize(???,???)
Vcl.Controls.TControl.DoCanResize(1632096,???)
Vcl.Controls.TControl.CheckNewSize(1267,1631964)
Vcl.Controls.TWinControl.WMWindowPosChanging((70, (), 0, (), $18EB20, 0))
Vcl.Forms.TCustomForm.WMWindowPosChanging((70, (), 0, (), $18EB20, 0))
Vcl.Controls.TControl.WndProc((70, 0, 1633056, 0, 0, 0, (), 60192, 24, (), 0, 0, ()))
Vcl.Controls.TWinControl.WndProc((70, 0, 1633056, 0, 0, 0, (), 60192, 24, (), 0, 0, ()))
Vcl.Forms.TCustomForm.WndProc((70, 0, 1633056, 0, 0, 0, (), 60192, 24, (), 0, 0, ()))
Vcl.Controls.TWinControl.MainWndProc(???)
System.Classes.StdWndProc(328612,70,0,1633056)
:00492cf4 TControl.CanResize + $28
Vcl.Controls.TWinControl.AlignControls($29227B0,(0, 0, 1259, 492, (0, 0), (1259, 492)))
Vcl.Forms.TScrollingWinControl.AlignControls($29227B0,???)
Vcl.Forms.TCustomForm.AlignControls(???,(0, 0, 1259, 492, (0, 0), (1259, 492)))
Vcl.Controls.TWinControl.AlignControl($29227B0)
Vcl.Controls.TControl.RequestAlign
Vcl.Controls.TWinControl.RequestAlign
Vcl.Controls.TWinControl.SetBounds(???,???,29,30)
Vcl.MPlayer.TMediaPlayer.WMSize((1633904, (), 4813467, 61012, 24, (), 4813491))
Vcl.Controls.TControl.WndProc((5, 0, 1966080, 0, 0, 0, (), 0, 30, (), 0, 0, ()))
Vcl.Controls.TWinControl.WndProc((5, 0, 1966080, 0, 0, 0, (), 0, 30, (), 0, 0, ()))
Vcl.Controls.TWinControl.MainWndProc(???)
System.Classes.StdWndProc(853926,5,0,1966080)
Winapi.Windows.CreateWindowEx(???,???,nil {#0},1140916224,925,3,0,30,328612,0,4194304,nil)
Vcl.Controls.TWinControl.CreateWindowHandle($18F464)
Vcl.Controls.TWinControl.CreateWnd
Vcl.Controls.TWinControl.CreateHandle
Vcl.Controls.TWinControl.HandleNeeded
Vcl.Controls.TWinControl.GetHandle
Vcl.MPlayer.TMediaPlayer.Open
Music_Player.TMPlayer.PlayFile(9)
Music_Main.TMain.PlayFile(9)
Music_Main.TMain.lbPlayListDblClick($2913D10)
Miniaturansicht angehängter Grafiken
fehlermeldung.png   ueberwachte-ausdruecke.png  
Gruß, Klaus
Die Titanic wurde von Profis gebaut,
die Arche Noah von einem Amateur.
... Und dieser Beitrag vom Amateurprofi....
  Mit Zitat antworten Zitat