用combobox扩展控件(dsCtrlComboBox)做出类似QQ登录界面的效果
原文地址:http://www.uieasy.cn/blog/?p=513
传统的combobox 在使用方面有很多限制,很难满足我们combobox类型控件的需求。主要表现中combobox内置的listbox难以控制且比较难以完美绘制。因此我们在DSkinControl控件中添加了新的控件dsCtrlComboBox来实现一些标准combobox难以实现的功能。
dsCtrlComboBox控件结构
由于使用dskinlite界面库可以自由绘制一个子窗口,绘制listbox,因此上图所示QQ登录界面很容易配置出来。首先是上部继承自CWnd的子窗口,我们在dsCtrlCombobox中使用combobox_bk来绘制。xml配置如下:
<window name="combobox_bk" type="static">
<property bkcolor="RGB(255,255,255)" btransparentbk="false" />
<text state="all" font="#default" left="30" vertalign="center" bsingleline="true" textcolor="RGB(0,0,0)" />
<image state="normal" picfile="#extend.combobox.bk.nor" paintmode="stretchparthorz" left_part="3" right_part="3"/>
<image state="over|down" picfile="#extend.combobox.bk.over" paintmode="stretchparthorz" left_part="3" right_part="3"/>
<image state="all" index="100" id="image.default" picfile="#extend.combobox.bk.nor" left="5" top="3" width="20" height="20"/>
<image state="normal" index="2" left="-25" top="1" width="24" height="24" picfile="#extend.combobox.btn.nor" />
<image state="over" index="2" left="-25" top="1" width="24" height="24" picfile="#extend.combobox.btn.over" />
<image state="down" index="2" left="-25" top="1" width="24" height="24" picfile="#extend.combobox.btn.down" />
</window>
其中
<image state="all" index="100" id="image.default" picfile="#extend.combobox.bk.nor" left="5" top="3" width="20" height="20"/>
是我们为类似IM登陆中使用的combobox优化的一种模式。其中index=100 id="image.default"是固定的值,用于显示dsCtrlCombobox前面的用户头像。
在dsCtrlComboBox内部代码中,通过如下调用来控制界面显示:
void dsCtrlComboBox::SetWindowImage( CString strImage)
{
ShowWindowImage( TRUE);
if ( !strImage.IsEmpty())
dsSetDrawItemValue( GetSafeHwnd(), _T("image.default"), strImage, FALSE);
}
void dsCtrlComboBox::ShowWindowImage(BOOL bShow)
{
if ( bShow )
dsSetDrawItemVisible( GetSafeHwnd(), 100,100, TRUE, FALSE);
else
dsSetDrawItemVisible( GetSafeHwnd(), 100,100, FALSE, FALSE);
}
因为我们提供dsCtrlComboBox的所有源码,因此开发人员也可以根据自己的需要来定义这些绘制元素。
同时我们通过以下xml配置绘制下拉的listbox:
<window name="combobox.listbox" type="">
<property bkcolor="#system_bg" bordercolor="RGB(255,0,0)" btransparentbk="false" scrollbar="scrollbar" />
<rect id="border" index="1" bordercolor="#system.border" borderwidth="1" style="hole" />
<rect id="border" index="2" bordercolor="RGB(255,255,255)" left="1" top="1" right="-1" bottom="-1" borderwidth="1" style="hole" />
<rect id="item" state="checked" gradientmode="horiz" gradientbegincolor="RGB(63,152,217)" gradientendcolor="RGB(48,134,198)" />
<rect id="item" bordercolor="RGB(255,255,255)" fillcolor="RGB(255,255,255)" state="normal"/>
<listboxinfo bDrawOver="true" itemheight="35" >
<drawitem id="default" >
<image state="all" id="image.default" picfile="#extend.combobox.bk.nor" left="5" top="2" width="20" height="20"/>
<text id="text.default" content="" left="30" top="4" state="normal" textcolor="RGB(0,0,0)" font="#default"/>
<text id="text.default" content="" left="30" top="4" state="over" textcolor="RGB(68,138,237)" font="#default"/>
<text id="text.default" content="" left="30" top="4" state="checked" textcolor="RGB(255,255,255)" font="#default"/>
<eventitem id="close" event="LButtonDown" cursor="handcur" state="checked" left="-20" top="5" width="15" height="15" visible="true">
<image state="normal" picfile="#extend.listbox.closebtn.nor" />
<image state="over" picfile="#extend.listbox.closebtn.over" />
</eventitem>
</drawitem>
</listboxinfo>
</window>
同样以上XML中id为“text.default” 和id 为“image.default”的绘制元素在代码中会被设置不同的值,用以显示每一个item对应的文本和图片值。
dsCtrlComboBox 函数使用
基本上我们完全按照MFC CComboBox的API来做封装,为了使用户很容易理解并使用。CComboBox的大部分函数我们在dsCtrlComboBox中都实现了,有些做了一些扩展。如:
int dsCtrlComboBox::AddString( LPCTSTR lpszString, LPCTSTR lpszImage);
此函数表示在添加item项时,同时指定item text及 item image。详情请参考我们的ComboBoxTest示例工程。
总结:
由于DSkinLite界面库对界面绘制灵活的支持,使得我们可以使用dsCtrlComboBox非常容易的绘制出不同样式的界面,本文中的类似IM软件中用户登陆combobox只是一个方面的应用,因为我们提供了DSkinControl的所有源码,开发人员可以根据界面需要配置不同的界面来。

浙公网安备 33010602011771号