第六步,初始化对话框
通过重载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:当用户改变了属性的时候,在onreceivemessage方法中调用上面的函数。
void setdirty()
{
m_bdirty = true;
if (m_ppagesite)
{
m_ppagesite->onstatuschange(proppagestatus_dirty);
}
}
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添加一个类厂模板的说明。这个全局的数组是你的dll中创建的所有的com对象都要用到的。
const amoviesetup_filter filtersetupdata =
{
/* not shown ... */
};cfactorytemplate g_templates[] =
{
// this entry is for the filter.
{
wszname,
&clsid_grayfilter,
cgrayfilter::createinstance,
null,
&filtersetupdata
},
// this entry is for the property page.
{
l"saturation props",
&clsid_saturationprop,
cgrayprop::createinstance,
null, null
}
};