Listbox, small problem getting correct scroll width horizontally

Started by zemtex, April 12, 2012, 03:24:12 AM

Previous topic - Next topic

zemtex

Hi

I use LB_SETHORIZONTALEXTENT to change the scroll width to a "reasonable" size without much more thought than that. The question is how to effectively get the horizontal scroller to fit exactly the longest string in the listbox without too much complexity. Do I have to use a dc and measure string length in pixels to get this right?
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

dedndave

GetTextExtentPoint32
http://msdn.microsoft.com/en-us/library/dd144938%28v=vs.85%29.aspx

GetTextExtentExPoint
http://msdn.microsoft.com/en-us/library/dd144935%28v=vs.85%29.aspx

GetTextExtentPoint32 returns the size in logical units
SetMapMode - the default mode is MM_TEXT - in which case, logical units are the same as pixels
if the mapping mode has been changed, you may have to calculate
when you get the pixels required, you might add a couple for fudge factor   :P
there are a number of things that go into measuring true type fonts, etc
so - it may not always be precise

zemtex

Quote from: dedndave on April 12, 2012, 03:48:22 AM
GetTextExtentPoint32
http://msdn.microsoft.com/en-us/library/dd144938%28v=vs.85%29.aspx

GetTextExtentExPoint
http://msdn.microsoft.com/en-us/library/dd144935%28v=vs.85%29.aspx

GetTextExtentPoint32 returns the size in logical units
SetMapMode - the default mode is MM_TEXT - in which case, logical units are the same as pixels
if the mapping mode has been changed, you may have to calculate
when you get the pixels required, you might add a couple for fudge factor   :P
there are a number of things that go into measuring true type fonts, etc
so - it may not always be precise

Does this mean I have to set font to the font used in my resource template first just in case a different font is selected than the font used in the listbox?
Can you do an example code that I can put in the WM_INITDIALOG to initialize the horizontal scrollbar properly, assuming I have already filled it with strings.
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

dedndave

yes - it needs to be the same font and size
no - i don't have an example, but i could probably do one tomorrow   :P

it would be easier if i didn't have to write the whole thing
do you have anything i can use ?

zemtex


.ELSEIF uMsg==WM_INITDIALOG
; do not return true. return false here so that the system don't set default keyboard focus

; Set horizontal scroller extent
INVOKE SendDlgItemMessage, hwndDlg, IDC_LST1, LB_SETHORIZONTALEXTENT, 1000, 0

.ENDIF


This is just what I have, I put 1000 temporarily because it adds just about 2 screens horizontally. You don't have to code it for me, but if you know the code and it is simple, you can paste it if you want to. I can't paste the entire thing, I have it in a DLL, and the DLL is unfinished and very messy, I have tons of files here in the project. It would be better to just include the WM_INITDIALOG.
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

dedndave

i was hoping for a program attachment that i could modify - lol
let me see what i can do...

dedndave

i don't know why i am surprised that the OS doesn't take care of this automatically   :lol

ok - here is my first stab at it

a simple one...
i put 2 strings in the list
measure the length of each
and set the scroll bar extent to that of the longest one

it is obvious that the DC i am measuring in does not have the same font or size as the one the list box uses

so - there are a couple ways to go, here
1) if you are going to set the font that is used in the list box, anyways - you simply select the same font into the hDC before measuring
2) if you are going to use the font as is, you need to find a way to get the facename and size so it can be selected into the DC
i dunno if that is a GetSystemMetrics thing or a SystemParametersInfo thing
it could be the ms sans serif 8 that i specified in the resource   :P

that should be a reasonably simple task, either way

a slightly more difficult task is to keep track of which item in the list has the longest text extent
i think you could keep a single extent value stored
if a new item is added to the list, see if it is larger than the stored value, and, if it is, replace it and set the extend width
if an item is removed from the list - and it is the longest item - you have to run through the list to find the longest

another approach might be to keep track of the extent of all items
faster, but uses more memory

it depends on how many items you may have in the list, i suppose

question for you...
were you planning on subclassing the list box ?

zemtex

1: About "running through finding the longest string", some longer strings can be shorter pixelwise than a shorter string, unless you are using terminal fonts.
2: No I were not thinking of subclassing the listbox, I've subclassed edit controls and that's enough work as it is.
3: I guess I could make a good average and assume a good width instead of measuring everything precicely and keep a lookup table perhaps.
I have been puzzling with lego bricks all my life. I know how to do this. When Peter, at age 6 is competing with me, I find it extremely neccessary to show him that I can puzzle bricks better than him, because he is so damn talented that all that is called rational has gone haywire.

dedndave

we just need to select the corrent font object before we call GetTextExtentPoint32