Control for owner-drawing items with 1 or 2 columns ?
CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 17

Thread: Control for owner-drawing items with 1 or 2 columns ?

  1. #1
    Join Date
    Jul 2001
    Posts
    293

    Control for owner-drawing items with 1 or 2 columns ?

    Hello,

    I want to show a list of graphical items in 1 or 2 columns (user selected).
    I will draw the items (owner-draw).
    I tried many hours today to find a solution with clistctrl.
    Now, I am on the way to give up.

    Is it possible to make it with clistctrl?
    Better idea?

    thx.
    Ralf

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Wallisellen (ZH), Switzerland
    Posts
    17,301

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Ralf, it is not clear what you mean by "show a list of graphical items in 1 or 2 columns".
    Also posting the code for drawing could help to understand your problem.
    Victor Nijegorodov

  3. #3
    Join Date
    Jul 2001
    Posts
    293

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Hello,

    it should look like this:
    Name:  sPlan 7.jpg
Views: 85
Size:  26.7 KB

    But every item is not an image, but an owner draw graphical object.

  4. #4
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,782

    Re: Control for owner-drawing items with 1 or 2 columns ?

    if all the images are the same size... and you just need a single text. to accompany it.

    It might be easier to just use the listcontrol in the normal way (not owner draw) and put it in Iconview (LVS_ICON).
    This may not be ideal if you need to handle hundreds/thousands of images though. In that case the simple way would be to use the customdraw (not ownerdraw, i.e. NM_CUSTOMDRAW) funcitonality and custom draw the items. (see http://msdn.microsoft.com/en-us/libr...v=vs.85).aspx)

  5. #5
    Join Date
    Jul 2001
    Posts
    293

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Hello OReubens,

    I tried this before. It seems to be the best solution.
    But it do not work, because I can not tell the control to show a specific number of columns.
    Are do you have an idea to do that?

  6. #6
    Join Date
    Jul 2001
    Posts
    293

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Hello,

    now, I found a solution with "small icon"-view and align=top.
    I have to set the row height with the height of the images (Imagelist).
    Also I can control the number of columns by setting the column width with SetColumnWidth(0,x).

    Another possible solution was the report-view. There I can explicitly control the number and width of columns. But the selection of an item is to handle more difficult.

    thx.
    Ralf

  7. #7
    Join Date
    Jul 2001
    Posts
    293

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Hello,

    I am got one more problem:
    as you can imagine I use custom draw.
    I want to draw my whole "grid" in the CDDS_ITEMPREPAINT-Stage.
    But with
    CDC* pDC=CDC::FromHandle(lpcust->nmcd.hdc);
    I get a device context only for a part of the grid.
    I have no access to the whole grid.

    The same it is with GetItemRect: I do not get the whole grid.
    Any ideas?

    thx.
    Ralf

  8. #8
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,021

    Re: Control for owner-drawing items with 1 or 2 columns ?

    1. What means "the whole grid"?
    2. What means "a device context only for a part of the grid"?
    3. Why do you want to "draw your whole grid" in CDDS_ITEMPREPAINT stage, as long as it is designed for customizing an item?

    Let's try to clarify a little bit.
    1. You don't need the whole control area as long as you can get it with GetClientRect.
    2. The divice context got in NM_CUSTOMDRAW, is control's device context (listview in our case); in Windows there's no such stuff like item DC or "only for a part of..." DC.
    3. In CDDS_ITEMPREPAINT stage, draw item-specific stuff. Put other additional drawing (for the whole control) in CDDS_POSTPAINT stage.


    Here is an example which I think is what you need:
    Code:
    void CDemoDialog::OnNMCustomdrawList(NMHDR *pNMHDR, LRESULT *pResult)
    {
        LPNMLVCUSTOMDRAW pNMCD = (LPNMLVCUSTOMDRAW)pNMHDR;
        *pResult = CDRF_DODEFAULT;
    
        switch(pNMCD->nmcd.dwDrawStage)
        {
        case CDDS_PREPAINT:
            *pResult |= CDRF_NOTIFYITEMDRAW;   // request item-paint notifications
            *pResult |= CDRF_NOTIFYPOSTPAINT;  // request post-paint notifications
            break;
    
        case CDDS_ITEMPREPAINT:
            {
                CRect rcItem(pNMCD->nmcd.rc);                // item rectangle
                DWORD dwItem = pNMCD->nmcd.dwItemSpec;       // item index
                CDC* pDC = CDC::FromHandle(pNMCD->nmcd.hdc); // listview DC
                /////////////////////////////////////////////////////////
                /// Item custom drawing here...
                /////////////////////////////////////////////////////////
            }
            *pResult |= CDRF_SKIPDEFAULT; // no further default drawing
            break;
    
        case CDDS_POSTPAINT:
            {
                CWnd* pWndList = CWnd::FromHandle(pNMCD->nmcd.hdr.hwndFrom);
                CRect rc;
                pWndList->GetClientRect(rc); // listview client area
                CDC* pDC = CDC::FromHandle(pNMCD->nmcd.hdc); // listview DC
                /////////////////////////////////////////////////////////
                /// Additional listview control custom drawing here...
                /////////////////////////////////////////////////////////
            }
            break;
        }
    }
    Note: The control has "Icon" (LVS_ICON) style and has attached a "dummy" image list, only for sizing the items.

    See also:
    Last edited by ovidiucucu; January 25th, 2014 at 09:20 AM.
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  9. #9
    Join Date
    Jul 2001
    Posts
    293

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Quote Originally Posted by ovidiucucu View Post
    [*] The divice context got in NM_CUSTOMDRAW, is control's device context (listview in our case); in Windows there's no such stuff like item DC or "only for a part of..." DC.
    Hello,

    with "part of" I mean the DC is clipped to a part of the row/column that is to be drawn.
    Not to the whole row/column!

    I use Small-icon style, because with the (big) icon-style I can not define more than one column!

    I will check your code later. Maybe you can comment my answer anyway.
    thx.

    Ralf

  10. #10
    ovidiucucu's Avatar
    ovidiucucu is offline Moderator/Reviewer Power Poster
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,021

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Quote Originally Posted by Ralf Schneider View Post
    [...]
    Maybe you can comment my answer anyway.
    For sure I can.
    Quote Originally Posted by Ralf Schneider View Post
    I use Small-icon style, because with the (big) icon-style I can not define more than one column!
    It's not very clear for me what that means, just I can say that you can easily arrange the items yourself, in a more flexible manner.

    Example
    Code:
    void CFoo::ArrangeListItems(CListCtrl& listCtrl, UINT nColCount)
    {
        ASSERT((LVS_TYPEMASK & listCtrl.GetStyle()) == LVS_ICON);
    
        int nHorzSpacing = 0, nVertSpacing = 0;
        VERIFY(listCtrl.GetItemSpacing(FALSE, &nHorzSpacing, &nVertSpacing));
    
        const int nItemCount = listCtrl.GetItemCount();
        for(int nItem = 0; nItem < nItemCount; nItem++)
        {
            const int nRow = nItem / nColCount;
            const int nCol = nItem % nColCount;
            
            CPoint ptPos(nCol * nHorzSpacing, nRow * nVertSpacing);
            listCtrl.SetItemPosition(nItem, ptPos);
        }
    }
    Last edited by ovidiucucu; January 26th, 2014 at 11:22 AM.
    Ovidiu Cucu
    "When in Rome, do as Romans do."
    Visit: Microsoft Virtual Academy
    Follow: https://twitter.com/#!/ovidiucucu
    My blog: http://codexpert.ro/blog/author/ovidiu-cucu/

  11. #11
    Join Date
    Jul 2001
    Posts
    293

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Hello,

    ok, with SetIconSpacing I can define columns.

    But I have a problem with CDDS_ITEMPREPAINT in your first post.
    The rect CRect rcItem(pNMCD->nmcd.rc) always is a NullRect!!

    One more problem:
    (e.g. cell size 100x100 pixel)
    the area to click and select an item has only a height of about 22px, starting from the top of the item.

    Correction: I can avoid this, if I use SetImageList with dummy image(s).
    Is this necessary?

    thx.
    Last edited by Ralf Schneider; January 27th, 2014 at 08:24 AM.

  12. #12
    Join Date
    Jul 2001
    Posts
    293

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Hello,

    one more question.
    I want to show the selection even the control do not have the focus.
    The problem is that in this case the CDIS_SELECTED-bit is not set.

    Ok, then I set the style-bit LVS_SHOWSELALWAYS.
    The result: the CDIS_SELECTED-bit is set on every item!

    How can I determine the selected item??????????????
    thx.

  13. #13
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,782

    Re: Control for owner-drawing items with 1 or 2 columns ?

    Quote Originally Posted by Ralf Schneider View Post
    ok, with SetIconSpacing I can define columns.
    Em... no, you don't define columns...you define iconspacing.

    Columns will be a consequence of various other metrics which after calculations of all those metrics will end up with a number of columns that can fit on a single row.

    Some of those metrics you can provide in your code (like icon spacing)
    others are OS (or theme) defined (like control borders, inner padding, cell padding, cell borders)...
    a couple are user manageable through the control panel (size of scrollbars, font, DPI, scaling, ...)


    Your assumptions may not work:
    - if the user has a different flavour of windows (classic view or themed view)
    - if the user is using another theme
    - if the user has selected a different DPI setting for this screen (and/or enabled XP style DPI scaling)
    - if the user has selected a different systemfont
    - if the user is using some of the features for improving the OS for people with disabilities.
    - ...

    You cannot in any reliable way control "number of columns" on a listcontrol in iconview.
    The idea is that you give your control a certain width (which may get translated according to DPI settings).
    The OS will calculate how many columns fit in that width
    You deal with the number of columns the OS has given you.

  14. #14
    Join Date
    Jul 2001
    Posts
    293

    Re: Control for owner-drawing items with 1 or 2 columns ?

    ok, and what can I do to solve my problem?
    No solution with clistctrl?

  15. #15
    Join Date
    Apr 2000
    Location
    Belgium (Europe)
    Posts
    3,782

    Re: Control for owner-drawing items with 1 or 2 columns ?

    The closest would be a listctrl in report view with 2 actual columns, but then you can't really select a left/right item, you select the whole row at a time.

    You have a couple "weird" requirements that sort of exclude all the common controls unless you're prepared to accept the fact that your solution will only work under a specific set of assumptions. You can work around some of the inate issues with the common controls to make it work "better", but it'll Always have cases where it won't work right.

    Why does it HAVE to be side by side ?
    Why does it HAVE to be 2 ?
    Where does that requirement come from? Just because "their old program did it that way", doesn't mean it can't be done better another way.

    Often it's just better to accept the standard behaviour of the common controls and work with that, rather than trying to enforce a method into a control that wasn't designed with that method in mind.
    This is especially true in that users have their expectations on the behaviour on a UI element that visually looks like something they already know. Forcing a control to do something it's not suited for may give your users a continuous sensation that "something isn't quite right".


    That said, the common controls can't solve all real life problems, and sometimes you do need something that behaves "different" (the most Obvious lack in common controls is a "grid" or spreadsheet-like input). In that case, a custom control is the right way to go. Make it look sufficiently different from the common controls so users will see it's something different and not have expectations for it. (that doesn't mean it shouldn't operate in a logical/intuitive way).

    THe bad part of this is that a custom control can take quite a bit of work to make.
    THe good part is that there's a good chance someone has been there before you and you can find sources for the control you need (or something close enough that you can use it as a base) or premade libraries with what you need.

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  


Azure Activities Information Page

Windows Mobile Development Center


Click Here to Expand Forum to Full Width

This is a CodeGuru survey question.


Featured


HTML5 Development Center