ATL & Windows Media

Started by James Waites, June 28, 2004, 05:54:21 PM

Previous topic - Next topic

James Waites

Hello,
I am thinking about buying FF but first I have a question.  I downloaded the demo to play around with and have put windows media player on my form using atl.  Now I cannot figure out how to send commands to media player to play a video or go full screen.  I just cannot figure it out.  If someone could help me along and help me figure it out that would be great.  I am trying to play a avi file located on my hard disk.  

Thank You


James Waites

Jose,
I'm sorry but I don't understand that example.  maybe it's because I don't know html or scripting, I just figured that there was a way to do it from within firefly since I could already put the control on the form.  Is it possible to do this with ff?

James Waites

Jose,
I am sorry I owe you an apology!  That example did set me off on the right foot!!  

Thanks for pointing me in the right direction.

Jose Roca

It is not a problem of FireFly but that PowerBasic COM automation only can deal with Dispatch interfaces, and the IServiceProvider and IWMPRemoteMediaServices interfaces needed to interface with Windows Media Player are derived from IUnknown. Maybe I would be able to make wrapper functions to be used with FireFly, but I only have the .h file for IServiceProvider, not for IWMPRemoteMediaServices and Windows Media Pleyer.

What my example does is to embed and instance of Internet Explorer (Mozilla can also be used) in a dialog and then to embed Windows Media Player in a blank  html page. This allows to manipulate WMP using VBScript or JavaScript in the same way as web pages do.

This is the C interface for IServiceProvider. Can anyone provide the missing ones?

EXTERN_C const IID IID_IServiceProvider;


   
   MIDL_INTERFACE("6d5140c1-7436-11ce-8034-00aa006009fa")
   IServiceProvider : public IUnknown
   {
   public:
       virtual /* [local] */ HRESULT STDMETHODCALLTYPE QueryService(
           /* [in] */ REFGUID guidService,
           /* [in] */ REFIID riid,
           /* [out] */ void **ppvObject) = 0;
       
   };
   


   typedef struct IServiceProviderVtbl
   {
       BEGIN_INTERFACE
       
       HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
           IServiceProvider * This,
           /* [in] */ REFIID riid,
           /* [iid_is][out] */ void **ppvObject);
       
       ULONG ( STDMETHODCALLTYPE *AddRef )(
           IServiceProvider * This);
       
       ULONG ( STDMETHODCALLTYPE *Release )(
           IServiceProvider * This);
       
       /* [local] */ HRESULT ( STDMETHODCALLTYPE *QueryService )(
           IServiceProvider * This,
           /* [in] */ REFGUID guidService,
           /* [in] */ REFIID riid,
           /* [out] */ void **ppvObject);
       
       END_INTERFACE
   } IServiceProviderVtbl;

   interface IServiceProvider
   {
       CONST_VTBL struct IServiceProviderVtbl *lpVtbl;
   };

TechSupport

Hi Jose, thanks for handling this question  ;)

James Waites

Hi Jose,
THis is from the wmp.h file is it what you need?





/* interface IWMPRemoteMediaServices */
/* [unique][helpstring][uuid][object] */


