CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 15 of 15
  1. #1
    Join Date
    Aug 2002
    Posts
    756

    Force OnMeasureItem() call on a ListBox

    Hi, ALL,
    I have a following situation.
    1. I know that OnMeasureItem() is called only once - when the control is created - according to MSDN.
    2. I'm trying to create a ListBox (not a ListCtrl!!!) and change the font on it. Unfortunately after calling SetFont(), OnMeasureItem() is not called and I end up with ugly looking screen.
    3. I found this, and saw that in reply #9 Alin gave an example. Unfortunately, it is for the ListCtrl, and not a ListBox.

    So, now, is there a working solution for a ListBox that does not involve re-creating control?
    Or maybe I can just simply call OnMeasureItem() myself?

    Thank you.

  2. #2
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: Force OnMeasureItem() call on a ListBox

    Did you try CListbox:SetItemHeight?
    Victor Nijegorodov

  3. #3
    Join Date
    Aug 2002
    Posts
    756

    Re: Force OnMeasureItem() call on a ListBox

    Hi, Victor,
    Quote Originally Posted by VictorN View Post
    Did you try CListbox:SetItemHeight?
    I presume this is MFC wrapper around this?
    On that link it says:

    Sets the height, in pixels, of items in a list box.
    So if I set the font of 20 points how do I calculate the proper height of the item? Or just use the bold font which have bigger height?

    Thank you.

  4. #4
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: Force OnMeasureItem() call on a ListBox

    Victor Nijegorodov

  5. #5
    Join Date
    Aug 2002
    Posts
    756

    Re: Force OnMeasureItem() call on a ListBox

    Hi, Victor,
    Quote Originally Posted by VictorN View Post
    The closest I see is this. But it says:

    computes the width and height of the specified string of text.
    I just need the height of the font. I don't really care about the string.

    Thank you.

    [EDIT]
    Also, I don't think it will work if I just want to make the current font bold.
    [/EDIT]
    Last edited by OneEyeMan; June 1st, 2014 at 03:21 AM.

  6. #6
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: Force OnMeasureItem() call on a ListBox

    You must first select the correct font in your DC before calling GetTextExtent. Then it will work!
    Victor Nijegorodov

  7. #7
    Join Date
    Aug 2002
    Posts
    756

    Re: Force OnMeasureItem() call on a ListBox

    Hi,
    Quote Originally Posted by VictorN View Post
    You must first select the correct font in your DC before calling GetTextExtent. Then it will work!
    OK. But is it the right WinAPI call I refer to?

    Thank you.

  8. #8
    Join Date
    Aug 2002
    Posts
    756

    Re: Force OnMeasureItem() call on a ListBox

    Also, maybe there is an easier API - GetTextMetrics().
    But MSDN does not say what it returns - points or pixels...

    Thank you.

    [EDIT]
    This is what I'm referring to.
    [/EDIT]
    Last edited by OneEyeMan; June 1st, 2014 at 04:17 AM.

  9. #9
    VictorN's Avatar
    VictorN is offline Super Moderator Power Poster
    Join Date
    Jan 2003
    Location
    Hanover Germany
    Posts
    20,398

    Re: Force OnMeasureItem() call on a ListBox

    Victor Nijegorodov

  10. #10
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,234

    Re: Force OnMeasureItem() call on a ListBox

    Do you really, really need an owner-draw listbox?
    If you simply want to change the font, simply call SetFont (for a non owner-draw listbox) and the items height will be automatically changed to fit the new font height.
    Last edited by ovidiucucu; June 1st, 2014 at 05:48 AM. Reason: typos
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  11. #11
    Join Date
    Aug 2002
    Posts
    756

    Re: Force OnMeasureItem() call on a ListBox

    Hi,
    Quote Originally Posted by ovidiucucu View Post
    Do you really, really need an owner-draw listbox?
    If you simply want to change the font, simply call SetFont (for a non owner-draw listbox) and the items height will be automatically changed to fit the hew font height.
    Unfortunately, yes.

    Thank you.

  12. #12
    Join Date
    Aug 2002
    Posts
    756

    Re: Force OnMeasureItem() call on a ListBox

    Hi,
    You are talking MFC, I speak WinAPI ;-)
    Did I reference a proper function above? Or maybe I can use GetTextMetrics()?

    Thank you.

  13. #13
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,234

    Re: Force OnMeasureItem() call on a ListBox

    Quote Originally Posted by OneEyeMan View Post
    1. I know that OnMeasureItem() is called only once - when the control is created - according to MSDN.
    True only for owner-draw controls with LBS_OWNERDRAWVARIABLE style not set. Otherwise, it is called each time an item is added or inserted.

    Quote Originally Posted by OneEyeMan View Post
    3. I found this, and saw that in reply #9 Alin gave an example. Unfortunately, it is for the ListCtrl, and not a ListBox.
    That's it! ListView and ListBox controls are very, very different controls.

    Quote Originally Posted by OneEyeMan View Post
    Or maybe I can just simply call OnMeasureItem() myself?
    If you want, you can do it, but with no results. OnMeasureItem handles WM_MEASUREITEM, which is sent by the system to control's parent for getting info about how to size items. If you directly call it, it does not help.

    Quote Originally Posted by OneEyeMan View Post
    You are talking MFC, I speak WinAPI ;-)
    MFC is just a lite C++ wrapper over WinAPI. Talking about CDC::GetTextExtent and ::GetTextExtentPoint32 should not be an understanding problem, at least not bigger than talking in American and British English.

    Quote Originally Posted by OneEyeMan View Post
    I just need the height of the font. I don't really care about the string.
    [...]
    If you don't really care about the string, just pass "I don't really care about the string" to GetTextExtent and get the returned height. You'll see it works. I mean, seriously.

    Quote Originally Posted by OneEyeMan View Post
    [EDIT]
    Also, I don't think it will work if I just want to make the current font bold.
    [/EDIT]
    Why don't you think that? Did you tried it and it didn't work?

    Quote Originally Posted by OneEyeMan View Post
    Quote Originally Posted by ovidiucucu View Post
    Do you really, really need an owner-draw listbox?
    If you simply want to change the font, simply call SetFont (for a non owner-draw listbox) and the items height will be automatically changed to fit the new font height.
    Unfortunately, yes.
    Well then, please give us detailed info about what you really want to accomplish.
    Last edited by ovidiucucu; June 1st, 2014 at 05:59 AM.
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

  14. #14
    Join Date
    Aug 2002
    Posts
    756

    Re: Force OnMeasureItem() call on a ListBox

    Hi,
    Quote Originally Posted by ovidiucucu View Post
    MFC is just a lite C++ wrapper over WinAPI. Talking about CDC::GetTextExtent and ::GetTextExtentPoint32 should not be an understanding problem, at least not bigger than talking in American and British English.
    The point is that I'm not sure if CDC::GetTextExtent and ::GetTextExtentPoint32() are the same thing, i.e. one is a direct wrapper around the other. ;-)

    Quote Originally Posted by ovidiucucu View Post
    If you don't really care about the string, just pass "I don't really care about the string" to GetTextExtent and get the returned height. You'll see it works. I mean, seriously.
    Well, I don't. In the list box I can have "123", "abc" and "Abrakadabra" as my strings. All I want to know is how do I change the font on the owner-drawn list box, making sure that the items will be painted (drawn) correctly. For that there is an OnMeasureItem()/WM_MEASUREITEM API call, that is done only once when the control is created. The problem is that there are 2 API calls: one is ::GetTextExtent() which gives the size of the string passed to the function, the other - ::GetTextMetrics(), which should return the information about the font itself.
    Now, I tried to call ::GetTextMetrics(), and pass lpTextMetrics.tmHeight as a parameter to LB_SETITEMHEIGHT as LPARAM, but it didn't work. So I guess my next move would be to try ::GetTextExtent{Point32}() and using that string you mentioned. ;-)

    Thank you.

  15. #15
    Join Date
    Feb 2003
    Location
    Iasi - Romania
    Posts
    8,234

    Re: Force OnMeasureItem() call on a ListBox

    Quote Originally Posted by OneEyeMan View Post
    The point is that I'm not sure if CDC::GetTextExtent and ::GetTextExtentPoint32() are the same thing, i.e. one is a direct wrapper around the other. ;-)
    To see what wraps whatever MFC method, just put a breakpont in the caller, run in debug mode, then step into (F11).
    In the particular case of CDC::GetTextExtent, you'll see something like this:
    Code:
    _AFXWIN_INLINE CSize CDC::GetTextExtent(const CString& str) const
        {
            ASSERT(m_hAttribDC != NULL);
            SIZE size;
            VERIFY(::GetTextExtentPoint32(m_hAttribDC, str, (int)str.GetLength(), &size));
            return size;
        }
    Ovidiu
    "When in Rome, do as Romans do."
    My latest articles: https://codexpertro.wordpress.com/

Posting Permissions

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





Click Here to Expand Forum to Full Width

Featured