快捷搜索:

Windows Mobile多媒体开发总结之Media Player Plugins(续

本文示例源代码或素材下载

在文章“Windows Mobile多媒体开拓总结之Media Player Plugins ”中总结了在WM(Windows Mobile)中扩展WMP(Windows Media Player)的几种措施。宣布之后有很多同伙扣问详细做法,以是我乘机也总结下相关常识,刚好也补一下我这方面的差缺。

需求:在WM开拓中假如不是零丁开拓自己的播放器或者应用第三方播放器,你就只能应用WMP,然则你可能必要在其余利用法度榜样或者驱动中节制WMP,或者必要得到WMP的播放状态,那么如何做呢?你可能会想到向WMP对应的按键发送消息,或者模拟键盘消息。实际上这些都不是好的办理规划。办理措施便是应用User Interface Background Plug-ins,这在上一篇文章中提到过了。

涉及到的常识:User Interface Background Plug-ins必要实现的接口和操作WMP的措施,COM进程内办事器的编写(在Windows下扩展微软本身软件,比如扩展IE,基础都以COM的形式),Today Plug-ins的编写等。(当然你应用ATL会更方便,就不必要自己这样一步步的实现COM了。这里只是为了深入的懂得下COM内部道理。)

【第一步】在Windows Mobile中开拓WMP相关头文件在AKU中的位置如下图(比如AKU 6.15):

图片看不清楚?请点击这里查看原图(大年夜图)。

在你的项目中必要应用wmp.h和wmpplug.h头文件。

【第二步】实现作为COM进程内办事器必要的措施,这也是必要在DLL中导出的措施:

DllGetClassObject

DllCanUnloadNow

DllRegisterServer

先简单懂得下COM办事器在创建历程中的位置,为了偷懒,图就直接引用VC常识库的,组件DLL等于所要编写的COM办事器端,客户端便是WMP:

图片看不清楚?请点击这里查看原图(大年夜图)。

关于更多COM的道理常识和应用可以参考《COM本色论》、《深入解析ATL》(我对ATL/WTL照样知之甚少,这本书已经放我枕头边好久了,不停在进修Windows操作系统而延误了进修ATL)或VC常识库等。

对上面的图再解释一下,当客户端调用CoCreateInstance措施(这是WMP去做的,我们不管)时,CoCreateInstance实际上完成了下列三步:

CoGetClassObject(rclsid, dwClsContext, NULL, IID_IClassFactory, (void **)&pCF); //此措施调用我们要实现的DllGetClassObject措施,得到工厂工具的指针

pCF->CreateInstance(pUnkOuter, riid, ppvObject);//CMediaPlayerPluginClassFactory::CreateInstance措施此时被调用

pCF->Release();

看一下我们要实现的这3个措施代码是如何的

STDAPI DllGetClassObject(REFCLSID clsid, REFIID riid, VOID ** ppv)

{

HRESULT                             hr;

CMediaPlayerPluginClassFactory *    pcf;

*ppv = NULL;

if ((pcf = new CMediaPlayerPluginClassFactory()) == NULL)

return E_OUTOFMEMORY;

if (FAILED(hr = pcf->QueryInterface(riid, ppv)))//把插件工厂工具的指针通报给WMP

{

delete pcf;

return hr;

}

return S_OK;

}

STDAPI DllCanUnloadNow()

{

if (g_pServer->CanUnload())

return S_OK;

else

return S_FALSE;

}

STDAPI DllRegisterServer()//当你安装插件时系统调用这个措施,在这里你把你的COM办事器注册到注册表的CLSID键上。

{

TCHAR   szModulePath[MAX_PATH];

// Get our module path.

if (!GetModuleFileName(GetModuleHandle(s_szModuleName), szModulePath, MAX_PATH))

return E_FAIL;

szModulePath[MAX_PATH - 1] = _T('');

// register this COM object.

//

// IMPORTANT:

// be sure to update this GUID with another if you create another plug-in.  Each plug-in must have a unique GUID.

return DllRegisterServerImplementation(_T("{009B9B8A-5080-4d09-8F74-9BD96A3558D4}"), s_szRegDescription, szModulePath, _T("Free"));

}

在上一篇文章中我列出了这个接口下的措施:

STDMETHODIMP Create(HWND hwndParent, HWND * phwndWindow);

STDMETHODIMP Destroy();

STDMETHODIMP DisplayPropertyPage(HWND hwndParent);

STDMETHODIMP GetProperty(LPCWSTR wszName, VARIANT * pvarProperty);

STDMETHODIMP SetCore(IWMPCore * pCore);

STDMETHODIMP SetProperty(LPCWSTR wszName, const VARIANT * pvarProperty);

STDMETHODIMP TranslateAccelerator(MSG * pMsg);

对付这些措施,实现你必要的,不感兴趣的仅仅让它为空即可,比如:

HRESULT CMediaPlayerPlugin::Create(HWND hwndParent, HWND * phwndWindow)

{

// As per the IWMPPluginUI documentation, this method will never be called

// because we're a background plugin (our registry Capabilities flags include

// PLUGIN_TYPE_BACKGROUND = 0x00000001).

return E_NOTIMPL;

}

SetCore是个关键措施,由于我们必要经由过程它得到操作WMP的接口指针,这里我们把得到的指针寄放在m_pCore中:

HRESULT CMediaPlayerPlugin::SetCore(IWMPCore * pCore)

{

// This method is called shortly after this instance is created, and allows

// us to hook up to Windows Media Player. Save the interface pointer.

//

// When WMP is shutting down, it calls SetCore(NULL) so we have to handle that

// as well.

if (m_pCore != NULL)

{

m_pCore->Release();

}

m_pCore = pCore;

if (m_pCore != NULL)

{

m_pCore->AddRef();

}

return S_OK;

}

您可能还会对下面的文章感兴趣: