-
May 30th, 2014, 09:40 PM
#1
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.
-
May 31st, 2014, 05:14 AM
#2
Re: Force OnMeasureItem() call on a ListBox
Did you try CListbox:SetItemHeight?
Victor Nijegorodov
-
May 31st, 2014, 09:39 PM
#3
Re: Force OnMeasureItem() call on a ListBox
Hi, Victor,
Originally Posted by VictorN
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.
-
June 1st, 2014, 02:52 AM
#4
Re: Force OnMeasureItem() call on a ListBox
Victor Nijegorodov
-
June 1st, 2014, 03:18 AM
#5
Re: Force OnMeasureItem() call on a ListBox
Hi, Victor,
Originally Posted by VictorN
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.
-
June 1st, 2014, 03:50 AM
#6
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
-
June 1st, 2014, 03:59 AM
#7
Re: Force OnMeasureItem() call on a ListBox
Hi,
Originally Posted by VictorN
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.
-
June 1st, 2014, 04:13 AM
#8
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.
-
June 1st, 2014, 04:25 AM
#9
Re: Force OnMeasureItem() call on a ListBox
Victor Nijegorodov
-
June 1st, 2014, 04:27 AM
#10
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
-
June 1st, 2014, 04:33 AM
#11
Re: Force OnMeasureItem() call on a ListBox
Hi,
Originally Posted by ovidiucucu
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.
-
June 1st, 2014, 04:43 AM
#12
Re: Force OnMeasureItem() call on a ListBox
Hi,
Originally Posted by VictorN
You are talking MFC, I speak WinAPI ;-)
Did I reference a proper function above? Or maybe I can use GetTextMetrics()?
Thank you.
-
June 1st, 2014, 05:29 AM
#13
Re: Force OnMeasureItem() call on a ListBox
Originally Posted by OneEyeMan
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.
Originally Posted by OneEyeMan
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.
Originally Posted by OneEyeMan
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.
Originally Posted by OneEyeMan
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.
Originally Posted by OneEyeMan
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.
Originally Posted by OneEyeMan
[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?
Originally Posted by OneEyeMan
Originally Posted by ovidiucucu
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.
-
June 3rd, 2014, 05:34 AM
#14
Re: Force OnMeasureItem() call on a ListBox
Hi,
Originally Posted by ovidiucucu
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. ;-)
Originally Posted by ovidiucucu
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.
-
June 5th, 2014, 10:03 AM
#15
Re: Force OnMeasureItem() call on a ListBox
Originally Posted by OneEyeMan
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;
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|