v2 Switches to global HeapAlloc wrappers, moves wmpids.h to include/ and changes C++ comments to C ones. 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 | 1004 ++++++++++++++++++++++++++++++++++++++++++++++- dlls/wmp/tests/oleobj.c | 2 +- dlls/wmp/wmp_main.c | 2 + dlls/wmp/wmp_private.h | 66 +++- include/wmp.idl | 27 +- include/wmpids.h | 435 ++++++++++++++++++++ 9 files changed, 1911 insertions(+), 97 deletions(-) create mode 100644 dlls/wmp/events.c create mode 100644 include/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;
Hi Anton,
On 02/02/2018 07:00 AM, Anton Romanov wrote:
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;
You can't do that. IWMPPlayer4 doesn't inherit from IWMPPlayer, so it's not the same interface. Also a short test (just calling QueryInterface() and checking the result) would be nice.
Thanks,
Jacek
Jacek,
On Tue, Feb 6, 2018 at 8:34 AM, Jacek Caban jacek@codeweavers.com wrote:
Hi Anton,
On 02/02/2018 07:00 AM, Anton Romanov wrote:
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;
You can't do that. IWMPPlayer4 doesn't inherit from IWMPPlayer, so it's not the same interface. Also a short test (just calling QueryInterface() and checking the result) would be nice.
Thanks for feedback. Have you had a chance to look at other patches in this series? I'm just unsure should I address something else as well before submitting new version.
Hi Anton,
On 02/06/2018 06:20 PM, Anton Romanov wrote:
Jacek,
On Tue, Feb 6, 2018 at 8:34 AM, Jacek Caban jacek@codeweavers.com wrote:
Hi Anton,
On 02/02/2018 07:00 AM, Anton Romanov wrote:
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;
You can't do that. IWMPPlayer4 doesn't inherit from IWMPPlayer, so it's not the same interface. Also a short test (just calling QueryInterface() and checking the result) would be nice.
Thanks for feedback. Have you had a chance to look at other patches in this series? I'm just unsure should I address something else as well before submitting new version.
I had a quick look, but didn't look closely yet. I noticed that there are no tests, while at least a bit of them would be nice. Here are some thoughts:
- patch 3: It seems like IWMPControls should be implemented in a separated object. With your implementation, QueryInterface will not do the right thing (it will never return IWMPControls, but when called on IWMPControls from get_controls(), it will find other WindowsMediaPlayer interfaces). Also we usually keep function implementations in the same order as declared in IDL file.
- patch 4 worries me a bit. It misses license header and has comments similar to PSDK version. Note that copying PSDK headers is not allowed.
- patch 5 and 6 has similar problems to patch 3.
In general, I'd suggest to resend the first patch or two and wait with others until this one is merged. It's often a case that feedback from the first patch will be important for others as well.
Thanks, Jacek
On 02/02/2018 07:00 AM, Anton Romanov wrote:
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;
You can't do that. IWMPPlayer4 doesn't inherit from IWMPPlayer, so it's not the same interface. Also a short test (just calling QueryInterface() and checking the result) would be nice.
Btw, even though IWMPPlayer does not inherit it "duplicates the methods of IWMPPlayer, IWMPPlayer2, and IWMPPlayer3, inherits the methods of IWMPCore3, and exposes additional methods" (c) MSDN. So, is there really a need to duplicate a vtbl?
Thanks, Anton.
Hi Anton,
On 2/7/18 6:40 AM, Anton Romanov wrote:
On 02/02/2018 07:00 AM, Anton Romanov wrote:
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;
You can't do that. IWMPPlayer4 doesn't inherit from IWMPPlayer, so it's not the same interface. Also a short test (just calling QueryInterface() and checking the result) would be nice.
Btw, even though IWMPPlayer does not inherit it "duplicates the methods of IWMPPlayer, IWMPPlayer2, and IWMPPlayer3, inherits the methods of IWMPCore3, and exposes additional methods" (c) MSDN. So, is there really a need to duplicate a vtbl?
For this to work, vtbls of IWMPPlayer and IWMPPlayer4 would need to compatible (as in IWMPPlayerVtbl would have to be a prefix of IWMPPlayer4Vtbl). In this case it's not: IWMPPlayer4 has get_dvd() (from IWMPCore2) where IWMPPlayer has get_enabled().
Given that, for this to work we need separated vtbls. MSDN in such case is mostly targeted for C++ where compiler takes care of that, but we need to forward calls explicitly. Note that implementing IWMPPlayer on top of IWMPPlayer4 is trivial - just call proper IWMPPlayer4 function.
Jacek
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 | 36 +++-- 7 files changed, 438 insertions(+), 80 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..204b2f6527 --- /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 = heap_realloc(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..d599c5bc6b 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -19,9 +19,21 @@ #define COBJMACROS
#include "windows.h" +#include "wine/heap.h" #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,27 +49,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; - -static inline void* __WINE_ALLOC_SIZE(1) heap_alloc(size_t len) -{ - return HeapAlloc(GetProcessHeap(), 0, len); -} - -static inline void* __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t len) -{ - return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); -} - -static inline BOOL heap_free(void *mem) -{ - return HeapFree(GetProcessHeap(), 0, mem); -}
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 d599c5bc6b..003eef8015 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -43,6 +43,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 --- include/wmpids.h | 435 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 435 insertions(+) create mode 100644 include/wmpids.h
diff --git a/include/wmpids.h b/include/wmpids.h new file mode 100644 index 0000000000..a562df3831 --- /dev/null +++ b/include/wmpids.h @@ -0,0 +1,435 @@ +/* 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 + +/* open state */ +#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 003eef8015..cb8a408b7f 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -44,6 +44,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 cb8a408b7f..b9c66a952a 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -46,6 +46,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 | 319 +++++++++++++++++++++++++++++++++++++++++++------ dlls/wmp/wmp_private.h | 34 ++++++ 2 files changed, 317 insertions(+), 36 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 69979be21d..268764955a 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); @@ -111,9 +127,38 @@ static HRESULT WINAPI WMPPlayer4_get_URL(IWMPPlayer4 *iface, BSTR *pbstrURL)
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 +549,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 +595,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 +670,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 +709,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 +760,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 +909,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 +928,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 +960,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 +990,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 +1155,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 +1404,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 +1531,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 +1590,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 b9c66a952a..810fafaf27 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -22,6 +22,8 @@ #include "wine/heap.h" #include "ole2.h" #include "wmp.h" +#include "wine/unicode.h" +#include "dshow.h"
typedef struct { IConnectionPoint IConnectionPoint_iface; @@ -55,6 +57,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; @@ -69,3 +88,18 @@ void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams); void unregister_wmp_class(void) DECLSPEC_HIDDEN;
extern HINSTANCE wmp_instance DECLSPEC_HIDDEN; +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; +}