Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Control '' has no parent window (TMediaPlayer) (https://www.clubdelphi.com/foros/showthread.php?t=79782)

sbraceras 10-08-2012 06:03:37

Control '' has no parent window (TMediaPlayer)
 
Hola, a ver si pueden ayudarme, mi pregunta es muy simple.
¿Cómo puedo hacer para crear un objeto MediaPlayer en una unit que no tiene un Form asociado?
Me está arrojando el error Control '' has no parent window y supongo que es porque no tiene una ventana 'padre' donde mostrarse el componente.

Tengo una unit Varios.pas que la llamo en todos lados de mi aplicación. Aprovechando esto, quiero crear el objeto en esa unit para que esté disponible siempre, en cualquier formulario.

En una parte de una función hice lo siguiente:

Código Delphi [-]
MediaPlayer := TMediaPlayer.Create(Application);
MediaPlayer.Close;
MediaPlayer.FileName := PathAndFile;
MediaPlayer.Open;
MediaPlayer.Play;

Y ahí es donde me tira el error. No puedo usar ese componente sin asociarle una ventana 'padre'?
Espero haber sido claro y que puedan ayudarme!

Muchas Gracias,
Santiago

ecfisa 10-08-2012 08:38:37

Hola sbraceras.

Cita:

No puedo usar ese componente sin asociarle una ventana 'padre'?
No, pero podes enviar el parent como parámetro a la unidad. Por si te sirve de guía, te pongo un código de ejemplo (muy básico) de como podrías hacer:
Código Delphi [-]
unit Unit2;

interface

uses Controls, MPlayer;

type
  TClase = class(TObject)
  private
    ...
    procedure PlayMediaNotify(Sender: TObject);
  public
    ...
    procedure PlayMedia(aWCtrl: TWinControl; const aFileName: string);
    ...
  end;

var
  MClase: TClase;

implementation

...
procedure TClase.PlayMediaNotify(Sender: TObject);
begin
  with TMediaPlayer(Sender) do
    if NotifyValue in [nvSuccessful,nvFailure] then
      Free;
end;

procedure TClase.PlayMedia(aWCtrl: TWinControl; const aFileName: string);
begin
  with TMediaPlayer.Create(nil) do
  begin
    Parent:= aWCtrl;
    Close;
    OnNotify:= PlayMediaNotify;
    FileName:= aFileName;
    Open;
    Play;
  end;
end;
...

end.

Llamada:
Código Delphi [-]
uses Unit2;
...
procedure TForm1.Button1Click(Sender: TObject);
...
begin
  ...
  MClase.PlayMedia(Form1,'C:\Users\Usuario\Music\Prueba.mp3');
end;

Saludos.

ecfisa 10-08-2012 09:17:58

Hola de nuevo.

Se me ocurrió qP:-), que si no precisas la presencia de los TButtonSet, sería mas sencillo y versátil usar la función mciSendString:

Código Delphi [-]
unit Unit2;
....

implementation

uses MMSystem;

procedure PlayMediaIn(aWCtrl:TWinControl; aFile: string);
var
 mciStr: string;
begin
  mciStr:= Format('%d %d %d %d',[aWCtrl.Left,aWCtrl.Top,aWCtrl.Width,aWCtrl.Height]);
  mciSendString('close alias1', nil,0, 0);
  mciSendString(PChar('open "' + aFile + '" alias alias1'), nil, 0, 0);
  mciSendString(PChar('window alias1 handle ' + IntToStr(aWCtrl.Handle)), nil,0,0);
  mciSendString(PChar('put alias1' + mciStr),nil,0,0);
  mciSendString('play alias1', nil, 0, 0);
end;
...
end.

Llamada de ejemplo:
Código Delphi [-]
uses Unit2;
...
procedure TForm1.Button1Click(Sender: TObject);
begin
  // reproduce en un TPanel, TForm, etc.
  PlayMediaIn(Panel1, 'C:\Users\Public\Videos\Sample Videos\Butterfly.wmv');