EXTERN_C const IID IID_IWMPRemoteMediaServices;


   
   MIDL_INTERFACE("CBB92747-741F-44fe-AB5B-F1A48F3B2A59")
   IWMPRemoteMediaServices : public IUnknown
   {
   public:
       virtual HRESULT STDMETHODCALLTYPE GetServiceType(
           /* [out] */ BSTR *pbstrType) = 0;
       
       virtual HRESULT STDMETHODCALLTYPE GetApplicationName(
           /* [out] */ BSTR *pbstrName) = 0;
       
       virtual HRESULT STDMETHODCALLTYPE GetScriptableObject(
           /* [out] */ BSTR *pbstrName,
           /* [out] */ IDispatch **ppDispatch) = 0;
       
       virtual HRESULT STDMETHODCALLTYPE GetCustomUIMode(
           /* [out] */ BSTR *pbstrFile) = 0;
       
   };
   


   typedef struct IWMPRemoteMediaServicesVtbl
   {
       BEGIN_INTERFACE
       
       HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
           IWMPRemoteMediaServices * This,
           /* [in] */ REFIID riid,
           /* [iid_is][out] */ void **ppvObject);
       
       ULONG ( STDMETHODCALLTYPE *AddRef )(
           IWMPRemoteMediaServices * This);
       
       ULONG ( STDMETHODCALLTYPE *Release )(
           IWMPRemoteMediaServices * This);
       
       HRESULT ( STDMETHODCALLTYPE *GetServiceType )(
           IWMPRemoteMediaServices * This,
           /* [out] */ BSTR *pbstrType);
       
       HRESULT ( STDMETHODCALLTYPE *GetApplicationName )(
           IWMPRemoteMediaServices * This,
           /* [out] */ BSTR *pbstrName);
       
       HRESULT ( STDMETHODCALLTYPE *GetScriptableObject )(
           IWMPRemoteMediaServices * This,
           /* [out] */ BSTR *pbstrName,
           /* [out] */ IDispatch **ppDispatch);
       
       HRESULT ( STDMETHODCALLTYPE *GetCustomUIMode )(
           IWMPRemoteMediaServices * This,
           /* [out] */ BSTR *pbstrFile);
       
       END_INTERFACE
   } IWMPRemoteMediaServicesVtbl;

   interface IWMPRemoteMediaServices
   {
       CONST_VTBL struct IWMPRemoteMediaServicesVtbl *lpVtbl;
   };

   





   (This)->lpVtbl -> QueryInterface(This,riid,ppvObject)


   (This)->lpVtbl -> AddRef(This)


   (This)->lpVtbl -> Release(This)



   (This)->lpVtbl -> GetServiceType(This,pbstrType)


   (This)->lpVtbl -> GetApplicationName(This,pbstrName)


   (This)->lpVtbl -> GetScriptableObject(This,pbstrName,ppDispatch)


   (This)->lpVtbl -> GetCustomUIMode(This,pbstrFile)








HRESULT STDMETHODCALLTYPE IWMPRemoteMediaServices_GetServiceType_Proxy(
   IWMPRemoteMediaServices * This,
   /* [out] */ BSTR *pbstrType);


void __RPC_STUB IWMPRemoteMediaServices_GetServiceType_Stub(
   IRpcStubBuffer *This,
   IRpcChannelBuffer *_pRpcChannelBuffer,
   PRPC_MESSAGE _pRpcMessage,
   DWORD *_pdwStubPhase);


HRESULT STDMETHODCALLTYPE IWMPRemoteMediaServices_GetApplicationName_Proxy(
   IWMPRemoteMediaServices * This,
   /* [out] */ BSTR *pbstrName);


void __RPC_STUB IWMPRemoteMediaServices_GetApplicationName_Stub(
   IRpcStubBuffer *This,
   IRpcChannelBuffer *_pRpcChannelBuffer,
   PRPC_MESSAGE _pRpcMessage,
   DWORD *_pdwStubPhase);


HRESULT STDMETHODCALLTYPE IWMPRemoteMediaServices_GetScriptableObject_Proxy(
   IWMPRemoteMediaServices * This,
   /* [out] */ BSTR *pbstrName,
   /* [out] */ IDispatch **ppDispatch);


void __RPC_STUB IWMPRemoteMediaServices_GetScriptableObject_Stub(
   IRpcStubBuffer *This,
   IRpcChannelBuffer *_pRpcChannelBuffer,
   PRPC_MESSAGE _pRpcMessage,
   DWORD *_pdwStubPhase);


HRESULT STDMETHODCALLTYPE IWMPRemoteMediaServices_GetCustomUIMode_Proxy(
   IWMPRemoteMediaServices * This,
   /* [out] */ BSTR *pbstrFile);


void __RPC_STUB IWMPRemoteMediaServices_GetCustomUIMode_Stub(
   IRpcStubBuffer *This,
   IRpcChannelBuffer *_pRpcChannelBuffer,
   PRPC_MESSAGE _pRpcMessage,
   DWORD *_pdwStubPhase);





Jose Roca

