如何在 ListControl MFC 中有一个多行项目?
Posted
技术标签:
【中文标题】如何在 ListControl MFC 中有一个多行项目?【英文标题】:How can I have a multi-line item in a ListControl MFC? 【发布时间】:2015-06-10 13:39:49 【问题描述】:我在 Visual Studio 2013 (C++) 中有一个带有项目列表(报表视图)的 MFC 列表控件
LVCOLUMN lvColumn;
lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.cx = 120;
lvColumn.pszText = "Full Name";
((CListCtrl*)GetDlgItem(IDC_LIST1))->InsertColumn(0, &lvColumn);
lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.cx = 75;
lvColumn.pszText = "Profession";
((CListCtrl*)GetDlgItem(IDC_LIST1))->InsertColumn(1, &lvColumn);
lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.cx = 80;
lvColumn.pszText = "Fav Sport";
((CListCtrl*)GetDlgItem(IDC_LIST1))->InsertColumn(2, &lvColumn);
lvColumn.mask = LVCF_FMT | LVCF_TEXT | LVCF_WIDTH;
lvColumn.fmt = LVCFMT_LEFT;
lvColumn.cx = 75;
lvColumn.pszText = "Hobby";
((CListCtrl*)GetDlgItem(IDC_LIST1))->InsertColumn(3, &lvColumn);
LVITEM lvItem;
int nItem;
lvItem.mask = LVIF_TEXT;
lvItem.iItem = 0;
lvItem.iSubItem = 0;
lvItem.pszText = "Sandra C. Anschwitz";
nItem = ((CListCtrl*)GetDlgItem(IDC_LIST1))->InsertItem(&lvItem);
((CListCtrl*)GetDlgItem(IDC_LIST1))->SetItemText(nItem, 1, "Singer");
((CListCtrl*)GetDlgItem(IDC_LIST1))->SetItemText(nItem, 2, "HandBall");
((CListCtrl*)GetDlgItem(IDC_LIST1))->SetItemText(nItem, 3, "Beach");
如何为全名、职业、运动和爱好设置多行项目?
【问题讨论】:
【参考方案1】:令人惊讶的是,默认的 CListCtrl 无法做到这一点。但是,通过一些自定义编码(和一些技巧),您可以获得您想要的效果。
首先,您需要从 CListCtrl 派生您自己的类,并为控件样式设置所有者绘制位 (Owner Draw Fixed = true)。在你的父对话框类中,创建一个图像列表(这里是诡计)。图像列表将用于指定列表控件每一行的高度。在下面的示例中,我使用了:
m_imagelist.Create(48, 48, ILC_COLOR4, 10, 10);
m_listctrl.SetImageList(&m_imagelist, LVSIL_SMALL);
您需要使用图像列表的 cx 和 cy 值来满足您的需求。您的控件将使用图像列表来调整每一行的大小,因为它预计会显示图标。接下来,像这样为 DrawItem 添加一个处理程序:
void MyClistCtrl::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
CString text = _T("Now is the time \nfor all good men\nto come to the aid");
pDC->DrawText(text , &lpDrawItemStruct->rcItem, DT_TOP);
// TODO: Add your code to draw the specified item
在我的示例中,这会导致……
这可能不是一个优雅的解决方案,但它确实有效。注意:使用这种方法,每一行都将具有相同的高度。
编辑:有几种方法可以获取行文本。最简单的方法是像这样使用 GetItemText:
CString txt = GetItemText(lpDrawItemStruct->itemID, 0);
pDC->DrawText(txt, &lpDrawItemStruct->rcItem, DT_TOP);
以上假设您使用 CListCtrl 方法之一设置每一行的文本来设置文本。
【讨论】:
非常感谢,您能告诉我如何在 DrawItem() 中嵌入项目文本和其他信息吗?目前,我调用SetItemText(nItem, 1, Actoss.str().c_str());
现在,如何调用DrawItem()?例如LPDRAWITEMSTRUCT 的值应该是多少?
@TOWI_Parallelism DrawItem 在需要渲染所有者绘制控件时调用。你不直接调用它。 MFC 将调用您的实现,让您有机会绘制控件的内容。 LPDRAWITEMSTRUCT 将填写您用于绘制控件的信息。
但是有没有办法在 LPDRAWITEMSTRUCT 中为每个项目嵌入所需的文本?在您的代码中,所有项目都将具有相同的 txt。以上是关于如何在 ListControl MFC 中有一个多行项目?的主要内容,如果未能解决你的问题,请参考以下文章
MFC使用ListControl时,第一次左键点击ListControl的列表时无法触发NM_CLICK消息,点击第二次时才能触发