ListBox 每项前加 Icon(金山词霸索引控件)(上)
来源:互联网 发布:淘宝滥用商标关键字 编辑:程序博客网 时间:2024/04/30 15:47
终于搞完了英文戏剧,又有时间接着做项目了.昨天完成了一个类似于金山词霸索引的控件,界面如下图,觉得学到满多东西的,所以想到要写下来.
要实现这样的一个功能,首先要想的是到底金山词霸用的是怎样的一个控件,是ComboBox, ListBox, 还是ListView. 当我找了很多资料,研究了各控件的用法之后,我决定用ListBox做, 最终还是可以实现到想要的功能.
相信大家都用过金山词霸吧,在输入框输入一个单词,它就会显示相应的索引. 要完成这个功能,其实很简单.首先,要在ListBox的每一项加一个位图,怎样在ListBox前面加位图呢,下面我把实现的重要步骤写下来:
1. 首先在你的Dialog项目中添加一个新类,例如CIconListBox. 接着在类里添加下面的函数
//重载DrawItem这个函数
void CIconListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
{
// TODO: Add your code to draw the specified item
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
if ((int)lpDrawItemStruct->itemID < 0)
{
if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&
(lpDrawItemStruct->itemState & ODS_FOCUS))
{
pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
}
else if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&
!(lpDrawItemStruct->itemState & ODS_FOCUS))
{
pDC->DrawFocusRect(&lpDrawItemStruct->rcItem);
}
return;
}
CRect rcItem(lpDrawItemStruct->rcItem); // To draw the focus rect.
CRect rClient(rcItem); // Rect to highlight the Item
CRect rText(rcItem); // Rect To display the Text
CPoint Pt( rcItem.left , rcItem.top ); // Point To draw the Image
if(m_pImageList)
{
rClient.left += 16;
rText.left += 16;
rText.top += 2;
}
else
{
rText.top += 2;
}
COLORREF crText;
CString strText;
int iImg = (int)lpDrawItemStruct->itemData;
if ((lpDrawItemStruct->itemState & ODS_SELECTED) &&
(lpDrawItemStruct->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
{
CBrush br(::GetSysColor(COLOR_HIGHLIGHT));
pDC->FillRect(&rClient, &br);
}
else if (!(lpDrawItemStruct->itemState & ODS_SELECTED) &&
(lpDrawItemStruct->itemAction & ODA_SELECT))
{
CBrush br(::GetSysColor(COLOR_WINDOW));
pDC->FillRect(&rClient, &br);
}
if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&
(lpDrawItemStruct->itemState & ODS_FOCUS))
{
pDC->DrawFocusRect(&rcItem);
}
else if ((lpDrawItemStruct->itemAction & ODA_FOCUS) &&
!(lpDrawItemStruct->itemState & ODS_FOCUS))
{
pDC->DrawFocusRect(&rcItem);
}
// To draw the Text set the background mode to Transparent.
int iBkMode = pDC->SetBkMode(TRANSPARENT);
if (lpDrawItemStruct->itemState & ODS_SELECTED)
crText = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
else if (lpDrawItemStruct->itemState & ODS_DISABLED)
crText = pDC->SetTextColor(::GetSysColor(COLOR_GRAYTEXT));
else
crText = pDC->SetTextColor(::GetSysColor(COLOR_WINDOWTEXT));
GetText(lpDrawItemStruct->itemID, strText);
UINT nFormat = DT_LEFT | DT_SINGLELINE | DT_VCENTER;
if (GetStyle() & LBS_USETABSTOPS)
nFormat |= DT_EXPANDTABS;
if(m_pImageList && (iImg != -1 ) )
m_pImageList->Draw(pDC,iImg,Pt,ILD_NORMAL);
//Draw the Text
pDC->DrawText(strText, -1, &rText, nFormat | DT_CALCRECT);
pDC->DrawText(strText, -1, &rText, nFormat);
pDC->SetTextColor(crText);
pDC->SetBkMode(iBkMode);
}
void CIconListBox::MeasureItem(LPMEASUREITEMSTRUCT lpMeasureItemStruct)
{
// TODO: Add your code to determine the size of specified item
lpMeasureItemStruct->itemHeight = 16;
}
//添加前面带位图的Item
int CIconListBox::AddString(LPCTSTR lpszItem, int iImg)
{
int iRet = CListBox::AddString(lpszItem);
if (iRet >= 0)
SetItemData(iRet, iImg);
return iRet;
}
//设置位图
void CIconListBox::SetItemImage(int iIndex, int iImg)
{
SetItemData(iIndex, iImg);
RedrawWindow();
}
在这个类添加一个protected类型的数据成员
CImageList* m_pImageList;
//////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
以上完成后,在你的Dialog 的.cpp文件上添加这样一个函数
//初始化位图表
void CMyListBoxDlg::InitImageLists()
{
CBitmap bmp;
// normal tree images
//在这里设置可以将一幅大的位图分成小的(例如一幅位图的图案是ABCDE,你可以在
//一项前面输出A,下一项输出B),循环输出 如果不用到这个功能后面两个参数设1
m_imgNormal.Create(
16, //截取位图的宽
15, //高
true,
1, //循环次数
1);
ASSERT(m_imgNormal.m_hImageList);
//load你要显示的位图
bmp.LoadBitmap(IDB_BITMAP3);
m_imgNormal.Add( &bmp, RGB(255,255,255));
bmp.DeleteObject();
}
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
然后在你的Dialog 的.h文件上添加这样一个数据成员
protected:
HICON m_hIcon;
CImageList m_imgNormal; //这里是要添加的
void InitImageLists();
CString Inputword;
// Generated message map functions
//{{AFX_MSG(CMyListBoxDlg)
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
afx_msg void OnEditchangeInputword();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////
以上完成后,就可以在对话框上拖进一个ListBox控件,添加为数据成员,它的类型是control,基于ClistBox ,然后把CListBox改成你自己写的类,例如我们上面的CiconListBox.
接着我们就在你的Dialog的.cpp文件的OnInitDialog() 添加代码:
InitImageLists();
for(int i = 0; i < 25 ; i++ )
{
m_list.AddString( "GWCB",0 ); //GWCB是要ItemText, 0是ImageList的索引值
}
//////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////
这样就完成了在ListBox每一项前面加位图了.后面要实现的是输入单词显示相应的单词索引,这个只是对字符串的处理,然后读索引文件(我是用XML格式的),比较简单,这里我就不多说了.有兴趣讨论或想要源代码的朋友可以联系我hongjian20_38@21cn.com- ListBox 每项前加 Icon(金山词霸索引控件)(上)
- ListBox 每项前加 Icon(金山词霸索引控件)(下)
- 【自绘ListBox之一】带Icon的ListBox控件
- 让ListBox控件每一行显示不同的颜色
- 服务器控件得到每一项的索引
- ListBox控件
- ListBox控件
- ListBox控件
- ListBox控件
- ListBox控件
- ListBox控件
- ListBox控件
- ListBox控件
- ListBox控件
- ListBox控件
- listbox控件
- ListBox 控件
- CComboBox控件的下拉列表框,用鼠标在该ListBox上滑动的时候显示出当前具有focus的item项的索引
- 车间站点完成了
- 关于DropDownList自动生成
- ajax 跨域问题的结局办法
- 3D效果表格
- chmod
- ListBox 每项前加 Icon(金山词霸索引控件)(上)
- ASP无法更新ACCESS数据库解决方法
- c#关于异步操作。
- 十六个经典面试问题回答思路
- 2007.05.21 symbian9
- AIX 系统性能检测
- 内存池-相关介绍
- 鱼和渔!
- 关于sql server建立索引需要注意的问题