I am looking for a tutorial or maybe a sample program that shows how to compute the position of a control, given its caption and font size.

For an example, I do stuff like this:

Are you ...

[] female
[] male

"Are you ..." is a static control, "female" and "male" are radio buttons.

So far, I have assigned locations manually, e.g. put the "female" radio button at 25% of the screen height and the "male" radio button at 30% of the screen height. Which looks ugly because, to be on the safe side, I leave too much space between the radio buttons. There must be a better (more precise) way.

Win32 help mentions the GetTextExtentPoint32 function or the TEXTMETRIC structure, but they seem to handle things in "logical units" and depend on the "current mapping mode". I simply need the number of pixels. Any pointers to a working solution would be greatly appreciated.

Thank you

Posted on 2002-03-06 12:32:52 by Frank
How about GetDialogBaseUnits? or GetWindowRect... SetWindowPos... Remember a control(edit, radio buttons...) is just like a window, so don't be fooled by the names GetWindowRect that this belongs to a window only. It applies to all controls.
Posted on 2002-03-06 13:13:17 by stryker
After selecting a font into your DC (better prepare everything by using an IC), obtain the font's metrics by using GetTextMetrics. The height of one line of text should be tmHeight + tmExternalLeading. You could add a couple of pixels if you like it better. Store this value in a variable and use it to calculate rows. You could also use DrawText, this function returns the height of the text, so you could add it to your previous origin to get to the next line. If you don't mess with mapping modes, you can safely assume that logical units ARE pixels. If you use percentages of screen dimensions to position your text, you might get unexpected results with different screen resolutions.
Posted on 2002-03-06 18:03:09 by micmic

How about GetDialogBaseUnits? or GetWindowRect... SetWindowPos...

Right ... GetDialogBaseUnits seems to work only with the system font. GetWindowRect tells me how big my control is where I need to know how big (high) it should be. But thank you anyway, you got me started into the right direction. What I found in the Win32 programmer's reference is a formula that has helped:

For the MM_TEXT mapping mode, you can use the following formula to specify a height for a font with a given point size:
lfHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);

Given the font size (in points), the font height (in pixels) can be computed, and that is what I needed. E.g.,

CreateControls proc hWin:DWORD

LOCAL lineheight : DWORD

invoke GetDC, hWin
mov hdc, eax
invoke GetDeviceCaps,hdc,LOGPIXELSY ; returns pixels per inch in EAX
mov ecx, 12 ; ECX = desired font size (in points)
; change this value to experiment
mul ecx
xor edx, edx
mov ecx, 72
div ecx
mov lineheight, eax
invoke ReleaseDC, hWin, hdc

; do the actual creation of controls here


CreateControls endp

The lineheight value tells me the height that a control needs to have so that its caption "just fits" into it. So I can create a control of the minimal required height, and can further position the next control immediately below it.

See the appended sample application. It is tested on Win2000 with various screen resultions -- I hope it will also work at home on Win95.


Posted on 2002-03-06 18:25:00 by Frank
Don't get confused, for your purposes you don't need the point size. The point size is something completely different, and you should use only if you are interested in printing something with exact dimensions on the paper (1 point = 1/72 of an inch). In such a case, if you need a specific point size font, you would use the equation you mentioned, and then create a font by specifying a negative lfHeight value.
But if all you want is to be able to know the height of your font in pixels, then you just have to use CreateFont with a positive lfHeight value, and this value will be your font height in pixels. It's simple.
Posted on 2002-03-06 18:59:45 by micmic