wmp: Add media completion notifications.
Signed-off-by: Anton Romanov <theli.ua@gmail.com> Signed-off-by: Jacek Caban <jacek@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
a56e57b3ec
commit
a072899794
|
@ -899,18 +899,20 @@ HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory *iface, IUnknown *outer,
|
|||
|
||||
wmp->ref = 1;
|
||||
|
||||
init_player(wmp);
|
||||
if (init_player(wmp)) {
|
||||
ConnectionPointContainer_Init(wmp);
|
||||
hdc = GetDC(0);
|
||||
dpi_x = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||
dpi_y = GetDeviceCaps(hdc, LOGPIXELSY);
|
||||
ReleaseDC(0, hdc);
|
||||
|
||||
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);
|
||||
hres = IOleObject_QueryInterface(&wmp->IOleObject_iface, riid, ppv);
|
||||
} else {
|
||||
hres = E_FAIL;
|
||||
}
|
||||
IOleObject_Release(&wmp->IOleObject_iface);
|
||||
return hres;
|
||||
}
|
||||
|
|
|
@ -24,6 +24,12 @@
|
|||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(wmp);
|
||||
|
||||
static ATOM player_msg_class;
|
||||
static INIT_ONCE class_init_once;
|
||||
static UINT WM_WMPEVENT;
|
||||
static const WCHAR WMPmessageW[] = {'_', 'W', 'M', 'P', 'M','e','s','s','a','g','e',0};
|
||||
|
||||
|
||||
static void update_state(WindowsMediaPlayer *wmp, LONG type, LONG state)
|
||||
{
|
||||
DISPPARAMS dispparams;
|
||||
|
@ -212,18 +218,20 @@ static HRESULT WINAPI WMPPlayer4_put_currentMedia(IWMPPlayer4 *iface, IWMPMedia
|
|||
{
|
||||
WindowsMediaPlayer *This = impl_from_IWMPPlayer4(iface);
|
||||
TRACE("(%p)->(%p)\n", This, pMedia);
|
||||
|
||||
if(pMedia == NULL) {
|
||||
return E_POINTER;
|
||||
}
|
||||
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistChanging);
|
||||
if(This->wmpmedia != NULL) {
|
||||
IWMPControls_stop(&This->IWMPControls_iface);
|
||||
IWMPMedia_Release(This->wmpmedia);
|
||||
}
|
||||
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistChanged);
|
||||
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistOpenNoMedia);
|
||||
|
||||
IWMPMedia_AddRef(pMedia);
|
||||
This->wmpmedia = pMedia;
|
||||
IWMPMedia_AddRef(This->wmpmedia);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -1425,6 +1433,20 @@ static HRESULT WINAPI WMPControls_play(IWMPControls *iface)
|
|||
(void**)&This->media_control);
|
||||
if (SUCCEEDED(hres))
|
||||
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposMediaOpen);
|
||||
if (SUCCEEDED(hres))
|
||||
hres = IGraphBuilder_QueryInterface(This->filter_graph, &IID_IMediaEvent,
|
||||
(void**)&This->media_event);
|
||||
if (SUCCEEDED(hres))
|
||||
{
|
||||
IMediaEventEx *media_event_ex = NULL;
|
||||
hres = IGraphBuilder_QueryInterface(This->filter_graph, &IID_IMediaEventEx,
|
||||
(void**)&media_event_ex);
|
||||
if (SUCCEEDED(hres)) {
|
||||
hres = IMediaEventEx_SetNotifyWindow(media_event_ex, (OAHWND)This->msg_window,
|
||||
WM_WMPEVENT, (LONG_PTR)This);
|
||||
IMediaEventEx_Release(media_event_ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsTransitioning);
|
||||
|
@ -1457,9 +1479,15 @@ static HRESULT WINAPI WMPControls_stop(IWMPControls *iface)
|
|||
hres = IMediaControl_Stop(This->media_control);
|
||||
IMediaControl_Release(This->media_control);
|
||||
}
|
||||
if (This->media_event) {
|
||||
IMediaEvent_Release(This->media_event);
|
||||
}
|
||||
|
||||
IGraphBuilder_Release(This->filter_graph);
|
||||
This->filter_graph = NULL;
|
||||
This->media_control = NULL;
|
||||
This->media_event = NULL;
|
||||
|
||||
update_state(This, DISPID_WMPCOREEVENT_OPENSTATECHANGE, wmposPlaylistOpenNoMedia);
|
||||
update_state(This, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsStopped);
|
||||
return hres;
|
||||
|
@ -1823,8 +1851,66 @@ static const IWMPMediaVtbl WMPMediaVtbl = {
|
|||
WMPMedia_isReadOnlyItem
|
||||
};
|
||||
|
||||
void init_player(WindowsMediaPlayer *wmp)
|
||||
static LRESULT WINAPI player_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
if (msg == WM_WMPEVENT && wParam == 0) {
|
||||
WindowsMediaPlayer *wmp = (WindowsMediaPlayer*)lParam;
|
||||
LONG event_code;
|
||||
LONG_PTR p1, p2;
|
||||
HRESULT hr;
|
||||
if (wmp->media_event) {
|
||||
do {
|
||||
hr = IMediaEvent_GetEvent(wmp->media_event, &event_code, &p1, &p2, 0);
|
||||
if (SUCCEEDED(hr)) {
|
||||
TRACE("got event_code = 0x%02x\n", event_code);
|
||||
IMediaEvent_FreeEventParams(wmp->media_event, event_code, p1, p2);
|
||||
/* For now we only handle EC_COMPLETE */
|
||||
if (event_code == EC_COMPLETE) {
|
||||
update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsMediaEnded);
|
||||
update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsTransitioning);
|
||||
update_state(wmp, DISPID_WMPCOREEVENT_PLAYSTATECHANGE, wmppsStopped);
|
||||
}
|
||||
}
|
||||
} while (hr == S_OK);
|
||||
} else {
|
||||
FIXME("Got event from quartz when interfaces are already released\n");
|
||||
}
|
||||
}
|
||||
return DefWindowProcW(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
|
||||
static BOOL WINAPI register_player_msg_class(INIT_ONCE *once, void *param, void **context) {
|
||||
static WNDCLASSEXW wndclass = {
|
||||
sizeof(wndclass), CS_DBLCLKS, player_wnd_proc, 0, 0,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
WMPmessageW, NULL
|
||||
};
|
||||
|
||||
wndclass.hInstance = wmp_instance;
|
||||
player_msg_class = RegisterClassExW(&wndclass);
|
||||
WM_WMPEVENT= RegisterWindowMessageW(WMPmessageW);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void unregister_player_msg_class(void) {
|
||||
if(player_msg_class)
|
||||
UnregisterClassW(MAKEINTRESOURCEW(player_msg_class), wmp_instance);
|
||||
}
|
||||
|
||||
BOOL init_player(WindowsMediaPlayer *wmp)
|
||||
{
|
||||
InitOnceExecuteOnce(&class_init_once, register_player_msg_class, NULL, NULL);
|
||||
wmp->msg_window = CreateWindowW( MAKEINTRESOURCEW(player_msg_class), NULL, 0, 0,
|
||||
0, 0, 0, HWND_MESSAGE, 0, wmp_instance, wmp );
|
||||
if (!wmp->msg_window) {
|
||||
ERR("Failed to create message window, GetLastError: %d\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
if (!WM_WMPEVENT) {
|
||||
ERR("Failed to register window message, GetLastError: %d\n", GetLastError());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
wmp->IWMPPlayer4_iface.lpVtbl = &WMPPlayer4Vtbl;
|
||||
wmp->IWMPPlayer_iface.lpVtbl = &WMPPlayerVtbl;
|
||||
wmp->IWMPSettings_iface.lpVtbl = &WMPSettingsVtbl;
|
||||
|
@ -1833,6 +1919,7 @@ void init_player(WindowsMediaPlayer *wmp)
|
|||
|
||||
wmp->invoke_urls = VARIANT_TRUE;
|
||||
wmp->auto_start = VARIANT_TRUE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void destroy_player(WindowsMediaPlayer *wmp)
|
||||
|
@ -1840,6 +1927,7 @@ void destroy_player(WindowsMediaPlayer *wmp)
|
|||
IWMPControls_stop(&wmp->IWMPControls_iface);
|
||||
if(wmp->wmpmedia)
|
||||
IWMPMedia_Release(wmp->wmpmedia);
|
||||
DestroyWindow(wmp->msg_window);
|
||||
}
|
||||
|
||||
WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface)
|
||||
|
|
|
@ -40,16 +40,15 @@
|
|||
called_ ## kind |= (1 << index); \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_CALLED(kind, index) \
|
||||
#define CLEAR_CALLED(kind, index) \
|
||||
do { \
|
||||
ok(called_ ## kind & (1 << index), "expected " #kind ", %d\n", index); \
|
||||
expect_ ## kind &= ~(1 << index); \
|
||||
called_ ## kind &= ~(1 << index); \
|
||||
}while(0)
|
||||
|
||||
#define CHECK_CALLED_OR_BROKEN(kind, index) \
|
||||
#define CHECK_CALLED(kind, index) \
|
||||
do { \
|
||||
ok(called_ ## kind & (1 << index) || broken(1), "expected " #kind ", %d\n", index); \
|
||||
ok(called_ ## kind & (1 << index), "expected " #kind ", %d\n", index); \
|
||||
expect_ ## kind &= ~(1 << index); \
|
||||
called_ ## kind &= ~(1 << index); \
|
||||
}while(0)
|
||||
|
@ -65,9 +64,11 @@ DEFINE_EXPECT(PLAYSTATE);
|
|||
DEFINE_EXPECT(OPENSTATE);
|
||||
|
||||
static HANDLE playing_event;
|
||||
static HANDLE completed_event;
|
||||
static DWORD main_thread_id;
|
||||
|
||||
static const WCHAR mp3file[] = {'t','e','s','t','.','m','p','3',0};
|
||||
static const WCHAR mp3file1s[] = {'t','e','s','t','1','s','.','m','p','3',0};
|
||||
static inline WCHAR *load_resource(const WCHAR *name)
|
||||
{
|
||||
static WCHAR pathW[MAX_PATH];
|
||||
|
@ -151,6 +152,8 @@ static HRESULT WINAPI WMPOCXEvents_Invoke(IDispatch *iface, DISPID dispIdMember,
|
|||
CHECK_EXPECT(PLAYSTATE, V_UI4(pDispParams->rgvarg));
|
||||
if (V_UI4(pDispParams->rgvarg) == wmppsPlaying) {
|
||||
SetEvent(playing_event);
|
||||
} else if (V_UI4(pDispParams->rgvarg) == wmppsMediaEnded) {
|
||||
SetEvent(completed_event);
|
||||
}
|
||||
if (winetest_debug > 1)
|
||||
trace("DISPID_WMPCOREEVENT_PLAYSTATECHANGE, %d\n", V_UI4(pDispParams->rgvarg));
|
||||
|
@ -208,18 +211,16 @@ static HRESULT pump_messages(DWORD timeout, DWORD count, const HANDLE *handles)
|
|||
return res;
|
||||
}
|
||||
|
||||
static void test_wmp(void)
|
||||
static void test_completion_event(void)
|
||||
{
|
||||
DWORD res = 0;
|
||||
IWMPPlayer4 *player4;
|
||||
IWMPControls *controls;
|
||||
HRESULT hres;
|
||||
BSTR filename;
|
||||
IConnectionPointContainer *container;
|
||||
IConnectionPoint *point;
|
||||
IOleObject *oleobj;
|
||||
static DWORD dw = 100;
|
||||
IWMPSettings *settings;
|
||||
|
||||
hres = CoCreateInstance(&CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, &IID_IOleObject, (void**)&oleobj);
|
||||
if(hres == REGDB_E_CLASSNOTREG) {
|
||||
|
@ -243,6 +244,86 @@ static void test_wmp(void)
|
|||
hres = IOleObject_QueryInterface(oleobj, &IID_IWMPPlayer4, (void**)&player4);
|
||||
ok(hres == S_OK, "Could not get IWMPPlayer4 iface: %08x\n", hres);
|
||||
|
||||
filename = SysAllocString(load_resource(mp3file1s));
|
||||
|
||||
SET_EXPECT(OPENSTATE, wmposPlaylistChanging);
|
||||
SET_EXPECT(OPENSTATE, wmposPlaylistOpenNoMedia);
|
||||
SET_EXPECT(OPENSTATE, wmposPlaylistChanged);
|
||||
SET_EXPECT(OPENSTATE, wmposOpeningUnknownURL);
|
||||
SET_EXPECT(OPENSTATE, wmposMediaOpen);
|
||||
SET_EXPECT(OPENSTATE, wmposMediaOpening);
|
||||
SET_EXPECT(PLAYSTATE, wmppsPlaying);
|
||||
SET_EXPECT(PLAYSTATE, wmppsMediaEnded);
|
||||
SET_EXPECT(PLAYSTATE, wmppsStopped);
|
||||
SET_EXPECT(PLAYSTATE, wmppsTransitioning);
|
||||
/* following two are sent on vistau64 vms only */
|
||||
SET_EXPECT(OPENSTATE, wmposMediaChanging);
|
||||
SET_EXPECT(PLAYSTATE, wmppsReady);
|
||||
hres = IWMPPlayer4_put_URL(player4, filename);
|
||||
ok(hres == S_OK, "IWMPPlayer4_put_URL failed: %08x\n", hres);
|
||||
res = pump_messages(3000, 1, &completed_event);
|
||||
ok(res == WAIT_OBJECT_0, "Timed out while waiting for media to complete\n");
|
||||
|
||||
/* following two are sent on vistau64 vms only */
|
||||
CLEAR_CALLED(OPENSTATE, wmposMediaChanging);
|
||||
CLEAR_CALLED(PLAYSTATE, wmppsReady);
|
||||
|
||||
CHECK_CALLED(OPENSTATE, wmposPlaylistChanging);
|
||||
CHECK_CALLED(OPENSTATE, wmposPlaylistChanged);
|
||||
CHECK_CALLED(OPENSTATE, wmposPlaylistOpenNoMedia);
|
||||
CHECK_CALLED(PLAYSTATE, wmppsTransitioning);
|
||||
CHECK_CALLED(OPENSTATE, wmposOpeningUnknownURL);
|
||||
CHECK_CALLED(OPENSTATE, wmposMediaOpen);
|
||||
CHECK_CALLED(PLAYSTATE, wmppsPlaying);
|
||||
CHECK_CALLED(PLAYSTATE, wmppsMediaEnded);
|
||||
CHECK_CALLED(PLAYSTATE, wmppsStopped);
|
||||
/* MediaOpening happens only on xp, 2003 */
|
||||
CLEAR_CALLED(OPENSTATE, wmposMediaOpening);
|
||||
|
||||
hres = IConnectionPoint_Unadvise(point, dw);
|
||||
ok(hres == S_OK, "Unadvise failed: %08x\n", hres);
|
||||
|
||||
IConnectionPoint_Release(point);
|
||||
IWMPPlayer4_Release(player4);
|
||||
IOleObject_Release(oleobj);
|
||||
DeleteFileW(filename);
|
||||
SysFreeString(filename);
|
||||
}
|
||||
|
||||
static BOOL test_wmp(void)
|
||||
{
|
||||
DWORD res = 0;
|
||||
IWMPPlayer4 *player4;
|
||||
IWMPControls *controls;
|
||||
HRESULT hres;
|
||||
BSTR filename;
|
||||
IConnectionPointContainer *container;
|
||||
IConnectionPoint *point;
|
||||
IOleObject *oleobj;
|
||||
static DWORD dw = 100;
|
||||
IWMPSettings *settings;
|
||||
BOOL test_ran = TRUE;
|
||||
|
||||
hres = CoCreateInstance(&CLSID_WindowsMediaPlayer, NULL, CLSCTX_INPROC_SERVER, &IID_IOleObject, (void**)&oleobj);
|
||||
if(hres == REGDB_E_CLASSNOTREG) {
|
||||
win_skip("CLSID_WindowsMediaPlayer not registered\n");
|
||||
return FALSE;
|
||||
}
|
||||
ok(hres == S_OK, "Could not create CLSID_WindowsMediaPlayer instance: %08x\n", hres);
|
||||
|
||||
hres = IOleObject_QueryInterface(oleobj, &IID_IConnectionPointContainer, (void**)&container);
|
||||
ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
|
||||
|
||||
hres = IConnectionPointContainer_FindConnectionPoint(container, &IID__WMPOCXEvents, &point);
|
||||
IConnectionPointContainer_Release(container);
|
||||
ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
|
||||
|
||||
hres = IConnectionPoint_Advise(point, (IUnknown*)&WMPOCXEvents, &dw);
|
||||
ok(hres == S_OK, "Advise failed: %08x\n", hres);
|
||||
|
||||
hres = IOleObject_QueryInterface(oleobj, &IID_IWMPPlayer4, (void**)&player4);
|
||||
ok(hres == S_OK, "Could not get IWMPPlayer4 iface: %08x\n", hres);
|
||||
|
||||
settings = NULL;
|
||||
hres = IWMPPlayer4_get_settings(player4, &settings);
|
||||
ok(hres == S_OK, "get_settings failed: %08x\n", hres);
|
||||
|
@ -277,9 +358,10 @@ static void test_wmp(void)
|
|||
|
||||
SET_EXPECT(OPENSTATE, wmposOpeningUnknownURL);
|
||||
SET_EXPECT(OPENSTATE, wmposMediaOpen);
|
||||
SET_EXPECT(OPENSTATE, wmposMediaOpening);
|
||||
SET_EXPECT(PLAYSTATE, wmppsPlaying);
|
||||
SET_EXPECT(PLAYSTATE, wmppsTransitioning);
|
||||
/* MediaOpening happens only on xp, 2003 */
|
||||
SET_EXPECT(OPENSTATE, wmposMediaOpening);
|
||||
hres = IWMPControls_play(controls);
|
||||
ok(hres == S_OK, "IWMPControls_play failed: %08x\n", hres);
|
||||
res = pump_messages(5000, 1, &playing_event);
|
||||
|
@ -288,14 +370,15 @@ static void test_wmp(void)
|
|||
/* This happens on Vista Ultimate 64 vms
|
||||
* I have been unable to find out source of this behaviour */
|
||||
win_skip("Failed to transition media to playing state.\n");
|
||||
test_ran = FALSE;
|
||||
goto playback_skip;
|
||||
}
|
||||
CHECK_CALLED(OPENSTATE, wmposOpeningUnknownURL);
|
||||
CHECK_CALLED(OPENSTATE, wmposMediaOpen);
|
||||
/* MediaOpening happens only on xp, 2003 */
|
||||
todo_wine CHECK_CALLED_OR_BROKEN(OPENSTATE, wmposMediaOpening);
|
||||
CHECK_CALLED(PLAYSTATE, wmppsPlaying);
|
||||
CHECK_CALLED(PLAYSTATE, wmppsTransitioning);
|
||||
/* MediaOpening happens only on xp, 2003 */
|
||||
CLEAR_CALLED(OPENSTATE, wmposMediaOpening);
|
||||
|
||||
SET_EXPECT(PLAYSTATE, wmppsStopped);
|
||||
/* The following happens on wine only since we close media on stop */
|
||||
|
@ -331,6 +414,8 @@ playback_skip:
|
|||
IOleObject_Release(oleobj);
|
||||
DeleteFileW(filename);
|
||||
SysFreeString(filename);
|
||||
|
||||
return test_ran;
|
||||
}
|
||||
|
||||
START_TEST(media)
|
||||
|
@ -339,9 +424,15 @@ START_TEST(media)
|
|||
|
||||
main_thread_id = GetCurrentThreadId();
|
||||
playing_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
test_wmp();
|
||||
completed_event = CreateEventW(NULL, FALSE, FALSE, NULL);
|
||||
if (test_wmp()) {
|
||||
test_completion_event();
|
||||
} else {
|
||||
win_skip("Failed to play media\n");
|
||||
}
|
||||
|
||||
CloseHandle(playing_event);
|
||||
CloseHandle(completed_event);
|
||||
|
||||
CoUninitialize();
|
||||
}
|
||||
|
|
|
@ -21,3 +21,6 @@
|
|||
/* ffmpeg -ar 48000 -t 60 -f s16le -acodec pcm_s16le -ac 2 -i /dev/zero -acodec libmp3lame -aq 4 output.mp3 */
|
||||
/* @makedep: test.mp3 */
|
||||
test.mp3 RCDATA "test.mp3"
|
||||
/* ffmpeg -ar 48000 -t 1 -f s16le -acodec pcm_s16le -ac 2 -i /dev/zero -acodec libmp3lame -aq 4 test1s.mp3 */
|
||||
/* @makedep: test1s.mp3 */
|
||||
test1s.mp3 RCDATA "test1s.mp3"
|
||||
|
|
Binary file not shown.
|
@ -92,6 +92,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
|
|||
break;
|
||||
case DLL_PROCESS_DETACH:
|
||||
unregister_wmp_class();
|
||||
unregister_player_msg_class();
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -75,9 +75,13 @@ struct WindowsMediaPlayer {
|
|||
/* DirectShow stuff */
|
||||
IGraphBuilder* filter_graph;
|
||||
IMediaControl* media_control;
|
||||
IMediaEvent* media_event;
|
||||
|
||||
/* Async event notification */
|
||||
HWND msg_window;
|
||||
};
|
||||
|
||||
void init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
|
||||
BOOL init_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
|
||||
void destroy_player(WindowsMediaPlayer*) DECLSPEC_HIDDEN;
|
||||
WMPMedia *unsafe_impl_from_IWMPMedia(IWMPMedia *iface) DECLSPEC_HIDDEN;
|
||||
HRESULT create_media_from_url(BSTR url, IWMPMedia **ppMedia) DECLSPEC_HIDDEN;
|
||||
|
@ -88,6 +92,7 @@ void call_sink(ConnectionPoint *This, DISPID dispid, DISPPARAMS *dispparams) DEC
|
|||
HRESULT WINAPI WMPFactory_CreateInstance(IClassFactory*,IUnknown*,REFIID,void**) DECLSPEC_HIDDEN;
|
||||
|
||||
void unregister_wmp_class(void) DECLSPEC_HIDDEN;
|
||||
void unregister_player_msg_class(void) DECLSPEC_HIDDEN;
|
||||
|
||||
extern HINSTANCE wmp_instance DECLSPEC_HIDDEN;
|
||||
|
||||
|
|
Loading…
Reference in New Issue