May 09, 2024, 05:50:30 PM

News:

IonicWind Snippit Manager 2.xx Released!  Install it on a memory stick and take it with you!  With or without IWBasic!


Getting Existing Font of Window/Control

Started by LarryMc, August 14, 2008, 09:06:29 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

LarryMc

Working on a program where user can change the fonts of controls.

I need to be able to obtain the same info that is returned by the FONTREQUEST command in order to see their changes.

I have found that using API GetTextMetrics with the TEXTMETRIC structure I can almost get there.

The only thing that is not straightforward is the height.

If I set a font size to 20 I get a number back like 24
A 40 gets me 54.

Also using GETTEXTSIZE 40 will get me a 54.

I suspect that a variation of this might have something to do with  the next step but I'm not sure:
-MulDiv(height,GetDeviceCaps(whdc,90 ),72)

Larry

LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

Larry,
Fonts are specified in points, 1 point = 1/72 of an inch.

logical units = -MulDiv(height, GetDeviceCaps(whdc,90 ),72)

or

pixels  = -( points *  pixels per inch Y) / 72 )

So GetDeviceCaps is returning the pixels per inch in the Y direction of the device.  Which is why it works for both printers and CRT's.

That formula is returning the height of the font in logical units (pixels) for a logfont UDT, which is where I am assuming you are getting it from.  A little math will get you back to the other direction, given a logical unit size...

lu*72 = height*ppiY
-(lu*72)/ppiY = height

So in the mapping mode used by Emergence windows (MM_TEXT) where 1 pixel = 1 logical unit you can assume that:

points = -((pixels * 72) /  GetDeviceCaps(whdc,90 ))

Assuming I solved correctly for height, a bit tired at the moment ;)
Ionic Wind Support Team

Ionic Wind Support Team

Of course an easier way would be to:

Send the control the WM_GETFONT message
Use the GetObject API functionto retrieve the LOGFONT udt from the font handle
and then lf.lfHeight is the pixels.

Paul.
Ionic Wind Support Team

LarryMc

Quote from: Paul Turley on August 14, 2008, 09:47:52 PM
Of course an easier way would be to:

Send the control the WM_GETFONT message
Use the GetObject API functionto retrieve the LOGFONT udt from the font handle
and then lf.lfHeight is the pixels.
I tried that for over 3 hours and never could get it to work.
That's why I was taking this route.
I'll start over with the logfont way.

This is the program I was using with gettextmetrics
declare "gdi32",GetTextColor(hdc:int),int
declare "gdi32",GetTextFaceA(hdc:int,nCount:int,lpFaceName:string),int
declare import, _GetTextMetrics alias GetTextMetricsA(hdc:INT, lpMetrics:TEXTMETRIC),INT
DECLARE "gdi32",GetDeviceCaps(hdc:INT, nIndex:INT),INT

TYPE TEXTMETRIC
DEF tmHeight:INT
DEF tmAscent:INT
DEF tmDescent:INT
DEF tmInternalLeading:INT
DEF tmExternalLeading:INT
DEF tmAveCharWidth:INT
DEF tmMaxCharWidth:INT
DEF tmWeight:INT
DEF tmOverhang:INT
DEF tmDigitizedAspectX:INT
DEF tmDigitizedAspectY:INT
DEF tmFirstChar:CHAR
DEF tmLastChar:CHAR
DEF tmDefaultChar:CHAR
DEF tmBreakChar:CHAR
DEF tmItalic:CHAR
DEF tmUnderlined:CHAR
DEF tmStruckOut:CHAR
DEF tmPitchAndFamily:CHAR
DEF tmCharSet:CHAR
ENDTYPE

TEXTMETRIC yy

openconsole
def w1:window

def fn:string
int h,fh
OPENWINDOW w1,0,0,10,10,@MINBOX,0,"Get Font Testr",&hnd

SETFONT w1, "Terminal", 20, 700, @SFITALIC | 0x00FF0000
print "SETFONT height ",20
h=gethdc(w1)
_GetTextMetrics(h, yy)
print " tmHeight (returned height) " ,yy.tmHeight
fh = ((yy.tmHeight * 72) /  GetDeviceCaps(h,90 ))
print "calc font height ",fh
if yy.tmItalic  = 0xff then print "Italic"
if yy.tmUnderlined  = 0xff then print "Underlined"
if yy.tmStruckOut  = 0xff then print "StruckOut"

frontpen w1,rgb(0,0,0)
GetTextFaceA(h,255,fn)
print GetTextColor(h)," ",fn
print
int tWidth, tHeight
GETTEXTSIZE w1, "Tell me", tWidth, tHeight
print "GETTEXTSIZE Height ", tHeight
releasehdc w1,h
waituntil w1=0
closeconsole
end
sub hnd
select @class
case @idclosewindow
closewindow w1
endselect
return
endsub




Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

DECLARE IMPORT,GetObjectA(hObject as UINT,cbSize as INT,pLog as POINTER),INT
DEF lf as LOGFONT