Yes. Thanks very much. I will need it if one day I plan to make my own player. But I have installed Windows Media Player 9 and found that it is very easy to add it to a SDK dialog.

After creating an instance of Windows Media Player with FireFly as you already have done, all you need to play a file is:

To set the path of the file:

  vVar = "D:\Archivos de Programa\Movie Maker\sample.wmv"  ' --> change path as needed
  object let DISPATCH_FORM1_OCXCONTROL1.URL = vVar

To play the file:

  object call DISPATCH_FORM1_OCXCONTROL1.controls.play

So you can, for example, add an edit field to enter the path and a button to play it, adding the above code in the event for the play button.

Jose Roca

I have added an edit control and a button and then in the clicked event of the button I read the content of the edit field I have added the following code and works perfect. Easy, isn't it?

FUNCTION FORM1_COMMAND1_BN_CLICKED (ControlIndex AS LONG, hWndForm AS DWORD, hWndControl AS DWORD, _
        idButtonControl AS LONG) AS LONG
 
  LOCAL strText AS STRING, vURL AS VARIANT                                                        
  CONTROL GET TEXT gFF_hDlg, IDC_FORM1_TEXT1 TO strText
  vURL = strText
 
  OBJECT LET DISPATCH_FORM1_OCXCONTROL1.URL = vUrl
  OBJECT CALL DISPATCH_FORM1_OCXCONTROL1.controls.play
 
END FUNCTION

TechSupport

Quote from: Jose RocaI have added an edit control and a button and then in the clicked event of the button I read the content of the edit field I have added the following code and works perfect. Easy, isn't it?

:thumbsup:

Also, to make the code easier, you don't even need to use PB's DDT commands. FireFly's internal functions make it even easier to retrieve the TextBox text. Also, there is no need for the "gFF_hDlg" variable because all HWND_ variables in FireFly are global (accessible via the "Handles and Control ID's" dialog).


FUNCTION FORM1_COMMAND1_BN_CLICKED (ControlIndex AS LONG, hWndForm AS DWORD, hWndControl AS DWORD, _
        idButtonControl AS LONG) AS LONG
 
  LOCAL strText AS STRING, vURL AS VARIANT                                                        
 
'Instead of the following DDT
 'CONTROL GET TEXT gFF_hDlg, IDC_FORM1_TEXT1 TO strText

'Use this instead...
  strText = FF_TextBox_GetText (HWND_FORM1_TEXT1)

  vURL = strText
 
  OBJECT LET DISPATCH_FORM1_OCXCONTROL1.URL = vUrl
  OBJECT CALL DISPATCH_FORM1_OCXCONTROL1.controls.play
 
END FUNCTION

Roger Garstang

Do you have the complete project files for this?  I'd like to actually see this because I haven't played with the OCX stuff yet.  Might make a good Sample too.

Jose Roca

Sorry Paul. I have been so busy that I haven't take the time to learn the new wrapper functions  :D

There is a problem that I have encountered with OCX embeded in SDK windows. If I close the main window clicking the x button sometimes the program remains in memory. I have found that I have to intercept %WM_SYSCOMMAND and send a %WM_CLOSE or %WM_DESTROY message.

     CASE %WM_SYSCOMMAND
        ' Capture this message and send a WM_DESTROY message
        ' or the program will remain in memory
        IF (wParam AND &HFFF0) = %SC_CLOSE THEN
           SendMessage hWnd, %WM_CLOSE, wParam, lParam
           EXIT FUNCTION
        END IF

Roger Garstang

I wondered about that myself with any FF App.  When I first started using it I was hearing about it needing to call the FF function to close the window, but I never had it call anything or post a CLOSE message like you did above to make sure it gets it.

TechSupport

Quote from: Jose RocaIf I close the main window clicking the x button sometimes the program remains in memory. I have found that I have to intercept %WM_SYSCOMMAND and send a %WM_CLOSE or %WM_DESTROY message.

Thanks Jose, I have added your code to the FireFly code generator.

Roger Garstang

That might make a problem for those of us that capture the X button and block it...unless you return %TRUE from it or something and route everything through WM_CLOSE, or put it in the blocks after the form's CUSTOM.