Signed-off-by: Anton Romanov theli.ua@gmail.com --- dlls/wmp/player.c | 61 +++++++++++++++++++++++++++++++++++++++++++------- dlls/wmp/tests/media.c | 27 ++++++++++++++++++++++ dlls/wmp/wmp_private.h | 3 +++ 3 files changed, 83 insertions(+), 8 deletions(-)
diff --git a/dlls/wmp/player.c b/dlls/wmp/player.c index 42ee06315a..d3c67a3820 100644 --- a/dlls/wmp/player.c +++ b/dlls/wmp/player.c @@ -1376,8 +1376,22 @@ static HRESULT WINAPI WMPControls_Invoke(IWMPControls *iface, DISPID dispIdMembe 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; + 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); + *pIsAvailable = VARIANT_FALSE; + if (!This->pFilterGraph) { + *pIsAvailable = VARIANT_FALSE; + } else if (strcmpW(currentPosition, bstrItem) == 0) { + DWORD capabilities; + IMediaSeeking_GetCapabilities(This->media_seeking, &capabilities); + *pIsAvailable = (capabilities & AM_SEEKING_CanSeekAbsolute) ? + VARIANT_TRUE : VARIANT_FALSE; + } else { + FIXME("%s not implemented\n", debugstr_w(bstrItem)); + return E_NOTIMPL; + } + + return S_OK; }
static HRESULT WINAPI WMPControls_play(IWMPControls *iface) @@ -1403,6 +1417,11 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface) if (SUCCEEDED(hres)) hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaControl, (void**)&This->media_control); + if (SUCCEEDED(hres)) + hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaSeeking, + (void**)&This->media_seeking); + if (SUCCEEDED(hres)) + hres = IMediaSeeking_SetTimeFormat(This->media_seeking, &TIME_FORMAT_MEDIA_TIME); update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, WMP_OPEN_STATE_MEDIA_OPEN); if (SUCCEEDED(hres)) hres = IGraphBuilder_QueryInterface(This->pFilterGraph, &IID_IMediaEvent, @@ -1420,7 +1439,10 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface) } } if (SUCCEEDED(hres)) { + LONGLONG duration; update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_PLAYING); + if (SUCCEEDED(IMediaSeeking_GetDuration(This->media_seeking, &duration))) + media->duration = (DOUBLE)duration / 10000000.0f; } else { update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, WMP_PLAY_STATE_UNDEFINED); } @@ -1445,6 +1467,8 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface) IMediaControl_Release(This->media_control); if (This->media_event) IMediaEvent_Release(This->media_event); + if (This->media_seeking) + IMediaSeeking_Release(This->media_seeking); This->pFilterGraph = NULL; This->media_control = NULL; This->media_event = NULL; @@ -1480,15 +1504,33 @@ static HRESULT WINAPI WMPControls_fastReverse(IWMPControls *iface) static 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); + if (!This->media_seeking) + return S_FALSE; + + hres = IMediaSeeking_GetCurrentPosition(This->media_seeking, ¤tPosition); + *pdCurrentPosition = (DOUBLE) currentPosition / 10000000.0f; + TRACE("hres: %d, pos: %f\n", hres, *pdCurrentPosition); + return hres; }
static 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); + if (!This->media_seeking) + return S_FALSE; + + Current = 10000000 * dCurrentPosition; + hres = IMediaSeeking_SetPositions(This->media_seeking, &Current, + AM_SEEKING_AbsolutePositioning, NULL, AM_SEEKING_NoPositioning); + + return hres; }
static HRESULT WINAPI WMPControls_get_currentPositionString(IWMPControls *iface, BSTR *pbstrCurrentPosition) @@ -1725,9 +1767,12 @@ static HRESULT WINAPI WMPMedia_getMarkerName(IWMPMedia *iface, LONG MarkerNum, B
static HRESULT WINAPI WMPMedia_get_duration(IWMPMedia *iface, DOUBLE *pDuration) { + /* MSDN: If this property is used with a media item other than the one + * specified in Player.currentMedia, it may not contain a valid value. */ WMPMedia *This = impl_from_IWMPMedia(iface); - FIXME("(%p)->(%p)\n", This, pDuration); - return E_NOTIMPL; + TRACE("(%p)->(%p)\n", This, pDuration); + *pDuration = This->duration; + return S_OK; }
static HRESULT WINAPI WMPMedia_get_durationString(IWMPMedia *iface, BSTR *pbstrDuration) diff --git a/dlls/wmp/tests/media.c b/dlls/wmp/tests/media.c index a6ed14b316..4af5078857 100644 --- a/dlls/wmp/tests/media.c +++ b/dlls/wmp/tests/media.c @@ -165,6 +165,11 @@ static void test_wmp(void) IOleObject *oleobj; static DWORD dw = 100; IWMPSettings *settings; + DOUBLE duration; + VARIANT_BOOL vbool; + IWMPMedia *media; + static const WCHAR currentPosition[] = {'c','u','r','r','e','n','t','P','o','s','i','t','i','o','n',0}; + BSTR bstrcurrentPosition = SysAllocString(currentPosition);
hres = CoCreateInstance(&CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, &IID_IOleObject, (void**)&oleobj); if(hres == REGDB_E_CLASSNOTREG) { @@ -202,6 +207,10 @@ static void test_wmp(void) ok(hres == S_OK, "get_controls failed: %08x\n", hres); ok(controls != NULL, "controls = NULL\n");
+ hres = IWMPControls_get_isAvailable(controls, bstrcurrentPosition, &vbool); + ok(hres == S_OK, "IWMPControls_get_isAvailable failed: %08x\n", hres); + ok(vbool == VARIANT_FALSE, "unexpected value\n"); + hres = IWMPControls_play(controls); ok(hres == NS_S_WMPCORE_COMMAND_NOT_AVAILABLE, "IWMPControls_play is available: %08x\n", hres);
@@ -221,6 +230,23 @@ static void test_wmp(void) CHECK_CALLED(OPENSTATE_CHANGE); CHECK_CALLED(PLAYSTATE_CHANGE);
+ hres = IWMPControls_get_isAvailable(controls, bstrcurrentPosition, &vbool); + ok(hres == S_OK, "IWMPControls_get_isAvailable failed: %08x\n", hres); + ok(vbool == VARIANT_TRUE, "unexpected value\n"); + + hres = IWMPControls_get_currentPosition(controls, &duration); + ok(hres == S_OK, "IWMPControls_get_currentPosition failed: %08x\n", hres); + ok(duration == 0.0, "unexpected value\n"); + + hres = IWMPControls_put_currentPosition(controls, duration); + ok(hres == S_OK, "IWMPControls_put_currentPosition failed: %08x\n", hres); + + hres = IWMPPlayer4_get_currentMedia(player4, &media); + ok(hres == S_OK, "IWMPPlayer4_get_currentMedia failed: %08x\n", hres); + hres = IWMPMedia_get_duration(media, &duration); + ok(hres == S_OK, "IWMPMedia_get_duration failed: %08x\n", hres); + ok(duration == 0.047, "unexpected value: %f\n", duration); + SET_EXPECT(OPENSTATE_CHANGE); SET_EXPECT(PLAYSTATE_CHANGE); hres = IWMPControls_stop(controls); @@ -241,6 +267,7 @@ static void test_wmp(void) IOleObject_Release(oleobj); DeleteFileW(filename); SysFreeString(filename); + SysFreeString(bstrcurrentPosition); }
START_TEST(media) diff --git a/dlls/wmp/wmp_private.h b/dlls/wmp/wmp_private.h index 1ffc36c74c..07fc0e1d9f 100644 --- a/dlls/wmp/wmp_private.h +++ b/dlls/wmp/wmp_private.h @@ -42,6 +42,8 @@ typedef struct { LONG ref;
WCHAR *url; + + DOUBLE duration; } WMPMedia;
struct WindowsMediaPlayer { @@ -76,6 +78,7 @@ struct WindowsMediaPlayer { IGraphBuilder* pFilterGraph; IMediaControl* media_control; IMediaEvent* media_event; + IMediaSeeking* media_seeking;
/* Async event notification */ HANDLE event_thread;