How can I have a multi-line item in a ListControl MFC?

微笑、不失礼 提交于 2020-01-06 03:53:06

问题


I have an MFC List Control in Visual Studio 2013 (C++) with a List of items (Report view)

   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");

How can I have multiline items for Full Name, Profession, Sport and Hobby?


回答1:


Surprisingly, this is not possible with the default CListCtrl. But, with a little custom coding (and some trickery), you can get the effect you want.

First, you’ll need to derive your own class from CListCtrl and set the owner draw bit (Owner Draw Fixed = true) for the control style. In your parent dialog class, create an image list (here’s the trickery). The image list will be used to specify the height of each row of the list control. In my example below, I used:

m_imagelist.Create(48, 48, ILC_COLOR4, 10, 10);
m_listctrl.SetImageList(&m_imagelist, LVSIL_SMALL);

You’ll need to play around with the cx and cy values for the image list to fit your needs. Your control will use the image list to size each row because it’s anticipating displaying icons. Next, add a handler for DrawItem like this:

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
    }

In my example, this results in…

It may not be an elegant solution, but, it works. Note: With this approach, every row will have the same height.

EDIT: There are a few ways to obtain the row text. The easiest would be to use GetItemText like so:

CString txt = GetItemText(lpDrawItemStruct->itemID, 0);
pDC->DrawText(txt, &lpDrawItemStruct->rcItem, DT_TOP);

The above assumes you set the text for each row using one of the CListCtrl methods to set text.



来源:https://stackoverflow.com/questions/30758085/how-can-i-have-a-multi-line-item-in-a-listcontrol-mfc

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!