end;
...

Saludos. :)

sbraceras 10-08-2012 16:03:52

Muy amable ecfisa!
Lo único que quiero hacer es reproducir mp3, no videos. Por esto es que de verdad no necesitaría ninguna ventana 'padre'. Y los botones del MediaPlayer no los preciso realmente.

Ya me habías recomendado usar la función mciSendString. El problema es que necesito saber cuando finaliza cada archivo de audio, para luego reproducir otro a continuación. Me recomendaste el parámetro 'wait' recuerdo, pero se cuelga la aplicación esperando a que finalice la reproducción y no me sirve. Y no quiero crear un thread tampoco pues es más engorroso. Por esto es que opté por el TMediaPlayer. Lo que hice fue poner un Timer que vaya 'mirando' la condición if MediaPlayer.Position = MediaPlayer.Length then begin y listo.
Voy a optar me parece por enviarle el padre por parámetro a una función PlayMedia(aWCtrl: TWinControl; const aFileName: string); y esconderé el componente entero, pues no quiero que aparezca nada del componente en pantalla. O bien definitivamente crearé un Form nuevo y colocaré ahí el componente. Cómo lo ves?

Gracias de nuevo! :)

Delphius 10-08-2012 19:55:39

Pero yo no entiendo... nada te impide poner el componente en cualquier lado del form y establecer en false su propiedad Visible. Si la idea es tener el TMediaPlayer sin estar mostrandolo me parece la manera más simple, y que no requiere código alguno de hacerlo.

Saludos,

sbraceras 10-08-2012 21:13:09

Cita:

Empezado por Delphius (Mensaje 439330)
Pero yo no entiendo... nada te impide poner el componente en cualquier lado del form y establecer en false su propiedad Visible. Si la idea es tener el TMediaPlayer sin estar mostrandolo me parece la manera más simple, y que no requiere código alguno de hacerlo.

Saludos,

Es lo que voy a hacer, pero enviándole el padre por parámetro y creando UN solo objeto MediaPlayer, pues no quiero colocar 5 TMediaPlayer en las 5 pantallas de mi aplicación donde quiero ejecutar sonidos de ayuda.

Gracias Delphius!
Saludos

ecfisa 11-08-2012 02:32:03

Cita:

Empezado por sbraceras (Mensaje 439308)
Lo único que quiero hacer es reproducir mp3, no videos.

Hola sbraceras.

En realidad la función reproduce videos o audio indistintamente. Podrías hacer lo siguiente sin ningún problema:
Código Delphi [-]
procedure TForm1.Button1Click(Sender: TObject);
begin
  PlayMediaIn(Form1, 'C:\Users\User\Music\prueba.mp3');
end;

Saludos.:)

Delphius 11-08-2012 05:43:38

Cita:

Empezado por sbraceras (Mensaje 439338)
Es lo que voy a hacer, pero enviándole el padre por parámetro y creando UN solo objeto MediaPlayer, pues no quiero colocar 5 TMediaPlayer en las 5 pantallas de mi aplicación donde quiero ejecutar sonidos de ayuda.

Gracias Delphius!
Saludos

Nada te impide poner uno sólo en tu form principal e invocar a éste pasando la ruta del archivo mientras está abierto el form en cuestión.
De este modo no interesa cuantos forms existan... como el Form Principal si o si debe estar presente (de cerrarlo se cierra la aplicación).

Saludos,

Casimiro Notevi 11-08-2012 09:24:30

Cita:

Empezado por Delphius (Mensaje 439360)
Nada te impide poner uno sólo en tu form principal e invocar a éste pasando la ruta del archivo mientras está abierto el form en cuestión.
De este modo no interesa cuantos forms existan... como el Form Principal si o si debe estar presente (de cerrarlo se cierra la aplicación).
Saludos,

Exacto, la verdad es que no he entendido para qué se quiere uno en cada form.


La franja horaria es GMT +2. Ahora son las 13:16:58.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi