Hi,

I'm having a problem with setting the right font height in a richedit control.

I call the FontDialog PROC below to choose the font size (and other things...)
this then saves the iPointSize for use later.

Then i call the SetupEditBoxFont PROC below to to set the CHARFORMAT of the richedit control,

The problem is that the size of the font is too small if i use the "correct" value of 72 when working out the height of the font-:

INVOKE GetDC,hWndRichEdit
push eax
INVOKE GetDeviceCaps,eax,LOGPIXELSY
INVOKE MulDiv,Height,eax,48 ;<------------ 72 doesnt work (fonts to small)
mov cfm.yHeight,eax
pop eax
INVOKE ReleaseDC,hWndRichEdit,eax

does anybody know what is wrong?

Regards,
Lennon.



FontDialog PROC hWnd:DWORD

LOCAL cf:CHOOSEFONT

mov cf.lStructSize,SIZEOF CHOOSEFONT
push hWnd
pop cf.hWndOwner
mov cf.lpLogFont,OFFSET LogFont
mov cf.Flags,CF_EFFECTS OR CF_SCREENFONTS OR CF_LIMITSIZE OR\
CF_FORCEFONTEXIST OR CF_INITTOLOGFONTSTRUCT
mov cf.hDC,0
mov cf.iPointSize,0
push Client_FontColour
pop cf.rgbColors
mov cf.lCustData,0
mov cf.lpfnHook,0
mov cf.lpTemplateName,0
mov cf.hInstance,0
mov cf.lpszStyle,0
mov cf.nFontType,0
mov cf.Alignment,0
mov cf.nSizeMin,8
mov cf.nSizeMax,28
INVOKE ChooseFont,ADDR cf

;save
mov eax,cf.iPointSize
mov Client_FontHeight,eax

mov eax,cf.rgbColors
mov Client_FontColour,eax

movzx eax,LogFont.lfCharSet
mov Client_FontCharSet,eax

xor eax,eax
.IF LogFont.lfItalic
or eax,CFM_ITALIC
.ENDIF
.IF LogFont.lfUnderline
or eax,CFM_UNDERLINE
.ENDIF
.IF LogFont.lfStrikeOut
or eax,CFM_STRIKEOUT
.ENDIF
.IF LogFont.lfWeight > 400
or eax,CFM_BOLD
.ENDIF
mov Client_FontEffects,eax

lea eax,LogFont.lfFaceName
INVOKE lstrcpy,OFFSET Client_szFontFaceName,eax
ret

FontDialog ENDP




SetupEditBoxFont PROC hWndRichEdit:DWORD,Colour:DWORD,Effects:DWORD,
Height:DWORD,CharSet:DWORD,szlpFontFaceName:DWORD

LOCAL cfm:CHARFORMAT

mov cfm.yOffset,0
mov cfm.bPitchAndFamily,DEFAULT_PITCH OR FF_DONTCARE

mov cfm.cbSize,SIZEOF cfm
mov cfm.dwMask,CFM_COLOR OR CFM_BOLD OR CFM_FACE OR CFM_ITALIC OR\
CFM_UNDERLINE OR CFM_STRIKEOUT OR CFM_SIZE OR CFM_CHARSET
mov eax,Effects
mov cfm.dwEffects,eax

INVOKE GetDC,hWndRichEdit
push eax
INVOKE GetDeviceCaps,eax,LOGPIXELSY
INVOKE MulDiv,Height,eax,48 ;<------------ 72 doesnt work (fonts to small)
mov cfm.yHeight,eax
pop eax
INVOKE ReleaseDC,hWndRichEdit,eax

mov eax,Colour
mov cfm.crTextColor,eax
mov eax,CharSet
mov cfm.bCharSet,al
lea eax,cfm.szFaceName
INVOKE lstrcpy,eax,szlpFontFaceName

INVOKE SendMessage,hWndRichEdit,EM_SETSEL,-1,-1
INVOKE SendMessage,hWndRichEdit,EM_SETCHARFORMAT,SCF_WORD OR SCF_SELECTION,ADDR cfm
ret

SetupEditBoxFont ENDP
Posted on 2003-10-15 09:39:57 by Lennon
Why don't you try using the desktop window instead of the richedit window? Perhaps the font size calculation is affected by the mapping mode of the richedit's DC (but I could be talking nonsense here)... :confused:
Posted on 2003-10-17 13:04:23 by QvasiModo
INVOKE MulDiv,Height,eax,48 ;<------------ 72 doesnt work
You select a line saying 72 doesnt work although the instruction contains 48!

48 may equal 72 but only if you specify it as a hex number with the "h" suffix, i.e. 48h. Without any suffix, 48=48 and not 72. Forgive me if I'm assuming the wrong thing.

And then I have no idea what your MulDiv proc is supposed to do with the supplied parameters.

Raymond
Posted on 2003-10-17 23:12:27 by Raymond
Hi,

Raymond, this is the formula from the sdk docs to specify the height for a font with a specified point size:-

nHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);

this is my asm version (can be done much better/faster but i want to get it working first)
Height has been set to the returned point size from choosefont) :-

INVOKE GetDC,hWndRichEdit
push eax
INVOKE GetDeviceCaps,eax,LOGPIXELSY
INVOKE MulDiv,Height,eax,48 ;<------------ 72 doesnt work (fonts to small)
mov cfm.yHeight,eax
pop eax
INVOKE ReleaseDC,hWndRichEdit,eax

what i am saying is (i thought i made it quite clear!) when i use the "correct" value of 72 the fonts are not the same size as the sample in choosefont, 48 is the value im using at the moment because i get the right size with it.

QvasiModo,

Do you mean i should try getting the main app windows DC instead of the richedit DC?

I've tried that...didnt make any difference :(

Regards,
Lennon.
Posted on 2003-10-18 06:30:23 by Lennon

QvasiModo,

Do you mean i should try getting the main app windows DC instead of the richedit DC?

I've tried that...didnt make any difference :(

Yep, I was talking nonsense then :)
Maybe this does the trick (or maybe I'm going for the world record of surreal posts :grin: ):


INVOKE GetDC,hWndRichEdit
push eax
INVOKE GetDeviceCaps,eax,LOGPIXELSY
INVOKE MulDiv,Height,eax,48 ;<------------ 72 doesnt work (fonts to small)
neg eax ;NOTE THIS!
mov cfm.yHeight,eax
pop eax
INVOKE ReleaseDC,hWndRichEdit,eax


EDIT: No, I'm confusing fonts with DIBs... :o

Here's a snippet to calculate the same thing... It worked for me :)


invoke GetDC,hwnd
push eax ;RDC
push hwnd ;RDC
invoke GetDeviceCaps,eax,LOGPIXELSY
xor edx,edx
mov ecx,10 ;font size
mul ecx
mov ecx,72
div ecx
mov lf.lfHeight,eax
call ReleaseDC
invoke CreateFontIndirect,offset lf
Posted on 2003-10-18 15:38:57 by QvasiModo
You should use 36 (72/2) a twip is exactly half the size of the size in CHOOSEFONT.iPointSize. Remember that CHOOSEFONT returns the height of the font in units of 1/10 of a point, CHARFORMAT requires twips which are 1/20 of a point so just use 36 instead of 72 when converting points and you should be alright.
Posted on 2003-10-18 15:47:55 by donkey
ARRRrrgggg

using 36 gives me fonts that are slightly smaller than the choosefont sample, and using your code QvasiModo i get fonts slightly too big!

It looks like it has nothing to do with the formula:

nHeight = -MulDiv(PointSize, GetDeviceCaps(hDC, LOGPIXELSY), 72);

the problem must be somewhere else like my choosefont code,

or maybe richedit is just being a *astard again...

i might give up and just leave it set at around 48, which seems to work perfectly on all 4 computers in the house!

thanks for the help again QvasiModo :alright:

Lennon.
Posted on 2003-10-18 17:06:54 by Lennon
This is my code for calculating font size, it has never failed me yet, it is the same as your pseudo code above:
CalcFontSize PROC FSIZE:DWORD

LOCAL hDC :DWORD
LOCAL hDesktop :DWORD

invoke GetDesktopWindow
mov hDesktop,eax
invoke GetDC,hDesktop
mov hDC,eax
invoke GetDeviceCaps,hDC,LOGPIXELSY
push eax
invoke ReleaseDC,hDesktop,hDC
pop eax
mul FSIZE
mov ecx,72
xor edx,edx
div ecx
neg eax
ret
CalcFontSize ENDP

To convert to twips you should only have to shl eax,1 on return. BTW when getting the LOGPIXELXY it will almost always return 96 as 96 dpi screens are all you are ever likely to see, but like you I prefer to make sure. But you can usually cut out everything up to pop eax and replace it with mov eax,96
Posted on 2003-10-18 17:14:22 by donkey
:alright:

you got it donkey!,

swapping your code for mine and adding "add eax,eax"
gives me the perfect font size...at last...now back to the problem of emoticons graphics inside a richedit control *sigh*

Thank you very much donkey.

Lennon.
Posted on 2003-10-18 18:10:42 by Lennon
You're welcome Lennon,

Glad I could help :)
Posted on 2003-10-18 19:16:02 by donkey