hfont = SendMessage(hControl, WM_GETFONT,0,0)

GetObjectA(hFont,LEN(LOGFONT),lf)

Of course you can also:

hfont = SendMessage(win, WM_GETFONT,0,0, control_id)

Paul.
Ionic Wind Support Team

LarryMc

eureka!


I was only one line away from getting it.

Thanks again Paul

BTW,
Am I correct in assuming that you can't resize rgnbuttons on the fly because of the bitmaps not being resized inside the control?

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

Yes you can resize them.  If you look at the code I use StretchBlt for the bitmaps if the size of the control is different from the size of the bitmap.
Ionic Wind Support Team

LarryMc

What I did with your rgn demo was changed the INITIAL size of the button and it didn't look correct. (1/2 a button etc)

Anyway, with my get font problem I thougt I had it, but no cigar.
I get a height of 0 with this.
DECLARE IMPORT,GetObjectA(hObject as UINT,cbSize as INT,pLog as POINTER),INT
openconsole
def w1:window
SETID "WM_GETFONT",0x31
uint hfont
DEF lf as LOGFONT

OPENWINDOW w1,0,0,10,10,@MINBOX,0,"Get Font Testr",&hnd
SETFONT w1, "Terminal", 20, 700, @SFITALIC | 0x00FF0000
print "SETFONT height ",20

hfont = SendMessage(w1,@WM_GETFONT,0,0)
print hfont
print GetObjectA(hFont,LEN(LOGFONT),lf)
print "returned height ",lf.lfHeight

waituntil w1=0
closeconsole
end
sub hnd
select @class
case @idclosewindow
closewindow w1
endselect
return
endsub

I know it's something stupid I'm doing wrong but I just can't see it.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

A regular window doesn't respond to WM_GETFONT, because windows don't have fonts only device contexts do.  Unless of course you code it to do so.  The handle to the windows font is directly accessible from the window UDT.

win.hfont

Which is where I store the font handle. Probably why you are confused because I do associate a font with the window, which is automatically set in the device context when you print, or use GetHDC.

If you are creating a custom control, from a window base, then it is a good idea to respond to WM_GETFONT by returning the primary font used by your control.  If you are using a subclassed button control then it already responds to the WM_GETFONT message correctly.

Paul.
Ionic Wind Support Team

Ionic Wind Support Team

And of course the requisite link to the description of WM_GETFONT.  Which can return NULL by the way.

http://msdn.microsoft.com/en-us/library/ms632624(VS.85).aspx
Ionic Wind Support Team

LarryMc

This works although there are rounding errors.
set font size to 10 and getfont gives you a 9
others around there don't have error.
DECLARE IMPORT,GetObjectA(hObject as UINT,cbSize as INT,pLog as POINTER),INT
DECLARE "gdi32",GetDeviceCaps(hdc:INT, nIndex:INT),INT
openconsole
def w1:window
SETID "WM_GETFONT",0x31
uint hfont
int fh
DEF lf as LOGFONT

OPENWINDOW w1,0,0,10,10,@MINBOX,0,"Get Font Testr",&hnd
CONTROL w1,@BUTTON,"",20,20,10,20,0x50008000,601
SETFONT w1, "Terminal", 12, 700, @SFITALIC | 0x00FF0000,601
print "SETFONT height ",12

hfont = SendMessage(w1,@WM_GETFONT,0,0,601)
print hfont
print GetObjectA(hFont,LEN(LOGFONT),lf)
print "returned height ",lf.lfHeight
h=gethdc(w1)
fh = -((lf.lfHeight * 72) /  GetDeviceCaps(h,90 ))
releasehdc w1,h
print "calc font height ",fh
waituntil w1=0
closeconsole
end
sub hnd
select @class
case @idclosewindow
closewindow w1
endselect
return
endsub


Thanks for bearing with me.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

Thats because "Terminal" is a bitmap font, and not a true type font.  It only exists in sizes 5, 6, 9, 12 and 14.  Also you can make your calculations a bit more accurate using:


-((lf.lfHeight * 72.0) /  GetDeviceCaps(h,90 ))

Othewise it is a pure integer division

Use Courier New, Arial or Lucida Console if you want a monospaced font in any size.

Paul.
Ionic Wind Support Team

LarryMc

Thanks again.
You never cease to amaze me.

Larry
LarryMc
Larry McCaughn :)
Author of IWB+, Custom Button Designer library, Custom Chart Designer library, Snippet Manager, IWGrid control library, LM_Image control library

Ionic Wind Support Team

Quote
What I did with your rgn demo was changed the INITIAL size of the button and it didn't look correct. (1/2 a button etc)

It only works if the button doesn't use a region, just the hot tracking and normal bitmaps.  Which is really just an oversight on my part, the code I was writing for my contract work needed scalable buttons, but they were not using regions to change the shape of the button...so I only added the stretchblt code in one place.

It's something I'll have to address in the next update.

Paul.
Ionic Wind Support Team