2
votes

I need to create a list view using WINAPI and MINGW (No possibility of MFC, WTF or any of the sort. Pure C/C++ and WINAPI), but i am not sure which list type to use for the easiest solution.

The listview items will be ownerdrawn, and it requires items to be in lines with fixed item widths.

|-----------------------|
| item1 | item2 | item3 |
|-----------------------|
| item4 | item5 | item6 |
|-----------------------|
| item7 | item8 | item9 |
|-----------------------|

What list type should i use for the easiest solution:

  • LVS_REPORT with ownerdrawn items and subitems. (a lot of custom msg handling)
  • LVS_ICON with custom width fixing. (not sure how to do it)
  • LVS_LIST ??
  • ???

Any win32 programming wizard out there, who knows how i could accomplish my goal without much headache ?

Update

Ok i got it. TLDR; solution is to get the cursor position from the user clicked, then do a subitemhittest and find out on which item/subitem the user clicked. Then set that item/subitem to LVIS_SELECTED. But you do have to ownerdraw the list, because windows does not support subitem column selecting natively.

Thx to nariuji and fluter for their supporting tips and tricks.

2
I would just try out things. Let the user decide on view.Cheers and hth. - Alf
Icon view will list it in that order. Owner draw version is not easy. See this post for hints stackoverflow.com/a/36443401/4603670Barmak Shemirani
What is this "Pure C/C++" of which you speak?Lightness Races in Orbit

2 Answers

2
votes

custom draw:
It is able to be change item's fonts and a back-ground color, and so on.
It is a functionality for LVS_REPORT and LVS_ICON

DWORD OnPrePaint(int nID, LPNMCUSTOMDRAW lpnmcd) {
    if(lpnmcd->hdr.idFrom == IDC_MY_LISTVIEW)  // my list view's ID
        return CDRF_NOTIFYITEMDRAW;            // custom draw
    else
        return CDRF_DODEFAULT;
}
DWORD OnItemPrePaint(int nID, LPNMCUSTOMDRAW lpnmcd) {
    if(lpnmcd->hdr.idFrom == IDC_MY_LISTVIEW){
        LPNMLVCUSTOMDRAW lpnmlv = (LPNMLVCUSTOMDRAW)lpnmcd;
        if(lpnmcd->dwItemSpec % 2) {            // change color
            lpnmlv->clrText = RGB(255, 255, 255);
            lpnmlv->clrTextBk = RGB(128, 128, 128);
        }
    }
    return CDRF_DODEFAULT;
}

owner draw:
It is necessary that all drawing code are written.
It is a functionality for only a style of LVS_REPORT.

void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct) {
    CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);
    int nItem = lpDrawItemStruct->itemID;
    LV_ITEM lvi;
    lvi.mask = LVIF_IMAGE | LVIF_STATE | LVIF_PARAM;
    lvi.iItem = nItem;
    lvi.iSubItem = 0;
    lvi.stateMask = 0xFFFF;
    GetItem(&lvi);

    // selected item color
    if (lvi.state & LVIS_SELECTED) {
        CBrush cb(::GetSysColor(COLOR_HIGHLIGHT));
        pDC->FillRect(rcItem, &cb);
    }
    else {
        // stripe color
        if (nItem % 2) {
            CBrush cb(::GetSysColor(LTGRAY_BRUSH));
            pDC->FillRect(rcItem, &cb);
        }
    }

    // draw text
    CRect rectText;
    GetItemRect(nItem, rectText, LVIR_LABEL);
    CString strData = GetItemText(nItem, 0);
    pDC->DrawText(strData, rectText, DT_LEFT | DT_SINGLELINE | DT_NOPREFIX | DT_VCENTER);
}
1
votes

Read about list view's docs on styles and views, what you want is LVS_REPORT, that's the view style gives you rows and columns. Other views will adapt and rearrange the items according to the controls sizes.

list view report style

https://msdn.microsoft.com/en-us/library/windows/desktop/bb774735(v=vs.85).aspx#ListView_Styles_and_Views