This series implement enough of WMP for WPF's MediaPlayer class to be mostly functional and makes "Magic The Gathering: Online" have sound.
Anton Romanov (7): wmp: Add IWMPPlayer interface wmp: Implement IConnectionPoint[Container] and add _WMPOCXEvents wmp: add IWMPControls stub implementation wmp: Add wmp defs wmp: Add IWMPMedia stub wmp: Add IWMPNetwork stub wmp: Implement minimal headless WMP
dlls/wmp/Makefile.in | 3 +- dlls/wmp/events.c | 388 ++++++++++++++++++ dlls/wmp/oleobj.c | 81 +--- dlls/wmp/player.c | 1013 +++++++++++++++++++++++++++++++++++++++++++++-- dlls/wmp/tests/oleobj.c | 2 +- dlls/wmp/wmp_main.c | 2 + dlls/wmp/wmp_private.h | 59 ++- dlls/wmp/wmpids.h | 437 ++++++++++++++++++++ include/wmp.idl | 27 +- 9 files changed, 1924 insertions(+), 88 deletions(-) create mode 100644 dlls/wmp/events.c create mode 100644 dlls/wmp/wmpids.h
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/oleobj.c | 3 +++ include/wmp.idl | 27 ++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-)
diff --git a/dlls/wmp/oleobj.c b/dlls/wmp/oleobj.c index acf38f3223..ea989f00e3 100644 --- a/dlls/wmp/oleobj.c +++ b/dlls/wmp/oleobj.c @@ -263,6 +263,9 @@ static HRESULT WINAPI OleObject_QueryInterface(IOleObject *iface, REFIID riid, v }else if(IsEqualGUID(riid, &IID_IWMPPlayer4)) { TRACE("(%p)->(IID_IWMPPlayer4 %p)\n", This, ppv); *ppv = &This->IWMPPlayer4_iface; + }else if(IsEqualGUID(riid, &IID_IWMPPlayer)) { + TRACE("(%p)->(IID_IWMPPlayer %p)\n", This, ppv); + *ppv = &This->IWMPPlayer4_iface; }else if(IsEqualGUID(riid, &IID_IWMPSettings)) { TRACE("(%p)->(IID_IWMPSettings %p)\n", This, ppv); *ppv = &This->IWMPSettings_iface; diff --git a/include/wmp.idl b/include/wmp.idl index a879ab7c83..442b702138 100644 --- a/include/wmp.idl +++ b/include/wmp.idl @@ -1007,6 +1007,31 @@ library WMPLib { HRESULT openPlayer([in] BSTR bstrURL); }
+ [ + odl, + uuid(6BF52A4F-394A-11D3-B153-00C04F79FAA6), + dual, + oleautomation + ] + interface IWMPPlayer : IWMPCore { + [id(0x00000013), propget] + HRESULT enabled([out, retval] VARIANT_BOOL* pbEnabled); + [id(0x00000013), propput] + HRESULT enabled([in] VARIANT_BOOL pbEnabled); + [id(0x00000015), propget] + HRESULT fullScreen([out, retval] VARIANT_BOOL* pbFullScreen); + [id(0x00000015), propput] + HRESULT fullScreen(VARIANT_BOOL pbFullScreen); + [id(0x00000016), propget] + HRESULT enableContextMenu([out, retval] VARIANT_BOOL* pbEnableContextMenu); + [id(0x00000016), propput] + HRESULT enableContextMenu(VARIANT_BOOL pbEnableContextMenu); + [id(0x00000017), propput] + HRESULT uiMode([in] BSTR pbstrMode); + [id(0x00000017), propget] + HRESULT uiMode([out, retval] BSTR* pbstrMode); + }; + [ odl, uuid(82a2986c-0293-4fd0-b279-b21b86c058be), @@ -1406,7 +1431,7 @@ library WMPLib { [default] interface IWMPPlayer4; /* interface IWMPPlayer3; */ /* interface IWMPPlayer2; */ - /* interface IWMPPlayer; */ + interface IWMPPlayer; interface IWMPControls; interface IWMPSettings; interface IWMPPlaylist;
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/Makefile.in | 3 +- dlls/wmp/events.c | 388 ++++++++++++++++++++++++++++++++++++++++++++++++ dlls/wmp/oleobj.c | 78 +++------- dlls/wmp/player.c | 9 +- dlls/wmp/tests/oleobj.c | 2 +- dlls/wmp/wmp_main.c | 2 + dlls/wmp/wmp_private.h | 20 ++- 7 files changed, 437 insertions(+), 65 deletions(-) create mode 100644 dlls/wmp/events.c
diff --git a/dlls/wmp/Makefile.in b/dlls/wmp/Makefile.in index 71ca0e5c7a..14d0a5694f 100644 --- a/dlls/wmp/Makefile.in +++ b/dlls/wmp/Makefile.in @@ -1,9 +1,10 @@ MODULE = wmp.dll -IMPORTS = user32 gdi32 oleaut32 +IMPORTS = uuid user32 gdi32 oleaut32 ole32
C_SRCS = \ oleobj.c \ player.c \ + events.c \ wmp_main.c
RC_SRCS = rsrc.rc diff --git a/dlls/wmp/events.c b/dlls/wmp/events.c new file mode 100644 index 0000000000..8d920254d5 --- /dev/null +++ b/dlls/wmp/events.c @@ -0,0 +1,388 @@ +#include "wmp_private.h" +#include "olectl.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wmp); + +static inline WindowsMediaPlayer *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface) +{ + return CONTAINING_RECORD(iface, WindowsMediaPlayer, IConnectionPointContainer_iface); +} + +static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, + REFIID riid, LPVOID *ppv) +{ + WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); + return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv); +} + +static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface) +{ + WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); + return IOleObject_AddRef(&This->IOleObject_iface); +} + +static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface) +{ + WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); + return IOleObject_Release(&This->IOleObject_iface); +} + +static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, + IEnumConnectionPoints **ppEnum) +{ + WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); + FIXME("(%p)->(%p)\n", This, ppEnum); + return E_NOTIMPL; +} + +static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, + REFIID riid, IConnectionPoint **ppCP){ + WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); + + if(!ppCP) { + WARN("ppCP == NULL\n"); + return E_POINTER; + } + + *ppCP = NULL; + + if(IsEqualGUID(&IID__WMPOCXEvents, riid)) { + TRACE("(%p)->(IID__WMPOCXEvents %p)\n", This, ppCP); + *ppCP = &This->wmpocx->IConnectionPoint_iface; + } + + if(*ppCP) { + IConnectionPoint_AddRef(*ppCP); + return S_OK; + } + + WARN("Unsupported IID %s\n", debugstr_guid(riid)); + return CONNECT_E_NOCONNECTION; +} + +static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = +{ + ConnectionPointContainer_QueryInterface, + ConnectionPointContainer_AddRef, + ConnectionPointContainer_Release, + ConnectionPointContainer_EnumConnectionPoints, + ConnectionPointContainer_FindConnectionPoint +}; + +static inline ConnectionPoint *impl_from_IConnectionPoint(IConnectionPoint *iface) +{ + return CONTAINING_RECORD(iface, ConnectionPoint, IConnectionPoint_iface); +} + +typedef struct { + IEnumConnections IEnumConnections_iface; + + LONG ref; + + ConnectionPoint *cp; + DWORD iter; +} EnumConnections; + +static inline EnumConnections *impl_from_IEnumConnections(IEnumConnections *iface) +{ + return CONTAINING_RECORD(iface, EnumConnections, IEnumConnections_iface); +} + +static HRESULT WINAPI EnumConnections_QueryInterface(IEnumConnections *iface, REFIID riid, void **ppv) +{ + EnumConnections *This = impl_from_IEnumConnections(iface); + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = &This->IEnumConnections_iface; + }else if(IsEqualGUID(&IID_IEnumConnections, riid)) { + TRACE("(%p)->(IID_IEnumConnections %p)\n", This, ppv); + *ppv = &This->IEnumConnections_iface; + }else { + WARN("Unsupported interface %s\n", debugstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI EnumConnections_AddRef(IEnumConnections *iface) +{ + EnumConnections *This = impl_from_IEnumConnections(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI EnumConnections_Release(IEnumConnections *iface) +{ + EnumConnections *This = impl_from_IEnumConnections(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) { + IConnectionPoint_Release(&This->cp->IConnectionPoint_iface); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI EnumConnections_Next(IEnumConnections *iface, ULONG cConnections, CONNECTDATA *pgcd, ULONG *pcFetched) +{ + EnumConnections *This = impl_from_IEnumConnections(iface); + ULONG cnt = 0; + + TRACE("(%p)->(%u %p %p)\n", This, cConnections, pgcd, pcFetched); + + while(cConnections--) { + while(This->iter < This->cp->sinks_size && !This->cp->sinks[This->iter]) + This->iter++; + if(This->iter == This->cp->sinks_size) + break; + + pgcd[cnt].pUnk = (IUnknown*)This->cp->sinks[This->iter]; + pgcd[cnt].dwCookie = cnt+1; + This->iter++; + cnt++; + } + + if(pcFetched) + *pcFetched = cnt; + return cnt ? S_OK : S_FALSE; +} + +static HRESULT WINAPI EnumConnections_Skip(IEnumConnections *iface, ULONG cConnections) +{ + EnumConnections *This = impl_from_IEnumConnections(iface); + FIXME("(%p)->(%u)\n", This, cConnections); + return E_NOTIMPL; +} + +static HRESULT WINAPI EnumConnections_Reset(IEnumConnections *iface) +{ + EnumConnections *This = impl_from_IEnumConnections(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI EnumConnections_Clone(IEnumConnections *iface, IEnumConnections **ppEnum) +{ + EnumConnections *This = impl_from_IEnumConnections(iface); + FIXME("(%p)->(%p)\n", This, ppEnum); + return E_NOTIMPL; +} + +static const IEnumConnectionsVtbl EnumConnectionsVtbl = { + EnumConnections_QueryInterface, + EnumConnections_AddRef, + EnumConnections_Release, + EnumConnections_Next, + EnumConnections_Skip, + EnumConnections_Reset, + EnumConnections_Clone +}; + +static HRESULT WINAPI ConnectionPoint_QueryInterface(IConnectionPoint *iface, + REFIID riid, LPVOID *ppv) +{ + ConnectionPoint *This = impl_from_IConnectionPoint(iface); + + *ppv = NULL; + + if(IsEqualGUID(&IID_IUnknown, riid)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = &This->IConnectionPoint_iface; + }else if(IsEqualGUID(&IID_IConnectionPoint, riid)) { + TRACE("(%p)->(IID_IConnectionPoint %p)\n", This, ppv); + *ppv = &This->IConnectionPoint_iface; + } + + if(*ppv) { + IConnectionPointContainer_AddRef(This->container); + return S_OK; + } + + WARN("Unsupported interface %s\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI ConnectionPoint_AddRef(IConnectionPoint *iface) +{ + ConnectionPoint *This = impl_from_IConnectionPoint(iface); + return IConnectionPointContainer_AddRef(This->container); +} + +static ULONG WINAPI ConnectionPoint_Release(IConnectionPoint *iface) +{ + ConnectionPoint *This = impl_from_IConnectionPoint(iface); + return IConnectionPointContainer_Release(This->container); +} + +static HRESULT WINAPI ConnectionPoint_GetConnectionInterface(IConnectionPoint *iface, IID *pIID) +{ + ConnectionPoint *This = impl_from_IConnectionPoint(iface); + + TRACE("(%p)->(%p)\n", This, pIID); + + *pIID = This->iid; + return S_OK; +} + +static HRESULT WINAPI ConnectionPoint_GetConnectionPointContainer(IConnectionPoint *iface, + IConnectionPointContainer **ppCPC) +{ + ConnectionPoint *This = impl_from_IConnectionPoint(iface); + + TRACE("(%p)->(%p)\n", This, ppCPC); + + *ppCPC = This->container; + IConnectionPointContainer_AddRef(This->container); + return S_OK; +} + +static HRESULT WINAPI ConnectionPoint_Advise(IConnectionPoint *iface, IUnknown *pUnkSink, + DWORD *pdwCookie) +{ + ConnectionPoint *This = impl_from_IConnectionPoint(iface); + IDispatch *disp; + DWORD i; + HRESULT hres; + + TRACE("(%p)->(%p %p)\n", This, pUnkSink, pdwCookie); + + hres = IUnknown_QueryInterface(pUnkSink, &This->iid, (void**)&disp); + if(FAILED(hres)) { + hres = IUnknown_QueryInterface(pUnkSink, &IID_IDispatch, (void**)&disp); + if(FAILED(hres)) + return CONNECT_E_CANNOTCONNECT; + } + + if(This->sinks) { + for(i=0; i<This->sinks_size; i++) { + if(!This->sinks[i]) + break; + } + + if(i == This->sinks_size) + This->sinks = HeapReAlloc(GetProcessHeap(), 0, This->sinks, + (++This->sinks_size)*sizeof(*This->sinks)); + }else { + This->sinks = heap_alloc(sizeof(*This->sinks)); + This->sinks_size = 1; + i = 0; + } + + This->sinks[i] = disp; + *pdwCookie = i+1; + + return S_OK; +} + +static HRESULT WINAPI ConnectionPoint_Unadvise(IConnectionPoint *iface, DWORD dwCookie) +{ + ConnectionPoint *This = impl_from_IConnectionPoint(iface); + + TRACE("(%p)->(%d)\n", This, dwCookie); + + if(!dwCookie || dwCookie > This->sinks_size || !This->sinks[dwCookie-1]) + return CONNECT_E_NOCONNECTION; + + IDispatch_Release(This->sinks[dwCookie-1]); + This->sinks[dwCookie-1] = NULL; + + return S_OK; +} + +static HRESULT WINAPI ConnectionPoint_EnumConnections(IConnectionPoint *iface, + IEnumConnections **ppEnum) +{ + ConnectionPoint *This = impl_from_IConnectionPoint(iface); + EnumConnections *ret; + + TRACE("(%p)->(%p)\n", This, ppEnum); + + ret = heap_alloc(sizeof(*ret)); + if(!ret) + return E_OUTOFMEMORY; + + ret->IEnumConnections_iface.lpVtbl = &EnumConnectionsVtbl; + ret->ref = 1; + ret->iter = 0; + + IConnectionPoint_AddRef(&This->IConnectionPoint_iface); + ret->cp = This; + + *ppEnum = &ret->IEnumConnections_iface; + return S_OK; +} + + +static const IConnectionPointVtbl ConnectionPointVtbl = +{ + ConnectionPoint_QueryInterface, + ConnectionPoint_AddRef, + ConnectionPoint_Release, + ConnectionPoint_GetConnectionInterface, + ConnectionPoint_GetConnectionPointContainer, + ConnectionPoint_Advise, + ConnectionPoint_Unadvise, + ConnectionPoint_EnumConnections +}; + +static void ConnectionPoint_Destroy(ConnectionPoint *This) +{ + DWORD i; + + for(i=0; i<This->sinks_size; i++) { + if(This->sinks[i]) + IDispatch_Release(This->sinks[i]); + } + + heap_free(This->sinks); + heap_free(This); +} + +static void ConnectionPoint_Create(REFIID riid, ConnectionPoint **cp, + IConnectionPointContainer *container) +{ + ConnectionPoint *ret = heap_alloc(sizeof(ConnectionPoint)); + + ret->IConnectionPoint_iface.lpVtbl = &ConnectionPointVtbl; + + ret->sinks = NULL; + ret->sinks_size = 0; + ret->container = container; + + ret->iid = *riid; + + *cp = ret; +} + +void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams) +{ + DWORD i; + + for(i=0; i<This->sinks_size; i++) { + if(This->sinks[i]) + IDispatch_Invoke(This->sinks[i], dispid, &IID_NULL, LOCALE_SYSTEM_DEFAULT, + DISPATCH_METHOD, dispparams, NULL, NULL, NULL); + } +} + +void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp) +{ + wmp->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl; + ConnectionPoint_Create(&IID__WMPOCXEvents, &wmp->wmpocx, &wmp->IConnectionPointContainer_iface); +} + +void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp) +{ + ConnectionPoint_Destroy(wmp->wmpocx); +} diff --git a/dlls/wmp/oleobj.c b/dlls/wmp/oleobj.c index ea989f00e3..8ac978218e 100644 --- a/dlls/wmp/oleobj.c +++ b/dlls/wmp/oleobj.c @@ -18,11 +18,11 @@
#include "wmp_private.h" #include "olectl.h" - #include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
+ static HWND get_container_hwnd(WindowsMediaPlayer *This) { IOleWindow *ole_window; @@ -306,6 +306,8 @@ static ULONG WINAPI OleObject_Release(IOleObject *iface)
if(!ref) { release_client_site(This); + ConnectionPointContainer_Destroy(This); + destroy_player(This); heap_free(This); }
@@ -874,55 +876,6 @@ static const IPersistStreamInitVtbl PersistStreamInitVtbl = { PersistStreamInit_InitNew };
-static inline WindowsMediaPlayer *impl_from_IConnectionPointContainer(IConnectionPointContainer *iface) -{ - return CONTAINING_RECORD(iface, WindowsMediaPlayer, IConnectionPointContainer_iface); -} - -static HRESULT WINAPI ConnectionPointContainer_QueryInterface(IConnectionPointContainer *iface, - REFIID riid, LPVOID *ppv) -{ - WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); - return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv); -} - -static ULONG WINAPI ConnectionPointContainer_AddRef(IConnectionPointContainer *iface) -{ - WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); - return IOleObject_AddRef(&This->IOleObject_iface); -} - -static ULONG WINAPI ConnectionPointContainer_Release(IConnectionPointContainer *iface) -{ - WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); - return IOleObject_Release(&This->IOleObject_iface); -} - -static HRESULT WINAPI ConnectionPointContainer_EnumConnectionPoints(IConnectionPointContainer *iface, - IEnumConnectionPoints **ppEnum) -{ - WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); - FIXME("(%p)->(%p)\n", This, ppEnum); - return E_NOTIMPL; -} - -static HRESULT WINAPI ConnectionPointContainer_FindConnectionPoint(IConnectionPointContainer *iface, - REFIID riid, IConnectionPoint **ppCP) -{ - WindowsMediaPlayer *This = impl_from_IConnectionPointContainer(iface); - FIXME("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppCP); - return CONNECT_E_NOCONNECTION; -} - -static const IConnectionPointContainerVtbl ConnectionPointContainerVtbl = -{ - ConnectionPointContainer_QueryInterface, - ConnectionPointContainer_AddRef, - ConnectionPointContainer_Release, - ConnectionPointContainer_EnumConnectionPoints, - ConnectionPointContainer_FindConnectionPoint -}; - HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) { @@ -941,22 +894,25 @@ HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory *iface, IUnknown *outer, wmp->IProvideClassInfo2_iface.lpVtbl = &ProvideClassInfo2Vtbl; wmp->IPersistStreamInit_iface.lpVtbl = &PersistStreamInitVtbl; wmp->IOleInPlaceObjectWindowless_iface.lpVtbl = &OleInPlaceObjectWindowlessVtbl; - wmp->IConnectionPointContainer_iface.lpVtbl = &ConnectionPointContainerVtbl; wmp->IOleControl_iface.lpVtbl = &OleControlVtbl;
wmp->ref = 1;
- init_player_ifaces(wmp); - - hdc = GetDC(0); - dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); - dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); - ReleaseDC(0, hdc); + hres = init_player(wmp); + if (hres == S_OK) { + ConnectionPointContainer_Init(wmp); + hdc = GetDC(0); + dpi_x = GetDeviceCaps(hdc, LOGPIXELSX); + dpi_y = GetDeviceCaps(hdc, LOGPIXELSY); + ReleaseDC(0, hdc);
- wmp->extent.cx = MulDiv(192, 2540, dpi_x); - wmp->extent.cy = MulDiv(192, 2540, dpi_y); + wmp->extent.cx = MulDiv(192, 2540, dpi_x); + wmp->extent.cy = MulDiv(192, 2540, dpi_y);
- hres = IOleObject_QueryInterface(&wmp->IOleObject_iface, riid, ppv); - IOleObject_Release(&wmp->IOleObject_iface); + hres = IOleObject_QueryInterface(&wmp->IOleObject_iface, riid, ppv); + IOleObject_Release(&wmp->IOleObject_iface); + } + if(hres != S_OK) + destroy_player(wmp); return hres; } diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 4c11c88d74..c410d6ef8f 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -22,6 +22,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
+static void update_state(WindowsMediaPlayer *wmp, int state); + static inline WindowsMediaPlayer *impl_from_IWMPPlayer4(IWMPPlayer4 *iface) { return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPPlayer4_iface); @@ -661,8 +663,13 @@ static const IWMPSettingsVtbl WMPSettingsVtbl = { WMPSettings_put_enableErrorDialogs };
-void init_player_ifaces(WindowsMediaPlayer *wmp) +void destroy_player(WindowsMediaPlayer* wmp) { + heap_free(wmp); +} + +HRESULT init_player(WindowsMediaPlayer *wmp) { wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl; wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl; + return S_OK; } diff --git a/dlls/wmp/tests/oleobj.c b/dlls/wmp/tests/oleobj.c index 2b646d7b1d..08c000590a 100644 --- a/dlls/wmp/tests/oleobj.c +++ b/dlls/wmp/tests/oleobj.c @@ -896,7 +896,7 @@ static void test_IConnectionPointContainer(IOleObject *oleobj)
point = NULL; hres = IConnectionPointContainer_FindConnectionPoint(container, &IID__WMPOCXEvents, &point); - todo_wine ok(hres == S_OK, "got: %08x\n", hres); + ok(hres == S_OK, "got: %08x\n", hres); if(point) IConnectionPoint_Release(point);
diff --git a/dlls/wmp/wmp_main.c b/dlls/wmp/wmp_main.c index 29b096f7fd..b97ad2879d 100644 --- a/dlls/wmp/wmp_main.c +++ b/dlls/wmp/wmp_main.c @@ -26,6 +26,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmp);
HINSTANCE wmp_instance;
+DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); + static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv) { *ppv = NULL; diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 7b7f51cd63..5abee6217d 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -22,6 +22,17 @@ #include "ole2.h" #include "wmp.h"
+typedef struct { + IConnectionPoint IConnectionPoint_iface; + + IConnectionPointContainer *container; + + IDispatch **sinks; + DWORD sinks_size; + + IID iid; +} ConnectionPoint; + struct WindowsMediaPlayer { IOleObject IOleObject_iface; IProvideClassInfo2 IProvideClassInfo2_iface; @@ -37,12 +48,19 @@ struct WindowsMediaPlayer { IOleClientSite *client_site; HWND hwnd; SIZEL extent; + + ConnectionPoint *wmpocx; };
-void init_player_ifaces(WindowsMediaPlayer*) DECLSPEC_HIDDEN; +HRESULT init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; +void destroy_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; +void ConnectionPointContainer_Init(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN; +void ConnectionPointContainer_Destroy(WindowsMediaPlayer *wmp) DECLSPEC_HIDDEN;
HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
+void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams); + void unregister_wmp_class(void) DECLSPEC_HIDDEN;
extern HINSTANCE wmp_instance DECLSPEC_HIDDEN;
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++- dlls/wmp/wmp_private.h | 1 + 2 files changed, 202 insertions(+), 2 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index c410d6ef8f..430f701539 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -29,6 +29,11 @@ static inline WindowsMediaPlayer *impl_from_IWMPPlayer4(IWMPPlayer4 *iface) return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPPlayer4_iface); }
+static inline WindowsMediaPlayer *impl_from_IWMPControls(IWMPControls *iface) +{ + return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPControls_iface); +} + static HRESULT WINAPI WMPPlayer4_QueryInterface(IWMPPlayer4 *iface, REFIID riid, void **ppv) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); @@ -118,8 +123,12 @@ static HRESULT WINAPI WMPPlayer4_get_playState(IWMPPlayer4 *iface, WMPPlayState static HRESULT WINAPI WMPPlayer4_get_controls(IWMPPlayer4 *iface, IWMPControls **ppControl) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%p)\n", This, ppControl); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, ppControl); + + IWMPSettings_AddRef(&This->IWMPSettings_iface); + *ppControl = &This->IWMPControls_iface; + return S_OK; }
static HRESULT WINAPI WMPPlayer4_get_settings(IWMPPlayer4 *iface, IWMPSettings **ppSettings) @@ -667,9 +676,199 @@ void destroy_player(WindowsMediaPlayer* wmp) { heap_free(wmp); }
+HRESULT WINAPI WMPControls_fastForward(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_fastReverse(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_get_currentItem(IWMPControls *iface, IWMPMedia **ppIWMPMedia) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%p)\n", This, ppIWMPMedia); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_get_currentMarker(IWMPControls *iface, LONG *plMarker) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%p)\n", This, plMarker); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_get_currentPosition(IWMPControls *iface, DOUBLE *pdCurrentPosition) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%p)\n", This, pdCurrentPosition); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_get_currentPositionString(IWMPControls *iface, BSTR *pbstrCurrentPosition) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%p)\n", This, pbstrCurrentPosition); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPControls_get_isAvailable(IWMPControls *iface, BSTR bstrItem, VARIANT_BOOL *pIsAvailable) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(bstrItem)); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_next(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_pause(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_play(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_playItem(IWMPControls *iface, IWMPMedia *pIWMPMedia) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%p)\n", This, pIWMPMedia); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_previous(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_put_currentItem(IWMPControls *iface, IWMPMedia *pIWMPMedia) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%p)\n", This, pIWMPMedia); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_put_currentMarker(IWMPControls *iface, LONG lMarker) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%d)\n", This, lMarker); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_put_currentPosition(IWMPControls *iface, DOUBLE dCurrentPosition) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%f)\n", This, dCurrentPosition); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPControls_stop(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPControls_QueryInterface(IWMPControls *iface, REFIID riid, void **ppv) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv); +} + +static ULONG WINAPI WMPControls_AddRef(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + return IOleObject_AddRef(&This->IOleObject_iface); +} + +static ULONG WINAPI WMPControls_Release(IWMPControls *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + return IOleObject_Release(&This->IOleObject_iface); +} + +static HRESULT WINAPI WMPControls_GetTypeInfoCount(IWMPControls *iface, UINT *pctinfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPControls_GetTypeInfo(IWMPControls *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%u %d %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPControls_GetIDsOfNames(IWMPControls *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPControls_Invoke(IWMPControls *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + FIXME("(%p)->(%d %s %d %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static const IWMPControlsVtbl WMPControlsVtbl = { + WMPControls_QueryInterface, + WMPControls_AddRef, + WMPControls_Release, + WMPControls_GetTypeInfoCount, + WMPControls_GetTypeInfo, + WMPControls_GetIDsOfNames, + WMPControls_Invoke, + WMPControls_get_isAvailable, + WMPControls_play, + WMPControls_stop, + WMPControls_pause, + WMPControls_fastForward, + WMPControls_fastReverse, + WMPControls_get_currentPosition, + WMPControls_put_currentPosition, + WMPControls_get_currentPositionString, + WMPControls_next, + WMPControls_previous, + WMPControls_get_currentItem, + WMPControls_put_currentItem, + WMPControls_get_currentMarker, + WMPControls_put_currentMarker, + WMPControls_playItem, +}; + HRESULT init_player(WindowsMediaPlayer *wmp) { wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl; wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl; + wmp->IWMPControls_iface.lpVtbl = &WMPControlsVtbl; return S_OK; } diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 5abee6217d..b047143b3e 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -42,6 +42,7 @@ struct WindowsMediaPlayer { IOleControl IOleControl_iface; IWMPPlayer4 IWMPPlayer4_iface; IWMPSettings IWMPSettings_iface; + IWMPControls IWMPControls_iface;
LONG ref;
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/wmpids.h | 437 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 437 insertions(+) create mode 100644 dlls/wmp/wmpids.h
diff --git a/dlls/wmp/wmpids.h b/dlls/wmp/wmpids.h new file mode 100644 index 0000000000..935a39d46c --- /dev/null +++ b/dlls/wmp/wmpids.h @@ -0,0 +1,437 @@ +// PLAY state +#define WMP_PLAY_STATE_UNDEFINED 0 +#define WMP_PLAY_STATE_STOPPED 1 +#define WMP_PLAY_STATE_PAUSED 2 +#define WMP_PLAY_STATE_PLAYING 3 +#define WMP_PLAY_STATE_SCAN_FORWARD 4 +#define WMP_PLAY_STATE_SCAN_REVERSE 5 +#define WMP_PLAY_STATE_BUFFERING 6 +#define WMP_PLAY_STATE_WAITING 7 +#define WMP_PLAY_STATE_MEDIA_ENDED 8 +#define WMP_PLAY_STATE_TRANSITIONING 9 +#define WMP_PLAY_STATE_READY 10 +#define WMP_PLAY_STATE_RECONNECTING 11 + +// MSDN: Player.openState +#define WMP_OPEN_STATE_UNDEFINED 0 +#define WMP_OPEN_STATE_PLAYLIST_CHANGING 1 +#define WMP_OPEN_STATE_PLAYLIST_LOCATING 2 +#define WMP_OPEN_STATE_PLAYLIST_CONNECTING 3 +#define WMP_OPEN_STATE_PLAYLIST_LOADING 4 +#define WMP_OPEN_STATE_PLAYLIST_OPENGING 5 +#define WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA 6 +#define WMP_OPEN_STATE_PLAYLIST_CHANGED 7 +#define WMP_OPEN_STATE_MEDIA_CHANGING 8 +#define WMP_OPEN_STATE_MEDIA_LOCATING 9 +#define WMP_OPEN_STATE_MEDIA_CONNECTING 10 +#define WMP_OPEN_STATE_MEDIA_LOADING 11 +#define WMP_OPEN_STATE_MEDIA_OPENING 12 +#define WMP_OPEN_STATE_MEDIA_OPEN 13 +#define WMP_OPEN_STATE_BEGIN_CODEC_ACQUISITION 14 +#define WMP_OPEN_STATE_END_CODEC_ACQUISITION 15 +#define WMP_OPEN_STATE_BEGIN_LICENSE_ACQUISITION 16 +#define WMP_OPEN_STATE_END_LICENSE_ACQUISITION 17 +#define WMP_OPEN_STATE_BEGIN_INDIVIDUALIZATION 18 +#define WMP_OPEN_STATE_END_INDIVIDUALIZATION 19 +#define WMP_OPEN_STATE_MEDIA_WAITING 20 +#define WMP_OPEN_STATE_OPENING_UNKNOWN_URL 21 + + + +// DISPID defines +#define DISPID_DELTA 50 + + +// IWMPCore +#define DISPID_WMPCORE_BASE 0 +#define DISPID_WMPCORE_URL (DISPID_WMPCORE_BASE + 1) +#define DISPID_WMPCORE_OPENSTATE (DISPID_WMPCORE_BASE + 2) +#define DISPID_WMPCORE_CLOSE (DISPID_WMPCORE_BASE + 3) +#define DISPID_WMPCORE_CONTROLS (DISPID_WMPCORE_BASE + 4) +#define DISPID_WMPCORE_SETTINGS (DISPID_WMPCORE_BASE + 5) +#define DISPID_WMPCORE_CURRENTMEDIA (DISPID_WMPCORE_BASE + 6) +#define DISPID_WMPCORE_NETWORK (DISPID_WMPCORE_BASE + 7) +#define DISPID_WMPCORE_MEDIACOLLECTION (DISPID_WMPCORE_BASE + 8) +#define DISPID_WMPCORE_PLAYLISTCOLLECTION (DISPID_WMPCORE_BASE + 9) +#define DISPID_WMPCORE_PLAYSTATE (DISPID_WMPCORE_BASE + 10) +#define DISPID_WMPCORE_VERSIONINFO (DISPID_WMPCORE_BASE + 11) +#define DISPID_WMPCORE_LAUNCHURL (DISPID_WMPCORE_BASE + 12) +#define DISPID_WMPCORE_CURRENTPLAYLIST (DISPID_WMPCORE_BASE + 13) +#define DISPID_WMPCORE_CDROMCOLLECTION (DISPID_WMPCORE_BASE + 14) +#define DISPID_WMPCORE_CLOSEDCAPTION (DISPID_WMPCORE_BASE + 15) +#define DISPID_WMPCORE_ISONLINE (DISPID_WMPCORE_BASE + 16) +#define DISPID_WMPCORE_ERROR (DISPID_WMPCORE_BASE + 17) +#define DISPID_WMPCORE_STATUS (DISPID_WMPCORE_BASE + 18) +#define DISPID_WMPCORE_LAST DISPID_WMPCORE_STATUS + +// IPlayer +#define DISPID_WMPOCX_BASE (DISPID_WMPCORE_LAST) +#define DISPID_WMPOCX_ENABLED (DISPID_WMPOCX_BASE + 1) +#define DISPID_WMPOCX_TRANSPARENTATSTART (DISPID_WMPOCX_BASE + 2) +#define DISPID_WMPOCX_FULLSCREEN (DISPID_WMPOCX_BASE + 3) +#define DISPID_WMPOCX_ENABLECONTEXTMENU (DISPID_WMPOCX_BASE + 4) +#define DISPID_WMPOCX_UIMODE (DISPID_WMPOCX_BASE + 5) +#define DISPID_WMPOCX_LAST DISPID_WMPOCX_UIMODE + +#define DISPID_WMPOCX2_BASE (DISPID_WMPOCX_LAST) +#define DISPID_WMPOCX2_STRETCHTOFIT (DISPID_WMPOCX2_BASE + 1) +#define DISPID_WMPOCX2_WINDOWLESSVIDEO (DISPID_WMPOCX2_BASE + 2) +#define DISPID_WMPOCX4_ISREMOTE (DISPID_WMPOCX2_BASE + 3) +#define DISPID_WMPOCX4_PLAYERAPPLICATION (DISPID_WMPOCX2_BASE + 4) +#define DISPID_WMPOCX4_OPENPLAYER (DISPID_WMPOCX2_BASE + 5) + + +// IWMPCore2 +#define DISPID_WMPCORE2_BASE (DISPID_WMPCORE_BASE + 39) +#define DISPID_WMPCORE2_DVD (DISPID_WMPCORE2_BASE + 1) +#define DISPID_WMPCORE3_NEWPLAYLIST (DISPID_WMPCORE2_BASE + 2) +#define DISPID_WMPCORE3_NEWMEDIA (DISPID_WMPCORE2_BASE + 3) + +// IWMPControl +// Note: Microsoft says these DISPIDs need to be contiguous +#define DISPID_WMPCONTROLS_BASE (DISPID_WMPCORE_BASE + DISPID_DELTA) +#define DISPID_WMPCONTROLS_PLAY (DISPID_WMPCONTROLS_BASE + 1) +#define DISPID_WMPCONTROLS_STOP (DISPID_WMPCONTROLS_BASE + 2) +#define DISPID_WMPCONTROLS_PAUSE (DISPID_WMPCONTROLS_BASE + 3) +#define DISPID_WMPCONTROLS_FASTFORWARD (DISPID_WMPCONTROLS_BASE + 4) +#define DISPID_WMPCONTROLS_FASTREVERSE (DISPID_WMPCONTROLS_BASE + 5) +#define DISPID_WMPCONTROLS_CURRENTPOSITION (DISPID_WMPCONTROLS_BASE + 6) +#define DISPID_WMPCONTROLS_CURRENTPOSITIONSTRING (DISPID_WMPCONTROLS_BASE + 7) +#define DISPID_WMPCONTROLS_NEXT (DISPID_WMPCONTROLS_BASE + 8) +#define DISPID_WMPCONTROLS_PREVIOUS (DISPID_WMPCONTROLS_BASE + 9) +#define DISPID_WMPCONTROLS_CURRENTITEM (DISPID_WMPCONTROLS_BASE + 10) +#define DISPID_WMPCONTROLS_CURRENTMARKER (DISPID_WMPCONTROLS_BASE + 11) +#define DISPID_WMPCONTROLS_ISAVAILABLE (DISPID_WMPCONTROLS_BASE + 12) +#define DISPID_WMPCONTROLS_PLAYITEM (DISPID_WMPCONTROLS_BASE + 13) +#define DISPID_WMPCONTROLS2_STEP (DISPID_WMPCONTROLS_BASE + 14) +#define DISPID_WMPCONTROLS3_AUDIOLANGUAGECOUNT (DISPID_WMPCONTROLS_BASE + 15) +#define DISPID_WMPCONTROLS3_GETAUDIOLANGUAGEID (DISPID_WMPCONTROLS_BASE + 16) +#define DISPID_WMPCONTROLS3_GETAUDIOLANGUAGEDESC (DISPID_WMPCONTROLS_BASE + 17) +#define DISPID_WMPCONTROLS3_CURRENTAUDIOLANGUAGE (DISPID_WMPCONTROLS_BASE + 18) +#define DISPID_WMPCONTROLS3_CURRENTAUDIOLANGUAGEINDEX (DISPID_WMPCONTROLS_BASE + 19) +#define DISPID_WMPCONTROLS3_GETLANGUAGENAME (DISPID_WMPCONTROLS_BASE + 20) +#define DISPID_WMPCONTROLS3_CURRENTPOSITIONTIMECODE (DISPID_WMPCONTROLS_BASE + 21) +#define DISPID_WMPCONTROLSFAKE_TIMECOMPRESSION (DISPID_WMPCONTROLS_BASE + 22) + +// IWMPSettings +#define DISPID_WMPSETTINGS_BASE (DISPID_WMPCONTROLS_BASE + DISPID_DELTA) +#define DISPID_WMPSETTINGS_AUTOSTART (DISPID_WMPSETTINGS_BASE + 1) +#define DISPID_WMPSETTINGS_BALANCE (DISPID_WMPSETTINGS_BASE + 2) +#define DISPID_WMPSETTINGS_INVOKEURLS (DISPID_WMPSETTINGS_BASE + 3) +#define DISPID_WMPSETTINGS_MUTE (DISPID_WMPSETTINGS_BASE + 4) +#define DISPID_WMPSETTINGS_PLAYCOUNT (DISPID_WMPSETTINGS_BASE + 5) +#define DISPID_WMPSETTINGS_RATE (DISPID_WMPSETTINGS_BASE + 6) +#define DISPID_WMPSETTINGS_VOLUME (DISPID_WMPSETTINGS_BASE + 7) +#define DISPID_WMPSETTINGS_BASEURL (DISPID_WMPSETTINGS_BASE + 8) +#define DISPID_WMPSETTINGS_DEFAULTFRAME (DISPID_WMPSETTINGS_BASE + 9) +#define DISPID_WMPSETTINGS_GETMODE (DISPID_WMPSETTINGS_BASE + 10) +#define DISPID_WMPSETTINGS_SETMODE (DISPID_WMPSETTINGS_BASE + 11) +#define DISPID_WMPSETTINGS_ENABLEERRORDIALOGS (DISPID_WMPSETTINGS_BASE + 12) +#define DISPID_WMPSETTINGS_ISAVAILABLE (DISPID_WMPSETTINGS_BASE + 13) +#define DISPID_WMPSETTINGS2_DEFAULTAUDIOLANGUAGE (DISPID_WMPSETTINGS_BASE + 14) +#define DISPID_WMPSETTINGS2_LIBRARYACCESSRIGHTS (DISPID_WMPSETTINGS_BASE + 15) +#define DISPID_WMPSETTINGS2_REQUESTLIBRARYACCESSRIGHTS (DISPID_WMPSETTINGS_BASE + 16) + +// IWMPPlayList +#define DISPID_WMPPLAYLIST_BASE (DISPID_WMPSETTINGS_BASE + DISPID_DELTA + DISPID_DELTA) +#define DISPID_WMPPLAYLIST_COUNT (DISPID_WMPPLAYLIST_BASE + 1) +#define DISPID_WMPPLAYLIST_NAME (DISPID_WMPPLAYLIST_BASE + 2) +#define DISPID_WMPPLAYLIST_GETITEMINFO (DISPID_WMPPLAYLIST_BASE + 3) +#define DISPID_WMPPLAYLIST_SETITEMINFO (DISPID_WMPPLAYLIST_BASE + 4) +#define DISPID_WMPPLAYLIST_CLEAR (DISPID_WMPPLAYLIST_BASE + 5) +#define DISPID_WMPPLAYLIST_INSERTITEM (DISPID_WMPPLAYLIST_BASE + 6) +#define DISPID_WMPPLAYLIST_APPENDITEM (DISPID_WMPPLAYLIST_BASE + 7) +#define DISPID_WMPPLAYLIST_REMOVEITEM (DISPID_WMPPLAYLIST_BASE + 8) +#define DISPID_WMPPLAYLIST_MOVEITEM (DISPID_WMPPLAYLIST_BASE + 9) +#define DISPID_WMPPLAYLIST_ATTRIBUTECOUNT (DISPID_WMPPLAYLIST_BASE + 10) +#define DISPID_WMPPLAYLIST_ATTRIBUTENAME (DISPID_WMPPLAYLIST_BASE + 11) +#define DISPID_WMPPLAYLIST_ITEM (DISPID_WMPPLAYLIST_BASE + 12) +#define DISPID_WMPPLAYLIST_ISIDENTICAL (DISPID_WMPPLAYLIST_BASE + 13) + +// IWMPCdrom +#define DISPID_WMPCDROM_BASE (DISPID_WMPPLAYLIST_BASE + DISPID_DELTA) +#define DISPID_WMPCDROM_DRIVESPECIFIER (DISPID_WMPCDROM_BASE + 1) +#define DISPID_WMPCDROM_PLAYLIST (DISPID_WMPCDROM_BASE + 2) +#define DISPID_WMPCDROM_EJECT (DISPID_WMPCDROM_BASE + 3) + +// IWMPCdromCollection +#define DISPID_WMPCDROMCOLLECTION_BASE (DISPID_WMPCDROM_BASE + DISPID_DELTA) +#define DISPID_WMPCDROMCOLLECTION_COUNT (DISPID_WMPCDROMCOLLECTION_BASE + 1) +#define DISPID_WMPCDROMCOLLECTION_ITEM (DISPID_WMPCDROMCOLLECTION_BASE + 2) +#define DISPID_WMPCDROMCOLLECTION_GETBYDRIVESPECIFIER (DISPID_WMPCDROMCOLLECTION_BASE + 3) +#define DISPID_WMPCDROMCOLLECTION_STARTMONITORINGCDROMS (DISPID_WMPCDROMCOLLECTION_BASE + 4) +#define DISPID_WMPCDROMCOLLECTION_STOPMONITORINGCDROMS (DISPID_WMPCDROMCOLLECTION_BASE + 5) + +// IWMPStringCollection +#define DISPID_WMPSTRINGCOLLECTION_BASE (DISPID_WMPCDROMCOLLECTION_BASE + DISPID_DELTA + DISPID_DELTA) +#define DISPID_WMPSTRINGCOLLECTION_COUNT (DISPID_WMPSTRINGCOLLECTION_BASE + 1) +#define DISPID_WMPSTRINGCOLLECTION_ITEM (DISPID_WMPSTRINGCOLLECTION_BASE + 2) + +// IWMPMediaCollection +#define DISPID_WMPMEDIACOLLECTION_BASE (DISPID_WMPSTRINGCOLLECTION_BASE + DISPID_DELTA) +#define DISPID_WMPMEDIACOLLECTION_ADD (DISPID_WMPMEDIACOLLECTION_BASE + 2) +#define DISPID_WMPMEDIACOLLECTION_GETALL (DISPID_WMPMEDIACOLLECTION_BASE + 3) +#define DISPID_WMPMEDIACOLLECTION_GETBYNAME (DISPID_WMPMEDIACOLLECTION_BASE + 4) +#define DISPID_WMPMEDIACOLLECTION_GETBYGENRE (DISPID_WMPMEDIACOLLECTION_BASE + 5) +#define DISPID_WMPMEDIACOLLECTION_GETBYAUTHOR (DISPID_WMPMEDIACOLLECTION_BASE + 6) +#define DISPID_WMPMEDIACOLLECTION_GETBYALBUM (DISPID_WMPMEDIACOLLECTION_BASE + 7) +#define DISPID_WMPMEDIACOLLECTION_GETBYATTRIBUTE (DISPID_WMPMEDIACOLLECTION_BASE + 8) +#define DISPID_WMPMEDIACOLLECTION_REMOVE (DISPID_WMPMEDIACOLLECTION_BASE + 9) +#define DISPID_WMPMEDIACOLLECTION_GETATTRIBUTESTRINGCOLLECTION (DISPID_WMPMEDIACOLLECTION_BASE + 11) +#define DISPID_WMPMEDIACOLLECTION_NEWQUERY (DISPID_WMPMEDIACOLLECTION_BASE + 12) +#define DISPID_WMPMEDIACOLLECTION_STARTMONITORING (DISPID_WMPMEDIACOLLECTION_BASE + 13) +#define DISPID_WMPMEDIACOLLECTION_STOPMONITORING (DISPID_WMPMEDIACOLLECTION_BASE + 14) +#define DISPID_WMPMEDIACOLLECTION_STARTCONTENTSCAN (DISPID_WMPMEDIACOLLECTION_BASE + 15) +#define DISPID_WMPMEDIACOLLECTION_STOPCONTENTSCAN (DISPID_WMPMEDIACOLLECTION_BASE + 16) +#define DISPID_WMPMEDIACOLLECTION_STARTSEARCH (DISPID_WMPMEDIACOLLECTION_BASE + 17) +#define DISPID_WMPMEDIACOLLECTION_STOPSEARCH (DISPID_WMPMEDIACOLLECTION_BASE + 18) +#define DISPID_WMPMEDIACOLLECTION_UPDATEMETADATA (DISPID_WMPMEDIACOLLECTION_BASE + 19) +#define DISPID_WMPMEDIACOLLECTION_GETMEDIAATOM (DISPID_WMPMEDIACOLLECTION_BASE + 20) +#define DISPID_WMPMEDIACOLLECTION_SETDELETED (DISPID_WMPMEDIACOLLECTION_BASE + 21) +#define DISPID_WMPMEDIACOLLECTION_ISDELETED (DISPID_WMPMEDIACOLLECTION_BASE + 22) +#define DISPID_WMPMEDIACOLLECTION_GETBYQUERYDESCRIPTION (DISPID_WMPMEDIACOLLECTION_BASE + 23) +#define DISPID_WMPMEDIACOLLECTION_FREEZECOLLECTIONCHANGE (DISPID_WMPMEDIACOLLECTION_BASE + 24) +#define DISPID_WMPMEDIACOLLECTION_UNFREEZECOLLECTIONCHANGE (DISPID_WMPMEDIACOLLECTION_BASE + 25) +#define DISPID_WMPMEDIACOLLECTION_POSTCOLLECTIONCHANGE (DISPID_WMPMEDIACOLLECTION_BASE + 26) + +// IWMPPlaylistCollection +#define DISPID_WMPPLAYLISTARRAY_BASE (DISPID_WMPMEDIACOLLECTION_BASE + DISPID_DELTA) +#define DISPID_WMPPLAYLISTARRAY_COUNT (DISPID_WMPPLAYLISTARRAY_BASE + 1) +#define DISPID_WMPPLAYLISTARRAY_ITEM (DISPID_WMPPLAYLISTARRAY_BASE + 2) + +// IWMPPlaylistCollection +#define DISPID_WMPPLAYLISTCOLLECTION_BASE (DISPID_WMPPLAYLISTARRAY_BASE + DISPID_DELTA) +#define DISPID_WMPPLAYLISTCOLLECTION_NEWPLAYLIST (DISPID_WMPPLAYLISTCOLLECTION_BASE + 2) +#define DISPID_WMPPLAYLISTCOLLECTION_GETALL (DISPID_WMPPLAYLISTCOLLECTION_BASE + 3) +#define DISPID_WMPPLAYLISTCOLLECTION_GETBYNAME (DISPID_WMPPLAYLISTCOLLECTION_BASE + 4) +#define DISPID_WMPPLAYLISTCOLLECTION_GETBYQUERYDESCRIPTION (DISPID_WMPPLAYLISTCOLLECTION_BASE + 5) +#define DISPID_WMPPLAYLISTCOLLECTION_REMOVE (DISPID_WMPPLAYLISTCOLLECTION_BASE + 6) +#define DISPID_WMPPLAYLISTCOLLECTION_NEWQUERY (DISPID_WMPPLAYLISTCOLLECTION_BASE + 7) +#define DISPID_WMPPLAYLISTCOLLECTION_STARTMONITORING (DISPID_WMPPLAYLISTCOLLECTION_BASE + 8) +#define DISPID_WMPPLAYLISTCOLLECTION_STOPMONITORING (DISPID_WMPPLAYLISTCOLLECTION_BASE + 9) +#define DISPID_WMPPLAYLISTCOLLECTION_SETDELETED (DISPID_WMPPLAYLISTCOLLECTION_BASE + 10) +#define DISPID_WMPPLAYLISTCOLLECTION_ISDELETED (DISPID_WMPPLAYLISTCOLLECTION_BASE + 11) +#define DISPID_WMPPLAYLISTCOLLECTION_IMPORTPLAYLIST (DISPID_WMPPLAYLISTCOLLECTION_BASE + 12) + +// IWMPMedia +#define DISPID_WMPMEDIA_BASE (DISPID_WMPPLAYLISTCOLLECTION_BASE + (4 * DISPID_DELTA)) +#define DISPID_WMPMEDIA_SOURCEURL (DISPID_WMPMEDIA_BASE + 1) +#define DISPID_WMPMEDIA_IMAGESOURCEWIDTH (DISPID_WMPMEDIA_BASE + 2) +#define DISPID_WMPMEDIA_IMAGESOURCEHEIGHT (DISPID_WMPMEDIA_BASE + 3) +#define DISPID_WMPMEDIA_MARKERCOUNT (DISPID_WMPMEDIA_BASE + 4) +#define DISPID_WMPMEDIA_GETMARKERTIME (DISPID_WMPMEDIA_BASE + 5) +#define DISPID_WMPMEDIA_GETMARKERNAME (DISPID_WMPMEDIA_BASE + 6) +#define DISPID_WMPMEDIA_DURATION (DISPID_WMPMEDIA_BASE + 7) +#define DISPID_WMPMEDIA_DURATIONSTRING (DISPID_WMPMEDIA_BASE + 8) +#define DISPID_WMPMEDIA_ATTRIBUTECOUNT (DISPID_WMPMEDIA_BASE + 9) +#define DISPID_WMPMEDIA_GETATTRIBUTENAME (DISPID_WMPMEDIA_BASE + 10) +#define DISPID_WMPMEDIA_GETITEMINFO (DISPID_WMPMEDIA_BASE + 11) +#define DISPID_WMPMEDIA_SETITEMINFO (DISPID_WMPMEDIA_BASE + 12) +#define DISPID_WMPMEDIA_ISIDENTICAL (DISPID_WMPMEDIA_BASE + 13) +#define DISPID_WMPMEDIA_NAME (DISPID_WMPMEDIA_BASE + 14) +#define DISPID_WMPMEDIA_GETITEMINFOBYATOM (DISPID_WMPMEDIA_BASE + 15) +#define DISPID_WMPMEDIA_ISMEMBEROF (DISPID_WMPMEDIA_BASE + 16) +#define DISPID_WMPMEDIA_ISREADONLYITEM (DISPID_WMPMEDIA_BASE + 17) +#define DISPID_WMPMEDIA2_ERROR (DISPID_WMPMEDIA_BASE + 18) +#define DISPID_WMPMEDIA3_GETATTRIBUTECOUNTBYTYPE (DISPID_WMPMEDIA_BASE + 19) +#define DISPID_WMPMEDIA3_GETITEMINFOBYTYPE (DISPID_WMPMEDIA_BASE + 20) + +// IWMPNetwork +#define DISPID_WMPNETWORK_BASE (DISPID_WMPMEDIA_BASE + DISPID_DELTA) +#define DISPID_WMPNETWORK_BANDWIDTH (DISPID_WMPNETWORK_BASE + 1) +#define DISPID_WMPNETWORK_RECOVEREDPACKETS (DISPID_WMPNETWORK_BASE + 2) +#define DISPID_WMPNETWORK_SOURCEPROTOCOL (DISPID_WMPNETWORK_BASE + 3) +#define DISPID_WMPNETWORK_RECEIVEDPACKETS (DISPID_WMPNETWORK_BASE + 4) +#define DISPID_WMPNETWORK_LOSTPACKETS (DISPID_WMPNETWORK_BASE + 5) +#define DISPID_WMPNETWORK_RECEPTIONQUALITY (DISPID_WMPNETWORK_BASE + 6) +#define DISPID_WMPNETWORK_BUFFERINGCOUNT (DISPID_WMPNETWORK_BASE + 7) +#define DISPID_WMPNETWORK_BUFFERINGPROGRESS (DISPID_WMPNETWORK_BASE + 8) +#define DISPID_WMPNETWORK_BUFFERINGTIME (DISPID_WMPNETWORK_BASE + 9) +#define DISPID_WMPNETWORK_FRAMERATE (DISPID_WMPNETWORK_BASE + 10) +#define DISPID_WMPNETWORK_MAXBITRATE (DISPID_WMPNETWORK_BASE + 11) +#define DISPID_WMPNETWORK_BITRATE (DISPID_WMPNETWORK_BASE + 12) +#define DISPID_WMPNETWORK_GETPROXYSETTINGS (DISPID_WMPNETWORK_BASE + 13) +#define DISPID_WMPNETWORK_SETPROXYSETTINGS (DISPID_WMPNETWORK_BASE + 14) +#define DISPID_WMPNETWORK_GETPROXYNAME (DISPID_WMPNETWORK_BASE + 15) +#define DISPID_WMPNETWORK_SETPROXYNAME (DISPID_WMPNETWORK_BASE + 16) +#define DISPID_WMPNETWORK_GETPROXYPORT (DISPID_WMPNETWORK_BASE + 17) +#define DISPID_WMPNETWORK_SETPROXYPORT (DISPID_WMPNETWORK_BASE + 18) +#define DISPID_WMPNETWORK_GETPROXYEXCEPTIONLIST (DISPID_WMPNETWORK_BASE + 19) +#define DISPID_WMPNETWORK_SETPROXYEXCEPTIONLIST (DISPID_WMPNETWORK_BASE + 20) +#define DISPID_WMPNETWORK_GETPROXYBYPASSFORLOCAL (DISPID_WMPNETWORK_BASE + 21) +#define DISPID_WMPNETWORK_SETPROXYBYPASSFORLOCAL (DISPID_WMPNETWORK_BASE + 22) +#define DISPID_WMPNETWORK_MAXBANDWIDTH (DISPID_WMPNETWORK_BASE + 23) +#define DISPID_WMPNETWORK_DOWNLOADPROGRESS (DISPID_WMPNETWORK_BASE + 24) +#define DISPID_WMPNETWORK_ENCODEDFRAMERATE (DISPID_WMPNETWORK_BASE + 25) +#define DISPID_WMPNETWORK_FRAMESSKIPPED (DISPID_WMPNETWORK_BASE + 26) + +// IWMPError +#define DISPID_WMPERROR_BASE (DISPID_WMPNETWORK_BASE + DISPID_DELTA) +#define DISPID_WMPERROR_CLEARERRORQUEUE (DISPID_WMPERROR_BASE + 1) +#define DISPID_WMPERROR_ERRORCOUNT (DISPID_WMPERROR_BASE + 2) +#define DISPID_WMPERROR_ITEM (DISPID_WMPERROR_BASE + 3) +#define DISPID_WMPERROR_WEBHELP (DISPID_WMPERROR_BASE + 4) + +// IWMPErrorItem +#define DISPID_WMPERRORITEM_BASE (DISPID_WMPERROR_BASE + DISPID_DELTA) +#define DISPID_WMPERRORITEM_ERRORCODE (DISPID_WMPERRORITEM_BASE + 1) +#define DISPID_WMPERRORITEM_ERRORDESCRIPTION (DISPID_WMPERRORITEM_BASE + 2) +#define DISPID_WMPERRORITEM_ERRORCONTEXT (DISPID_WMPERRORITEM_BASE + 3) +#define DISPID_WMPERRORITEM_REMEDY (DISPID_WMPERRORITEM_BASE + 4) +#define DISPID_WMPERRORITEM_CUSTOMURL (DISPID_WMPERRORITEM_BASE + 5) +#define DISPID_WMPERRORITEM2_CONDITION (DISPID_WMPERRORITEM_BASE + 6) + +// IWMPClosedCaption +#define DISPID_WMPCLOSEDCAPTION_BASE (DISPID_WMPERRORITEM_BASE + DISPID_DELTA) +#define DISPID_WMPCLOSEDCAPTION_SAMISTYLE (DISPID_WMPCLOSEDCAPTION_BASE + 1) +#define DISPID_WMPCLOSEDCAPTION_SAMILANG (DISPID_WMPCLOSEDCAPTION_BASE + 2) +#define DISPID_WMPCLOSEDCAPTION_SAMIFILENAME (DISPID_WMPCLOSEDCAPTION_BASE + 3) +#define DISPID_WMPCLOSEDCAPTION_CAPTIONINGID (DISPID_WMPCLOSEDCAPTION_BASE + 4) +#define DISPID_WMPCLOSEDCAPTION2_GETLANGCOUNT (DISPID_WMPCLOSEDCAPTION_BASE + 5) +#define DISPID_WMPCLOSEDCAPTION2_GETLANGNAME (DISPID_WMPCLOSEDCAPTION_BASE + 6) +#define DISPID_WMPCLOSEDCAPTION2_GETLANGID (DISPID_WMPCLOSEDCAPTION_BASE + 7) +#define DISPID_WMPCLOSEDCAPTION2_GETSTYLECOUNT (DISPID_WMPCLOSEDCAPTION_BASE + 8) +#define DISPID_WMPCLOSEDCAPTION2_GETSTYLENAME (DISPID_WMPCLOSEDCAPTION_BASE + 9) + +// IWMPDVD +#define DISPID_WMPDVD_BASE (DISPID_WMPCLOSEDCAPTION_BASE + DISPID_DELTA) +#define DISPID_WMPDVD_ISAVAILABLE (DISPID_WMPDVD_BASE + 1) +#define DISPID_WMPDVD_DOMAIN (DISPID_WMPDVD_BASE + 2) +#define DISPID_WMPDVD_TOPMENU (DISPID_WMPDVD_BASE + 3) +#define DISPID_WMPDVD_TITLEMENU (DISPID_WMPDVD_BASE + 4) +#define DISPID_WMPDVD_BACK (DISPID_WMPDVD_BASE + 5) +#define DISPID_WMPDVD_RESUME (DISPID_WMPDVD_BASE + 6) + +// IWMPMetadata* interfaces +#define DISPID_WMPMETADATA_BASE (DISPID_WMPDVD_BASE + DISPID_DELTA) +#define DISPID_WMPMETADATA_PICTURE_MIMETYPE (DISPID_WMPMETADATA_BASE + 1) +#define DISPID_WMPMETADATA_PICTURE_PICTURETYPE (DISPID_WMPMETADATA_BASE + 2) +#define DISPID_WMPMETADATA_PICTURE_DESCRIPTION (DISPID_WMPMETADATA_BASE + 3) +#define DISPID_WMPMETADATA_PICTURE_URL (DISPID_WMPMETADATA_BASE + 4) +#define DISPID_WMPMETADATA_TEXT_TEXT (DISPID_WMPMETADATA_BASE + 5) +#define DISPID_WMPMETADATA_TEXT_DESCRIPTION (DISPID_WMPMETADATA_BASE + 6) + +// IWMPPlayerApplication +#define DISPID_WMPPLAYERAPP_BASE (DISPID_WMPMETADATA_BASE + DISPID_DELTA) +#define DISPID_WMPPLAYERAPP_SWITCHTOPLAYERAPPLICATION (DISPID_WMPPLAYERAPP_BASE + 1) +#define DISPID_WMPPLAYERAPP_SWITCHTOCONTROL (DISPID_WMPPLAYERAPP_BASE + 2) +#define DISPID_WMPPLAYERAPP_PLAYERDOCKED (DISPID_WMPPLAYERAPP_BASE + 3) +#define DISPID_WMPPLAYERAPP_HASDISPLAY (DISPID_WMPPLAYERAPP_BASE + 4) +#define DISPID_WMPPLAYERAPP_REMOTESTATUS (DISPID_WMPPLAYERAPP_BASE + 5) + +// IWMPDownloadManager +#define DISPID_WMPDOWNLOADMANAGER_BASE (DISPID_WMPPLAYERAPP_BASE + DISPID_DELTA) +#define DISPID_WMPDOWNLOADMANAGER_GETDOWNLOADCOLLECTION (DISPID_WMPDOWNLOADMANAGER_BASE + 1) +#define DISPID_WMPDOWNLOADMANAGER_CREATEDOWNLOADCOLLECTION (DISPID_WMPDOWNLOADMANAGER_BASE + 2) + +// IWMPDownloadCollection +#define DISPID_WMPDOWNLOADCOLLECTION_BASE (DISPID_WMPDOWNLOADMANAGER_BASE + DISPID_DELTA) +#define DISPID_WMPDOWNLOADCOLLECTION_ID (DISPID_WMPDOWNLOADCOLLECTION_BASE + 1) +#define DISPID_WMPDOWNLOADCOLLECTION_COUNT (DISPID_WMPDOWNLOADCOLLECTION_BASE + 2) +#define DISPID_WMPDOWNLOADCOLLECTION_ITEM (DISPID_WMPDOWNLOADCOLLECTION_BASE + 3) +#define DISPID_WMPDOWNLOADCOLLECTION_STARTDOWNLOAD (DISPID_WMPDOWNLOADCOLLECTION_BASE + 4) +#define DISPID_WMPDOWNLOADCOLLECTION_REMOVEITEM (DISPID_WMPDOWNLOADCOLLECTION_BASE + 5) +#define DISPID_WMPDOWNLOADCOLLECTION_CLEAR (DISPID_WMPDOWNLOADCOLLECTION_BASE + 6) + +// IWMPDownloadItem +#define DISPID_WMPDOWNLOADITEM_BASE (DISPID_WMPDOWNLOADCOLLECTION_BASE + DISPID_DELTA) +#define DISPID_WMPDOWNLOADITEM_SOURCEURL (DISPID_WMPDOWNLOADITEM_BASE + 1) +#define DISPID_WMPDOWNLOADITEM_SIZE (DISPID_WMPDOWNLOADITEM_BASE + 2) +#define DISPID_WMPDOWNLOADITEM_TYPE (DISPID_WMPDOWNLOADITEM_BASE + 3) +#define DISPID_WMPDOWNLOADITEM_PROGRESS (DISPID_WMPDOWNLOADITEM_BASE + 4) +#define DISPID_WMPDOWNLOADITEM_DOWNLOADSTATE (DISPID_WMPDOWNLOADITEM_BASE + 5) +#define DISPID_WMPDOWNLOADITEM_PAUSE (DISPID_WMPDOWNLOADITEM_BASE + 6) +#define DISPID_WMPDOWNLOADITEM_RESUME (DISPID_WMPDOWNLOADITEM_BASE + 7) +#define DISPID_WMPDOWNLOADITEM_CANCEL (DISPID_WMPDOWNLOADITEM_BASE + 8) + +// IWMPDownloadItem2 +#define DISPID_WMPDOWNLOADITEM2_BASE (DISPID_WMPDOWNLOADITEM_BASE + DISPID_DELTA) +#define DISPID_WMPDOWNLOADITEM2_GETITEMINFO (DISPID_WMPDOWNLOADITEM2_BASE + 1) + +///////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////// +#define DISPID_WMPCORE_MIN 1 +#define DISPID_WMPCORE_MAX DISPID_WMPDOWNLOADITEM2_GETITEMINFO + + +// DIID_WMPCoreEvents +#define WMPCOREEVENT_BASE 5000 +#define DISPID_WMPCOREEVENT_OPENSTATECHANGE (WMPCOREEVENT_BASE + 1) +#define DISPID_WMPCOREEVENT_STATUSCHANGE (WMPCOREEVENT_BASE + 2) + + +#define WMPCOREEVENT_CONTROL_BASE 5100 +#define DISPID_WMPCOREEVENT_PLAYSTATECHANGE (WMPCOREEVENT_CONTROL_BASE + 1) +#define DISPID_WMPCOREEVENT_AUDIOLANGUAGECHANGE (WMPCOREEVENT_CONTROL_BASE + 2) + +#define WMPCOREEVENT_SEEK_BASE 5200 +#define DISPID_WMPCOREEVENT_ENDOFSTREAM (WMPCOREEVENT_SEEK_BASE + 1) +#define DISPID_WMPCOREEVENT_POSITIONCHANGE (WMPCOREEVENT_SEEK_BASE + 2) +#define DISPID_WMPCOREEVENT_MARKERHIT (WMPCOREEVENT_SEEK_BASE + 3) +#define DISPID_WMPCOREEVENT_DURATIONUNITCHANGE (WMPCOREEVENT_SEEK_BASE + 4) + +#define WMPCOREEVENT_CONTENT_BASE 5300 +#define DISPID_WMPCOREEVENT_SCRIPTCOMMAND (WMPCOREEVENT_CONTENT_BASE + 1) + +#define WMPCOREEVENT_NETWORK_BASE 5400 +#define DISPID_WMPCOREEVENT_DISCONNECT (WMPCOREEVENT_NETWORK_BASE + 1) +#define DISPID_WMPCOREEVENT_BUFFERING (WMPCOREEVENT_NETWORK_BASE + 2) +#define DISPID_WMPCOREEVENT_NEWSTREAM (WMPCOREEVENT_NETWORK_BASE + 3) + +#define WMPCOREEVENT_ERROR_BASE 5500 +#define DISPID_WMPCOREEVENT_ERROR (WMPCOREEVENT_ERROR_BASE + 1) + +#define WMPCOREEVENT_WARNING_BASE 5600 +#define DISPID_WMPCOREEVENT_WARNING (WMPCOREEVENT_WARNING_BASE + 1) + +#define WMPCOREEVENT_CDROM_BASE 5700 +#define DISPID_WMPCOREEVENT_CDROMMEDIACHANGE (WMPCOREEVENT_CDROM_BASE + 1) + +#define WMPCOREEVENT_PLAYLIST_BASE 5800 +#define DISPID_WMPCOREEVENT_PLAYLISTCHANGE (WMPCOREEVENT_PLAYLIST_BASE + 1) +#define DISPID_WMPCOREEVENT_MEDIACHANGE (WMPCOREEVENT_PLAYLIST_BASE + 2) +#define DISPID_WMPCOREEVENT_CURRENTMEDIAITEMAVAILABLE (WMPCOREEVENT_PLAYLIST_BASE + 3) +#define DISPID_WMPCOREEVENT_CURRENTPLAYLISTCHANGE (WMPCOREEVENT_PLAYLIST_BASE + 4) +#define DISPID_WMPCOREEVENT_CURRENTPLAYLISTITEMAVAILABLE (WMPCOREEVENT_PLAYLIST_BASE + 5) +#define DISPID_WMPCOREEVENT_CURRENTITEMCHANGE (WMPCOREEVENT_PLAYLIST_BASE + 6) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONCHANGE (WMPCOREEVENT_PLAYLIST_BASE + 7) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONATTRIBUTESTRINGADDED (WMPCOREEVENT_PLAYLIST_BASE + 8) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONATTRIBUTESTRINGREMOVED (WMPCOREEVENT_PLAYLIST_BASE + 9) +#define DISPID_WMPCOREEVENT_PLAYLISTCOLLECTIONCHANGE (WMPCOREEVENT_PLAYLIST_BASE + 10) +#define DISPID_WMPCOREEVENT_PLAYLISTCOLLECTIONPLAYLISTADDED (WMPCOREEVENT_PLAYLIST_BASE + 11) +#define DISPID_WMPCOREEVENT_PLAYLISTCOLLECTIONPLAYLISTREMOVED (WMPCOREEVENT_PLAYLIST_BASE + 12) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONCONTENTSCANADDEDITEM (WMPCOREEVENT_PLAYLIST_BASE + 13) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONCONTENTSCANPROGRESS (WMPCOREEVENT_PLAYLIST_BASE + 14) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONSEARCHFOUNDITEM (WMPCOREEVENT_PLAYLIST_BASE + 15) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONSEARCHPROGRESS (WMPCOREEVENT_PLAYLIST_BASE + 16) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONSEARCHCOMPLETE (WMPCOREEVENT_PLAYLIST_BASE + 17) +#define DISPID_WMPCOREEVENT_PLAYLISTCOLLECTIONPLAYLISTSETASDELETED (WMPCOREEVENT_PLAYLIST_BASE + 18) +#define DISPID_WMPCOREEVENT_MODECHANGE (WMPCOREEVENT_PLAYLIST_BASE + 19) +#define DISPID_WMPCOREEVENT_MEDIACOLLECTIONATTRIBUTESTRINGCHANGED (WMPCOREEVENT_PLAYLIST_BASE + 20) +#define DISPID_WMPCOREEVENT_MEDIAERROR (WMPCOREEVENT_PLAYLIST_BASE + 21) +#define DISPID_WMPCOREEVENT_DOMAINCHANGE (WMPCOREEVENT_PLAYLIST_BASE + 22) +#define DISPID_WMPCOREEVENT_OPENPLAYLISTSWITCH (WMPCOREEVENT_PLAYLIST_BASE + 23) + + + +// DIID_WMPOCXEvents +// These are the events that will be fired from OCX itself +#define WMPOCXEVENT_BASE 6500 +#define DISPID_WMPOCXEVENT_SWITCHEDTOPLAYERAPPLICATION (WMPOCXEVENT_BASE + 1) +#define DISPID_WMPOCXEVENT_SWITCHEDTOCONTROL (WMPOCXEVENT_BASE + 2) +#define DISPID_WMPOCXEVENT_PLAYERDOCKEDSTATECHANGE (WMPOCXEVENT_BASE + 3) +#define DISPID_WMPOCXEVENT_PLAYERRECONNECT (WMPOCXEVENT_BASE + 4) +#define DISPID_WMPOCXEVENT_CLICK (WMPOCXEVENT_BASE + 5) +#define DISPID_WMPOCXEVENT_DOUBLECLICK (WMPOCXEVENT_BASE + 6) +#define DISPID_WMPOCXEVENT_KEYDOWN (WMPOCXEVENT_BASE + 7) +#define DISPID_WMPOCXEVENT_KEYPRESS (WMPOCXEVENT_BASE + 8) +#define DISPID_WMPOCXEVENT_KEYUP (WMPOCXEVENT_BASE + 9) +#define DISPID_WMPOCXEVENT_MOUSEDOWN (WMPOCXEVENT_BASE + 10) +#define DISPID_WMPOCXEVENT_MOUSEMOVE (WMPOCXEVENT_BASE + 11) +#define DISPID_WMPOCXEVENT_MOUSEUP (WMPOCXEVENT_BASE + 12) +#define DISPID_WMPOCXEVENT_DEVICECONNECT (WMPOCXEVENT_BASE + 13) +#define DISPID_WMPOCXEVENT_DEVICEDISCONNECT (WMPOCXEVENT_BASE + 14) +#define DISPID_WMPOCXEVENT_DEVICESTATUSCHANGE (WMPOCXEVENT_BASE + 15) +#define DISPID_WMPOCXEVENT_DEVICESYNCSTATECHANGE (WMPOCXEVENT_BASE + 16) +#define DISPID_WMPOCXEVENT_DEVICESYNCERROR (WMPOCXEVENT_BASE + 17) +#define DISPID_WMPOCXEVENT_CREATEPARTNERSHIPCOMPLETE (WMPOCXEVENT_BASE + 18)
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 219 ++++++++++++++++++++++++++++++++++++++++++++++++- dlls/wmp/wmp_private.h | 2 + 2 files changed, 219 insertions(+), 2 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 430f701539..c15a79e2d0 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -24,6 +24,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmp);
static void update_state(WindowsMediaPlayer *wmp, int state);
+static inline WindowsMediaPlayer *impl_from_IWMPMedia(IWMPMedia *iface) +{ + return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPMedia_iface); +} + static inline WindowsMediaPlayer *impl_from_IWMPPlayer4(IWMPPlayer4 *iface) { return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPPlayer4_iface); @@ -145,8 +150,10 @@ static HRESULT WINAPI WMPPlayer4_get_settings(IWMPPlayer4 *iface, IWMPSettings * static HRESULT WINAPI WMPPlayer4_get_currentMedia(IWMPPlayer4 *iface, IWMPMedia **ppMedia) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%p)\n", This, ppMedia); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, ppMedia); + IWMPMedia_AddRef(&This->IWMPMedia_iface); + *ppMedia = &This->IWMPMedia_iface; + return S_OK; }
static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia *pMedia) @@ -865,10 +872,218 @@ static const IWMPControlsVtbl WMPControlsVtbl = { WMPControls_playItem, };
+HRESULT WINAPI WMPMedia_get_isIdentical(IWMPMedia *iface, IWMPMedia *other, VARIANT_BOOL *pvBool) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p, %p)\n", This, other, pvBool); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_get_sourceURL(IWMPMedia *iface, BSTR *pbstrName) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pbstrName); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_get_name(IWMPMedia *iface, BSTR *pbstrName) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pbstrName); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_put_name(IWMPMedia *iface, BSTR pbstrName) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(pbstrName)); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_get_imageSourceWidth(IWMPMedia *iface, LONG *pWidth) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pWidth); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_get_imageSourceHeight(IWMPMedia *iface, LONG *pHeight) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pHeight); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_get_markerCount(IWMPMedia *iface, LONG* pMarkerCount) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pMarkerCount); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_getMarkerTime(IWMPMedia *iface, LONG MarkerNum, DOUBLE *pMarkerTime) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d, %p)\n", This, MarkerNum, pMarkerTime); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_getMarkerName(IWMPMedia *iface, LONG MarkerNum, BSTR *pbstrMarkerName) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d, %p)\n", This, MarkerNum, pbstrMarkerName); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_get_duration(IWMPMedia *iface, DOUBLE *pDuration) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pDuration); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_get_durationString(IWMPMedia *iface, BSTR *pbstrDuration) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pbstrDuration); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_get_attributeCount(IWMPMedia *iface, LONG *plCount) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, plCount); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_getAttributeName(IWMPMedia *iface, LONG lIndex, BSTR *pbstrItemName) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d, %p)\n", This, lIndex, pbstrItemName); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_getItemInfo(IWMPMedia *iface, BSTR bstrItemName, BSTR *pbstrVal) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrItemName), pbstrVal); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_setItemInfo(IWMPMedia *iface, BSTR bstrItemName, BSTR bstrVal) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s, %s)\n", This, debugstr_w(bstrItemName), debugstr_w(bstrVal)); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_getItemInfoByAtom(IWMPMedia *iface, LONG lAtom, BSTR *pbstrVal) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d, %p)\n", This, lAtom, pbstrVal); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_isMemberOf(IWMPMedia *iface, IWMPPlaylist *pPlaylist, VARIANT_BOOL *pvarfIsMemberOf) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p, %p)\n", This, pPlaylist, pvarfIsMemberOf); + return E_NOTIMPL; +} + +HRESULT WINAPI WMPMedia_isReadOnlyItem(IWMPMedia *iface, BSTR bstrItemName, VARIANT_BOOL *pvarfIsReadOnly) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrItemName), pvarfIsReadOnly); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_QueryInterface(IWMPMedia *iface, REFIID riid, void **ppv) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv); +} + +static ULONG WINAPI WMPMedia_AddRef(IWMPMedia *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + return IOleObject_AddRef(&This->IOleObject_iface); +} + +static ULONG WINAPI WMPMedia_Release(IWMPMedia *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + return IOleObject_Release(&This->IOleObject_iface); +} + +static HRESULT WINAPI WMPMedia_GetTypeInfoCount(IWMPMedia *iface, UINT *pctinfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_GetTypeInfo(IWMPMedia *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%u %d %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_GetIDsOfNames(IWMPMedia *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPMedia_Invoke(IWMPMedia *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); + FIXME("(%p)->(%d %s %d %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + + +static const IWMPMediaVtbl WMPMediaVtbl = { + WMPMedia_QueryInterface, + WMPMedia_AddRef, + WMPMedia_Release, + WMPMedia_GetTypeInfoCount, + WMPMedia_GetTypeInfo, + WMPMedia_GetIDsOfNames, + WMPMedia_Invoke, + WMPMedia_get_isIdentical, + WMPMedia_get_sourceURL, + WMPMedia_get_name, + WMPMedia_put_name, + WMPMedia_get_imageSourceWidth, + WMPMedia_get_imageSourceHeight, + WMPMedia_get_markerCount, + WMPMedia_getMarkerTime, + WMPMedia_getMarkerName, + WMPMedia_get_duration, + WMPMedia_get_durationString, + WMPMedia_get_attributeCount, + WMPMedia_getAttributeName, + WMPMedia_getItemInfo, + WMPMedia_setItemInfo, + WMPMedia_getItemInfoByAtom, + WMPMedia_isMemberOf, + WMPMedia_isReadOnlyItem +}; + HRESULT init_player(WindowsMediaPlayer *wmp) { wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl; wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl; wmp->IWMPControls_iface.lpVtbl = &WMPControlsVtbl; + wmp->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl; + return S_OK; } diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index b047143b3e..ca5002f5c4 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -43,6 +43,8 @@ struct WindowsMediaPlayer { IWMPPlayer4 IWMPPlayer4_iface; IWMPSettings IWMPSettings_iface; IWMPControls IWMPControls_iface; + //For now there is only one IWMPMedia at a time + IWMPMedia IWMPMedia_iface;
LONG ref;
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 300 ++++++++++++++++++++++++++++++++++++++++++++++++- dlls/wmp/wmp_private.h | 1 + 2 files changed, 298 insertions(+), 3 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index c15a79e2d0..69979be21d 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -24,6 +24,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmp);
static void update_state(WindowsMediaPlayer *wmp, int state);
+static inline WindowsMediaPlayer *impl_from_IWMPNetwork(IWMPNetwork *iface) +{ + return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPNetwork_iface); +} + static inline WindowsMediaPlayer *impl_from_IWMPMedia(IWMPMedia *iface) { return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPMedia_iface); @@ -201,8 +206,12 @@ static HRESULT WINAPI WMPPlayer4_launchURL(IWMPPlayer4 *iface, BSTR url) static HRESULT WINAPI WMPPlayer4_get_network(IWMPPlayer4 *iface, IWMPNetwork **ppQNI) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%p)\n", This, ppQNI); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, ppQNI); + + IWMPNetwork_AddRef(&This->IWMPNetwork_iface); + *ppQNI = &This->IWMPNetwork_iface; + return S_OK; }
static HRESULT WINAPI WMPPlayer4_get_currentPlaylist(IWMPPlayer4 *iface, IWMPPlaylist **ppPL) @@ -1049,7 +1058,6 @@ static HRESULT WINAPI WMPMedia_Invoke(IWMPMedia *iface, DISPID dispIdMember, return E_NOTIMPL; }
- static const IWMPMediaVtbl WMPMediaVtbl = { WMPMedia_QueryInterface, WMPMedia_AddRef, @@ -1078,12 +1086,298 @@ static const IWMPMediaVtbl WMPMediaVtbl = { WMPMedia_isReadOnlyItem };
+static HRESULT WINAPI WMPNetwork_QueryInterface(IWMPNetwork *iface, REFIID riid, void **ppv) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + return IOleObject_QueryInterface(&This->IOleObject_iface, riid, ppv); +} + +static ULONG WINAPI WMPNetwork_AddRef(IWMPNetwork *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + return IOleObject_AddRef(&This->IOleObject_iface); +} + +static ULONG WINAPI WMPNetwork_Release(IWMPNetwork *iface) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + return IOleObject_Release(&This->IOleObject_iface); +} + +static HRESULT WINAPI WMPNetwork_GetTypeInfoCount(IWMPNetwork *iface, UINT *pctinfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, pctinfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_GetTypeInfo(IWMPNetwork *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%u %d %p)\n", This, iTInfo, lcid, ppTInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_GetIDsOfNames(IWMPNetwork *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s %p %u %d %p)\n", This, debugstr_guid(riid), rgszNames, cNames, lcid, rgDispId); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_Invoke(IWMPNetwork *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, + EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%d %s %d %x %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid), lcid, + wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bandWidth(IWMPNetwork *iface, LONG *plBandwidth) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBandwidth); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_recoveredPackets(IWMPNetwork *iface, LONG *plRecoveredPackets) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plRecoveredPackets); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_sourceProtocol(IWMPNetwork *iface, BSTR *pbstrSourceProtocol) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, pbstrSourceProtocol); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_receivedPackets(IWMPNetwork *iface, LONG *plReceivedPackets) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plReceivedPackets); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_lostPackets(IWMPNetwork *iface, LONG *plLostPackets) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plLostPackets); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_receptionQuality(IWMPNetwork *iface, LONG *plReceptionQuality) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plReceptionQuality); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bufferingCount(IWMPNetwork *iface, LONG *plBufferingCount) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBufferingCount); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bufferingProgress(IWMPNetwork *iface, LONG *plBufferingProgress) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBufferingProgress); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bufferingTime(IWMPNetwork *iface, LONG *plBufferingTime) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBufferingTime); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_put_bufferingTime(IWMPNetwork *iface, LONG lBufferingTime) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%d)\n", This, lBufferingTime); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_frameRate(IWMPNetwork *iface, LONG *plFrameRate) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plFrameRate); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_maxBitRate(IWMPNetwork *iface, LONG *plBitRate) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBitRate); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_bitRate(IWMPNetwork *iface, LONG *plBitRate) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plBitRate); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxySettings(IWMPNetwork *iface, BSTR bstrProtocol, LONG *plProxySetting) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), plProxySetting); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxySettings(IWMPNetwork *iface, BSTR bstrProtocol, LONG lProxySetting) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %d)\n", This, debugstr_w(bstrProtocol), lProxySetting); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxyName(IWMPNetwork *iface, BSTR bstrProtocol, BSTR *pbstrProxyName) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), pbstrProxyName); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxyName(IWMPNetwork *iface, BSTR bstrProtocol, BSTR bstrProxyName) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %s)\n", This, debugstr_w(bstrProtocol), debugstr_w(bstrProxyName)); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxyPort(IWMPNetwork *iface, BSTR bstrProtocol, LONG *plProxyPort) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), plProxyPort); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxyPort(IWMPNetwork *iface, BSTR bstrProtocol, LONG lProxyPort) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %d)\n", This, debugstr_w(bstrProtocol), lProxyPort); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxyExceptionList(IWMPNetwork *iface, BSTR bstrProtocol, BSTR *pbstrExceptionList) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), pbstrExceptionList); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxyExceptionList(IWMPNetwork *iface, BSTR bstrProtocol, BSTR bstrExceptionList) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %s)\n", This, debugstr_w(bstrProtocol), debugstr_w(bstrExceptionList)); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_getProxyBypassForLocal(IWMPNetwork *iface, BSTR bstrProtocol, VARIANT_BOOL *pfBypassForLocal) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %p)\n", This, debugstr_w(bstrProtocol), pfBypassForLocal); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_setProxyBypassForLocal(IWMPNetwork *iface, BSTR bstrProtocol, VARIANT_BOOL fBypassForLocal) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%s, %d)\n", This, debugstr_w(bstrProtocol), fBypassForLocal); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_maxBandwidth(IWMPNetwork *iface, LONG *plMaxBandwidth) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plMaxBandwidth); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_put_maxBandwidth(IWMPNetwork *iface, LONG lMaxBandwidth) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%d)\n", This, lMaxBandwidth); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_downloadProgress(IWMPNetwork *iface, LONG *plDownloadProgress) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plDownloadProgress); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_encodedFrameRate(IWMPNetwork *iface, LONG *plFrameRate) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plFrameRate); + return E_NOTIMPL; +} + +static HRESULT WINAPI WMPNetwork_get_framesSkipped(IWMPNetwork *iface, LONG *plFrames) +{ + WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); + FIXME("(%p)->(%p)\n", This, plFrames); + return E_NOTIMPL; +} + +static const IWMPNetworkVtbl WMPNetworkVtbl = { + WMPNetwork_QueryInterface, + WMPNetwork_AddRef, + WMPNetwork_Release, + WMPNetwork_GetTypeInfoCount, + WMPNetwork_GetTypeInfo, + WMPNetwork_GetIDsOfNames, + WMPNetwork_Invoke, + WMPNetwork_get_bandWidth, + WMPNetwork_get_recoveredPackets, + WMPNetwork_get_sourceProtocol, + WMPNetwork_get_receivedPackets, + WMPNetwork_get_lostPackets, + WMPNetwork_get_receptionQuality, + WMPNetwork_get_bufferingCount, + WMPNetwork_get_bufferingProgress, + WMPNetwork_get_bufferingTime, + WMPNetwork_put_bufferingTime, + WMPNetwork_get_frameRate, + WMPNetwork_get_maxBitRate, + WMPNetwork_get_bitRate, + WMPNetwork_getProxySettings, + WMPNetwork_setProxySettings, + WMPNetwork_getProxyName, + WMPNetwork_setProxyName, + WMPNetwork_getProxyPort, + WMPNetwork_setProxyPort, + WMPNetwork_getProxyExceptionList, + WMPNetwork_setProxyExceptionList, + WMPNetwork_getProxyBypassForLocal, + WMPNetwork_setProxyBypassForLocal, + WMPNetwork_get_maxBandwidth, + WMPNetwork_put_maxBandwidth, + WMPNetwork_get_downloadProgress, + WMPNetwork_get_encodedFrameRate, + WMPNetwork_get_framesSkipped, +}; + HRESULT init_player(WindowsMediaPlayer *wmp) { wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl; wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl; wmp->IWMPControls_iface.lpVtbl = &WMPControlsVtbl; wmp->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl; + wmp->IWMPNetwork_iface.lpVtbl = &WMPNetworkVtbl;
return S_OK; } diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index ca5002f5c4..5b79fafa07 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -45,6 +45,7 @@ struct WindowsMediaPlayer { IWMPControls IWMPControls_iface; //For now there is only one IWMPMedia at a time IWMPMedia IWMPMedia_iface; + IWMPNetwork IWMPNetwork_iface;
LONG ref;
Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 328 +++++++++++++++++++++++++++++++++++++++++++------ dlls/wmp/wmp_private.h | 35 ++++++ 2 files changed, 325 insertions(+), 38 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 69979be21d..e12fed7d3a 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -17,12 +17,14 @@ */
#include "wmp_private.h" +#include "wmpids.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
-static void update_state(WindowsMediaPlayer *wmp, int state); +static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state); +static void media_change(WindowsMediaPlayer *wmp, LONG type, IDispatch *pItem);
static inline WindowsMediaPlayer *impl_from_IWMPNetwork(IWMPNetwork *iface) { @@ -44,6 +46,20 @@ static inline WindowsMediaPlayer *impl_from_IWMPControls(IWMPControls *iface) return CONTAINING_RECORD(iface, WindowsMediaPlayer, IWMPControls_iface); }
+HRESULT WINAPI WMPControls_play(IWMPControls *iface) +{ + HRESULT hres; + WindowsMediaPlayer *This = impl_from_IWMPControls(iface); + TRACE("(%p)\n", This); + hres = IMediaControl_Run(This->media_control); + if (SUCCEEDED(hres)) + { + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_PLAYING); + media_change(This, DISPID_WMPCOREEVENT_MEDIACHANGE, (IDispatch*)&This->IWMPMedia_iface); + } + return hres; +} + static HRESULT WINAPI WMPPlayer4_QueryInterface(IWMPPlayer4 *iface, REFIID riid, void **ppv) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); @@ -105,15 +121,49 @@ static HRESULT WINAPI WMPPlayer4_close(IWMPPlayer4 *iface) static HRESULT WINAPI WMPPlayer4_get_URL(IWMPPlayer4 *iface, BSTR *pbstrURL) { WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%p)\n", This, pbstrURL); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pbstrURL); + if (!pbstrURL) + return E_POINTER; + + *pbstrURL = This->url; + + return S_OK; }
static HRESULT WINAPI WMPPlayer4_put_URL(IWMPPlayer4 *iface, BSTR url) { + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(url)); - return E_NOTIMPL; + TRACE("(%p)->(%s)\n", This, debugstr_w(url)); + if (!url) + return E_POINTER; + if (This->url) { + heap_free(This->url); + } + This->url = heap_strdupW(url); + + if (!This->url) + return E_OUTOFMEMORY; + + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGING); + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); + media_change(This, DISPID_WMPCOREEVENT_CURRENTITEMCHANGE, (IDispatch*)&This->IWMPMedia_iface); + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_CHANGED); + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_PLAYLIST_OPEN_NO_MEDIA); + media_change(This, DISPID_WMPCOREEVENT_CURRENTITEMCHANGE, (IDispatch*)&This->IWMPMedia_iface); + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_OPENING_UNKNOWN_URL); + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); + media_change(This, DISPID_WMPCOREEVENT_CURRENTITEMCHANGE, (IDispatch*)&This->IWMPMedia_iface); + + hres = IGraphBuilder_RenderFile(This->pFilterGraph, url, NULL); + if (SUCCEEDED(hres)) { + update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_OPEN); + } + + if (SUCCEEDED(hres) && This->autoStart) + WMPControls_play((IWMPControls*)This); + + return hres; }
static HRESULT WINAPI WMPPlayer4_get_openState(IWMPPlayer4 *iface, WMPOpenState *pwmpos) @@ -504,15 +554,19 @@ static HRESULT WINAPI WMPSettings_get_isAvailable(IWMPSettings *iface, BSTR item static HRESULT WINAPI WMPSettings_get_autoStart(IWMPSettings *iface, VARIANT_BOOL *p) { WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + if (!p) + return E_POINTER; + *p = This->autoStart; + return S_OK; }
static HRESULT WINAPI WMPSettings_put_autoStart(IWMPSettings *iface, VARIANT_BOOL v) { WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); - FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + TRACE("(%p)->(%x)\n", This, v); + This->autoStart = v; + return S_OK; }
static HRESULT WINAPI WMPSettings_get_baseURL(IWMPSettings *iface, BSTR *p) @@ -546,15 +600,21 @@ static HRESULT WINAPI WMPSettings_put_defaultFrame(IWMPSettings *iface, BSTR v) static HRESULT WINAPI WMPSettings_get_invokeURLs(IWMPSettings *iface, VARIANT_BOOL *p) { WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); + // Leaving as FIXME as we don't currently use this FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + if (!p) + return E_POINTER; + *p = This->invokeURLs; + return S_OK; }
static HRESULT WINAPI WMPSettings_put_invokeURLs(IWMPSettings *iface, VARIANT_BOOL v) { WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); + // Leaving as FIXME as we don't currently use this FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + This->invokeURLs = v; + return S_OK; }
static HRESULT WINAPI WMPSettings_get_mute(IWMPSettings *iface, VARIANT_BOOL *p) @@ -615,16 +675,26 @@ static HRESULT WINAPI WMPSettings_put_balance(IWMPSettings *iface, LONG v)
static HRESULT WINAPI WMPSettings_get_volume(IWMPSettings *iface, LONG *p) { + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, p); + hres = IBasicAudio_get_Volume(This->basic_audio, p); + /* IBasicAudio - [-10000, 0], wmp - [0, 100] */ + if (SUCCEEDED(hres)) + *p = (*p + 10000) * 100 / 10000; + return hres; }
static HRESULT WINAPI WMPSettings_put_volume(IWMPSettings *iface, LONG v) { + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); - FIXME("(%p)->(%d)\n", This, v); - return E_NOTIMPL; + TRACE("(%p)->(%d)\n", This, v); + /* IBasicAudio - [-10000, 0], wmp - [0, 100] */ + v = 10000 * v / 100 - 10000; + hres = IBasicAudio_put_Volume(This->basic_audio, v); + TRACE("ret: %d", hres); + return hres; }
static HRESULT WINAPI WMPSettings_getMode(IWMPSettings *iface, BSTR mode, VARIANT_BOOL *p) @@ -644,15 +714,21 @@ static HRESULT WINAPI WMPSettings_setMode(IWMPSettings *iface, BSTR mode, VARIAN static HRESULT WINAPI WMPSettings_get_enableErrorDialogs(IWMPSettings *iface, VARIANT_BOOL *p) { WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); + // Leaving as FIXME as we don't currently use this FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + if (!p) + return E_POINTER; + *p = This->enableErrorDialogs; + return S_OK; }
static HRESULT WINAPI WMPSettings_put_enableErrorDialogs(IWMPSettings *iface, VARIANT_BOOL v) { WindowsMediaPlayer *This = impl_from_IWMPSettings(iface); + // Leaving as FIXME as we don't currently use this FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + This->enableErrorDialogs = v; + return S_OK; }
static const IWMPSettingsVtbl WMPSettingsVtbl = { @@ -689,9 +765,124 @@ static const IWMPSettingsVtbl WMPSettingsVtbl = { };
void destroy_player(WindowsMediaPlayer* wmp) { + /* shutdown event thread */ + if (wmp->event_thread) + { + SetEvent(wmp->stop_event); + WaitForSingleObject(wmp->event_thread, INFINITE); + CloseHandle(wmp->event_thread); + CloseHandle(wmp->stop_event); + } + + if (wmp->media_seeking) + IMediaSeeking_Release(wmp->media_seeking); + if (wmp->media_event) + IBasicAudio_Release(wmp->basic_audio); + if (wmp->media_event) + IMediaEvent_Release(wmp->media_event); + if (wmp->media_control) + IMediaControl_Release(wmp->media_control); + if (wmp->pFilterGraph) + IGraphBuilder_Release(wmp->pFilterGraph); + if (wmp->url) + heap_free(wmp->url); heap_free(wmp); }
+static void status_change(WindowsMediaPlayer *wmp) +{ + DISPPARAMS dispparams; + + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = NULL; + + call_sink(wmp->wmpocx, DISPID_WMPCOREEVENT_STATUSCHANGE, + &dispparams); +} + +static void media_change(WindowsMediaPlayer *wmp, LONG type, IDispatch *pItem) +{ + DISPPARAMS dispparams; + VARIANTARG params[1]; + + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = params; + + V_VT(params) = VT_DISPATCH; + V_DISPATCH(params) = pItem; + + call_sink(wmp->wmpocx, type, + &dispparams); + status_change(wmp); +} +static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state) +{ + DISPPARAMS dispparams; + VARIANTARG params[1]; + + dispparams.cArgs = 1; + dispparams.cNamedArgs = 0; + dispparams.rgdispidNamedArgs = NULL; + dispparams.rgvarg = params; + + V_VT(params) = VT_UI4; + V_UI4(params) = state; + + call_sink(wmp->wmpocx, type, + &dispparams); + status_change(wmp); +} + +static DWORD CALLBACK WMP_event_thread(LPVOID parm) +{ + WindowsMediaPlayer* wmp = (WindowsMediaPlayer *)parm; + HRESULT hr; + HANDLE handle[2]; + DWORD n = 0, ret = 0; + + handle[n++] = wmp->stop_event; + IMediaEvent_GetEventHandle(wmp->media_event, (OAEVENT *)&handle[n++]); + for (;;) { + DWORD r; + + r = WaitForMultipleObjects(n, handle, FALSE, INFINITE); + if (r == WAIT_OBJECT_0) { + TRACE("got stop event\n"); + break; + } + else if (r == WAIT_OBJECT_0+1) { + LONG event_code; + LONG_PTR p1, p2; + do { + hr = IMediaEvent_GetEvent(wmp->media_event, &event_code, &p1, &p2, 0); + if (SUCCEEDED(hr)) { + TRACE("got event_code = 0x%02x\n", event_code); + /* For now we only handle EC_COMPLETE */ + if (event_code == EC_COMPLETE) { + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_MEDIA_ENDED); + media_change(wmp, DISPID_WMPCOREEVENT_MEDIACHANGE, (IDispatch*)&wmp->IWMPMedia_iface); + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); + update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED); + } + + IMediaEvent_FreeEventParams(wmp->media_event, event_code, p1, p2); + } + } while (hr == S_OK); + } + else { + TRACE("Unknown error (%d)\n", (int)r); + break; + } + } + + return ret; +} + + HRESULT WINAPI WMPControls_fastForward(IWMPControls *iface) { WindowsMediaPlayer *This = impl_from_IWMPControls(iface); @@ -723,8 +914,14 @@ HRESULT WINAPI WMPControls_get_currentMarker(IWMPControls *iface, LONG *plMarker HRESULT WINAPI WMPControls_get_currentPosition(IWMPControls *iface, DOUBLE *pdCurrentPosition) { WindowsMediaPlayer *This = impl_from_IWMPControls(iface); - FIXME("(%p)->(%p)\n", This, pdCurrentPosition); - return E_NOTIMPL; + HRESULT hres; + LONGLONG currentPosition; + + TRACE("(%p)->(%p)\n", This, pdCurrentPosition); + hres = IMediaSeeking_GetCurrentPosition(This->media_seeking, ¤tPosition); + *pdCurrentPosition = (DOUBLE) currentPosition / 10000000.0f; + TRACE("hres: %d, pos: %f\n", hres, *pdCurrentPosition); + return hres; }
HRESULT WINAPI WMPControls_get_currentPositionString(IWMPControls *iface, BSTR *pbstrCurrentPosition) @@ -736,9 +933,22 @@ HRESULT WINAPI WMPControls_get_currentPositionString(IWMPControls *iface, BSTR *
static HRESULT WINAPI WMPControls_get_isAvailable(IWMPControls *iface, BSTR bstrItem, VARIANT_BOOL *pIsAvailable) { + HRESULT hres = E_NOTIMPL; WindowsMediaPlayer *This = impl_from_IWMPControls(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(bstrItem)); - return E_NOTIMPL; + static const WCHAR currentPosition[] = {'c','u','r','r','e','n','t','P','o','s','i','t','i','o','n',0}; + TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrItem), pIsAvailable); + if (strcmpW(currentPosition, bstrItem) == 0) { + DWORD capabilities; + hres = IMediaSeeking_GetCapabilities(This->media_seeking, &capabilities); + *pIsAvailable = (capabilities & AM_SEEKING_CanSeekAbsolute) ? + VARIANT_TRUE : VARIANT_FALSE; + } else { + FIXME("%s not implemented\n", debugstr_w(bstrItem)); + } + hres = S_OK; + *pIsAvailable = VARIANT_TRUE; + + return hres; }
HRESULT WINAPI WMPControls_next(IWMPControls *iface) @@ -755,13 +965,6 @@ HRESULT WINAPI WMPControls_pause(IWMPControls *iface) return E_NOTIMPL; }
-HRESULT WINAPI WMPControls_play(IWMPControls *iface) -{ - WindowsMediaPlayer *This = impl_from_IWMPControls(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; -} - HRESULT WINAPI WMPControls_playItem(IWMPControls *iface, IWMPMedia *pIWMPMedia) { WindowsMediaPlayer *This = impl_from_IWMPControls(iface); @@ -792,16 +995,27 @@ HRESULT WINAPI WMPControls_put_currentMarker(IWMPControls *iface, LONG lMarker)
HRESULT WINAPI WMPControls_put_currentPosition(IWMPControls *iface, DOUBLE dCurrentPosition) { + LONGLONG Current; + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPControls(iface); - FIXME("(%p)->(%f)\n", This, dCurrentPosition); - return E_NOTIMPL; + TRACE("(%p)->(%f)\n", This, dCurrentPosition); + Current = 10000000 * dCurrentPosition; + hres = IMediaSeeking_SetPositions(This->media_seeking, &Current, + AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning); + + return hres; }
HRESULT WINAPI WMPControls_stop(IWMPControls *iface) { + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPControls(iface); - FIXME("(%p)\n", This); - return E_NOTIMPL; + TRACE("(%p)\n", This); + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_TRANSITIONING); + hres = IMediaControl_Stop(This->media_control); + if (SUCCEEDED(hres)) + update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_STOPPED); + return hres; }
static HRESULT WINAPI WMPControls_QueryInterface(IWMPControls *iface, REFIID riid, void **ppv) @@ -946,9 +1160,15 @@ HRESULT WINAPI WMPMedia_getMarkerName(IWMPMedia *iface, LONG MarkerNum, BSTR *pb
HRESULT WINAPI WMPMedia_get_duration(IWMPMedia *iface, DOUBLE *pDuration) { + LONGLONG duration; + HRESULT hres; WindowsMediaPlayer *This = impl_from_IWMPMedia(iface); - FIXME("(%p)->(%p)\n", This, pDuration); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pDuration); + hres = IMediaSeeking_GetDuration(This->media_seeking, &duration); + if (SUCCEEDED(hres)) + *pDuration = (DOUBLE)duration / 10000000.0f; + TRACE("%d, %f, %lld\n", hres, *pDuration, duration); + return hres; }
HRESULT WINAPI WMPMedia_get_durationString(IWMPMedia *iface, BSTR *pbstrDuration) @@ -1189,8 +1409,9 @@ static HRESULT WINAPI WMPNetwork_get_bufferingCount(IWMPNetwork *iface, LONG *pl static HRESULT WINAPI WMPNetwork_get_bufferingProgress(IWMPNetwork *iface, LONG *plBufferingProgress) { WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); - FIXME("(%p)->(%p)\n", This, plBufferingProgress); - return E_NOTIMPL; + FIXME("stub, returning 100 (%p)->(%p)\n", This, plBufferingProgress); + *plBufferingProgress = 100; + return S_OK; }
static HRESULT WINAPI WMPNetwork_get_bufferingTime(IWMPNetwork *iface, LONG *plBufferingTime) @@ -1315,8 +1536,9 @@ static HRESULT WINAPI WMPNetwork_put_maxBandwidth(IWMPNetwork *iface, LONG lMaxB static HRESULT WINAPI WMPNetwork_get_downloadProgress(IWMPNetwork *iface, LONG *plDownloadProgress) { WindowsMediaPlayer *This = impl_from_IWMPNetwork(iface); - FIXME("(%p)->(%p)\n", This, plDownloadProgress); - return E_NOTIMPL; + FIXME("stub, returning 100 (%p)->(%p)\n", This, plDownloadProgress); + *plDownloadProgress = 100; + return S_OK; }
static HRESULT WINAPI WMPNetwork_get_encodedFrameRate(IWMPNetwork *iface, LONG *plFrameRate) @@ -1373,11 +1595,41 @@ static const IWMPNetworkVtbl WMPNetworkVtbl = {
HRESULT init_player(WindowsMediaPlayer *wmp) { + HRESULT hres; + wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl; wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl; wmp->IWMPControls_iface.lpVtbl = &WMPControlsVtbl; wmp->IWMPMedia_iface.lpVtbl = &WMPMediaVtbl; wmp->IWMPNetwork_iface.lpVtbl = &WMPNetworkVtbl;
+ wmp->invokeURLs = TRUE; + wmp->autoStart = TRUE; + + + hres = CoCreateInstance(&CLSID_FilterGraph, + NULL, + CLSCTX_INPROC_SERVER, + &IID_IGraphBuilder, + (void **)&wmp->pFilterGraph); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(wmp->pFilterGraph, &IID_IMediaControl, (void**)&wmp->media_control); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(wmp->pFilterGraph, &IID_IMediaEvent, (void**)&wmp->media_event); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(wmp->pFilterGraph, &IID_IBasicAudio, (void**)&wmp->basic_audio); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(wmp->pFilterGraph, &IID_IMediaSeeking, (void**)&wmp->media_seeking); + if (SUCCEEDED(hres)) + hres = IMediaSeeking_SetTimeFormat(wmp->media_seeking, &TIME_FORMAT_MEDIA_TIME); + if (SUCCEEDED(hres)) + { + wmp->stop_event = CreateEventW(NULL, FALSE, FALSE, NULL); + wmp->event_thread = CreateThread(NULL, 0, WMP_event_thread, wmp, 0, NULL); + } + if (!wmp->event_thread) { + TRACE("Can't create thread\n"); + return E_FAIL; + } return S_OK; } diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 5b79fafa07..6816c5893a 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -21,6 +21,8 @@ #include "windows.h" #include "ole2.h" #include "wmp.h" +#include "wine/unicode.h" +#include "dshow.h"
typedef struct { IConnectionPoint IConnectionPoint_iface; @@ -54,6 +56,23 @@ struct WindowsMediaPlayer { SIZEL extent;
ConnectionPoint *wmpocx; + + /* Settings */ + VARIANT_BOOL autoStart; + VARIANT_BOOL invokeURLs; + VARIANT_BOOL enableErrorDialogs; + BSTR url; + + /* DirectShow stuff */ + IGraphBuilder* pFilterGraph; + IMediaControl* media_control; + IMediaEvent* media_event; + IBasicAudio * basic_audio; + IMediaSeeking * media_seeking; + + /* Async event notification */ + HANDLE event_thread; + HANDLE stop_event; };
HRESULT init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN; @@ -83,3 +102,19 @@ static inline BOOL heap_free(void *mem) { return HeapFree(GetProcessHeap(), 0, mem); } + +static inline WCHAR *heap_strdupW(const WCHAR *str) +{ + WCHAR *ret; + + if(str) { + size_t size = strlenW(str)+1; + ret = heap_alloc(size*sizeof(WCHAR)); + if(ret) + memcpy(ret, str, size*sizeof(WCHAR)); + }else { + ret = NULL; + } + + return ret; +}