如何创建Filter的属性页.doc_第1页
如何创建Filter的属性页.doc_第2页
如何创建Filter的属性页.doc_第3页
如何创建Filter的属性页.doc_第4页
如何创建Filter的属性页.doc_第5页
已阅读5页,还剩8页未读 继续免费阅读

VIP免费下载

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

如何创建Filter的属性页 摘要: 本篇文档我们将要讲述如何给一个filter创建一个属性页,通过CBasePropertyPage基类。这篇文档的实例代码演示了创建属性页的步骤,这里我们假设我们要创建属性页的视频filter支持饱和度属性页,这个属性页有一个滑动条,用户可以通过这个滑动条来控制饱和度。第一步,设置属性的机理Filter必须支持一种和属性页沟通的方式,通过属性页可以设置或者获取filter的属性,下面是可能的三种方式1暴露一个接口2通过IDispatch支持自动化属性3暴露IPropertyBag 接口,并定义一系列的属性下面的例子利用了一个普通的COM接口,叫做ISaturaton,这并不是一个真正的com接口,只是我们用来在这里举例的,你也可以自己定义任何的com对象。首先我们在一个头文件中声明接口的ID和定义。/ Always create new GUIDs! Never copy a GUID from an example. DEFINE_GUID(IID_ISaturation, 0x19412d6e, 0x6401, 0x475c, 0xb0, 0x48, 0x7a, 0xd2, 0x96, 0xe1, 0x6a, 0x19);interface ISaturation : public IUnknown STDMETHOD(GetSaturation)(long *plSat) = 0; STDMETHOD(SetSaturation)(long lSat) = 0; ; 你也可以用IDL定义接口,并用MIDL编译器创建头文件,然后在Filter上实现这个接口,这个例子采用“Get”,“Set”方法来设置饱和度的值,注意,修改这个m_lSaturation的值的时候一定要进行保护 class CGrayFilter : public ISaturation, /* Other inherited classes. */ private: CCritSec m_csShared; / Protects shared data. long m_lSaturation; / Saturation level. public: STDMETHODIMP GetSaturation(long *plSat) if (!plSat) return E_POINTER; CAutoLock lock(&m_csShared); *plSat = m_lSaturation; return S_OK; STDMETHODIMP SetSaturation(long lSat) CAutoLock lock(&m_csShared); if (lSat SATURATION_MAX) return E_INVALIDARG; m_lSaturation = lSat; return S_OK; ; 当然你实现接口的一些细节可能和上面的代码不一致。反正你自己实现就是了第二步,实现ISpecifyPropertyPages接口做完了上一步,下面就要在你个filter中实现ISpecifyPropertyPages接口,这个接口只有一个方法,GetPages,这个方法返回filter所支持的所有的属性页的CLSID。在这个例子里,Filter只支持一个属性页,首先产生一个CLSID,并在头文件声明/ Always create new GUIDs! Never copy a GUID from an example. DEFINE_GUID(CLSID_SaturationProp, 0xa9bd4eb, 0xded5, 0x4df0, 0xba, 0xf6, 0x2c, 0xea, 0x23, 0xf5, 0x72, 0x61); 然后要实现ISpecifyPropertyPages接口的GetPages方法:class CGrayFilter : public ISaturation, public ISpecifyPropertyPages, /* Other inherited classes. */ public: STDMETHODIMP GetPages(CAUUID *pPages) if (pPages = NULL) return E_POINTER; pPages-cElems = 1; pPages-pElems = (GUID*)CoTaskMemAlloc(sizeof(GUID); if (pPages-pElems = NULL) return E_OUTOFMEMORY; pPages-pElems0 = CLSID_SaturationProp; return S_OK; ;/* . */第三步,支持QueryInterface为了暴露Filter的接口,照着下面的步骤作哦1 在你的filter中包含DECLARE_IUNKNOWN宏的声明: Public: DECLARE_IUNKNOWN; 2 重载CUnknown:NonDelegatingQueryInterface 方法来检查两个接口的IIDs。 STDMETHODIMP CGrayFilter:NonDelegatingQueryInterface(REFIID riid, void *ppv) if (riid = IID_ISpecifyPropertyPages) return GetInterface(static_cast(this), ppv); if (riid = IID_ISaturation) return GetInterface(static_cast(this), ppv); return CBaseFilter:NonDelegatingQueryInterface(riid, ppv); 第四步,创建属性页到这一步,filter已经支持一个属性页的所需要的东西了,下一步就是要实现属性页本身了。首先创建一个对话框的资源,然后以这个对话的资源声明一个类,要从CBasePropertyPage. 派生,图1下面的代码显示了部分的声明,包含了我们在后面将要用到的部分变量。class CGrayProp : public CBasePropertyPage private: ISaturation *m_pGray; / Pointer to the filters custom interface. long m_lVal / Store the old value, so we can revert. long m_lNewVal; / New value. public: /* . */ ; 看看构造函数吧 CGrayProp:CGrayProp(IUnknown *pUnk) : CBasePropertyPage(NAME(GrayProp), pUnk, IDD_PROPPAGE, IDS_PROPPAGE_TITLE), m_pGray(0) 下面,你还要记得重载CBasePropertyPage 的几个方法哦OnConnect,当属性页创建的时候,会调用这个方法,通过这个方法将IUnknown指针付给Filter。OnActivate 当对话框创建的时候被调用OnReceiveMessage 当对话框接收到窗口消息时被调用OnApplyChanges当用户单击OK或者Apply 按钮来确认对属性进行更新时,调用OnDisconnect 当用户取消Property sheet时调用 第五步,保存filter的一个指针 通过重载CBasePropertyPage:OnConnect方法将一个指针保存到filter,下面的例子演示了如何通过方法传递过来的参数查询filter支持的接口 HRESULT CGrayProp:OnConnect(IUnknown *pUnk) if (pUnk = NULL) return E_POINTER; ASSERT(m_pGray = NULL); return pUnk-QueryInterface(IID_ISaturation, reinterpret_cast(&m_pGray); 第六步,初始化对话框通过重载CBasePropertyPage:OnActivate方法来初始化一个对话框,在这个例子里,属性页使用了滑动条,所以,在初始化的第一步就是要初始化控件动态库,然后再初始化slider。HRESULT CGrayProp:OnActivate(void) INITCOMMONCONTROLSEX icc; icc.dwSize = sizeof(INITCOMMONCONTROLSEX); icc.dwICC = ICC_BAR_CLASSES; if (InitCommonControlsEx(&icc) = FALSE) return E_FAIL; ASSERT(m_pGray != NULL); HRESULT hr = m_pGray-GetSaturation(&m_lVal); if (SUCCEEDED(hr) SendDlgItemMessage(m_Dlg, IDC_SLIDER1, TBM_SETRANGE, 0, MAKELONG(SATURATION_MIN, SATURATION_MAX); SendDlgItemMessage(m_Dlg, IDC_SLIDER1, TBM_SETTICFREQ, (SATURATION_MAX - SATURATION_MIN) / 10, 0); SendDlgItemMessage(m_Dlg, IDC_SLIDER1, TBM_SETPOS, 1, m_lVal); return hr; 第七步,处理窗口消息重载CBasePropertyPage:OnReceiveMessage方法来处理用户的输入等消息。如果你不想处理消息,你只需简单调用父类的OnReceiveMessage 即可。无论何时用户改变了属性,都会做下面的事情1 将属性页的m_bDirty设置为TRUE;2调用属性框的IPropertyPageSite:OnStatusChange方法,并传递一个PROPPAGESTATUS_DIRTY,这个标志用来通知property frame应该将Apply按钮可用,CBasePropertyPage:m_pPageSite变量保存着一个IPropertyPageSite接口为了简化步骤,你可以在你的属性页中添加下面的代码private: void SetDirty() m_bDirty = TRUE; if (m_pPageSite) m_pPageSite-OnStatusChange(PROPPAGESTATUS_DIRTY); 当用户改变了属性的时候,在OnReceiveMessage方法中调用上面的函数。 BOOL CGrayProp:OnReceiveMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) switch (uMsg) case WM_COMMAND: if (LOWORD(wParam) = IDC_DEFAULT) / User clicked the Revert to Default button. m_lNewVal = SATURATION_DEFAULT; m_pGray-SetSaturation(m_lNewVal); / Update the slider control. SendDlgItemMessage(m_Dlg, IDC_SLIDER1, TBM_SETPOS, 1, m_lNewVal); SetDirty(); return (LRESULT) 1; break; case WM_HSCROLL: / User moved the slider. switch(LOWORD(wParam) case TB_PAGEDOWN: case SB_THUMBTRACK: case TB_PAGEUP: m_lNewVal = SendDlgItemMessage(m_Dlg, IDC_SLIDER1, TBM_GETPOS, 0, 0); m_pGray-SetSaturation(m_lNewVal); SetDirty(); return (LRESULT) 1; / Switch. / Let the parent class handle the message. return CBasePropertyPage:OnReceiveMessage(hwnd,uMsg,wParam,lParam); 第八步,处理属性的改变重载CBasePropertyPage:OnApplyChanges方法来提交属性页的改变,如果用户单击了确定,或者应用按钮,OnApplyChanges方法都会调用到 HRESULT CGrayProp:OnApplyChanges(void) m_lVal = m_lNewVal; return S_OK; 第九步,断开属性页连接重载CBasePropertyPage:OnDisconnect方法来释放你在OnConnect方法中请求的所有的接口,如果用户没有更新属性,而是单击了取消按钮,你还要将属性的原始值保存下来。当用户单击取消按钮,但是没有相应的响应这个消息的方法,所以,你要检查用户是否调用了OnApplyChanges方法,看看例子也好:HRESULT CGrayProp:OnDisconnect(void) if (m_pGray) / If the user clicked OK, m_lVal holds the new value. / Otherwise, if the user clicked Cancel, m_lVal is the old value. m_pGray-SetSaturation(m_lVal); m_pGray-Release(); m_pGray = NULL; return S_OK; 第十步,支持com的注册最后一步就是要支持com的注册,因此 属性框才能够创建你属性页的实例,首先在全局数组g_Templates添加一

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论