The MASM Forum

General => The Workshop => Topic started by: jj2007 on May 03, 2013, 10:04:19 AM

Title: GetLogFont
Post by: jj2007 on May 03, 2013, 10:04:19 AM
There was an old thread here (http://www.masmforum.com/board/index.php?topic=18730.0) where Dave & myself tried to implement "GetLogFont" in Masm32.

It turns out the approach was slightly flawed. Here is an algo that works. It takes a control handle and the address of an existing font handle.

The tricky point was that we had tried to use GetCurrentObject, hCtrl, OBJ_FONT to get the current logfont. But apparently Windows unselects the control's font on EndPaint, so in order to get the logfont, you need to select it first. Oops :(

There is a chance that it works also directly with GetObject, hFont, LOGFONT, addr MyLogFont, but I haven't tested that yet.

; CodeGuru: (http://forums.codeguru.com/showthread.php?510521-Current-window-font)
; GetCurrentObject(hDC, OBJ_FONT) retrieves the font currently selected in a device context, which is a different stuff.
; If no font was previously selected in DC by a call of SelectObject, then fially you'll get the system font.

MbFnt proc hCtrl, pHFont        ; handle to control, address of global font handle
LOCAL MbCF:CHOOSEFONTW, MbLF:LOGFONTW
ClearLocalVariables uses edi esi
  mov esi, hCtrl
  usedeb=0
  m2m MbCF.lStructSize, CHOOSEFONT
  inc MbCF.Flags                        ; mov CF_SCREENFONTS=1 ; no CF_EFFECTS
  invoke GetDC, esi
  push eax                                ; arg for ReleaseDC
  push OBJ_FONT
  push eax
  mov edi, pHFont
  invoke SelectObject, eax, [edi]
  call GetCurrentObject        ; invoke GetCurrentObject, eax, OBJ_FONT
  lea edx, MbLF
  mov MbCF.lpLogFont, edx
  invoke GetObject, eax, LOGFONT, edx
  push esi
  call ReleaseDC
  invoke ChooseFontW, addr MbCF
  .if eax
        invoke DeleteObject, [edi]
        invoke CreateFontIndirectW, MbCF.lpLogFont
        .if eax
                mov [edi], eax
                sm esi, WM_SETFONT, eax, 1
        .endif
  .endif
  PopUses
  ret
MbFnt endp
Title: Re: GetLogFont
Post by: dedndave on May 03, 2013, 10:29:12 PM
what control are you trying to get the font for ?
Title: Re: GetLogFont
Post by: jj2007 on May 03, 2013, 11:11:48 PM
The edit control only. By the way, it works now, here is the final version, 93 bytes short:

MbFnt proc hCtrl, pHFont                ; handle to control, address of global font handle
LOCAL MbCF:CHOOSEFONT, MbLF:LOGFONT
  ClearLocalVariables                ; any other routine to zero the locals will do
  m2m MbCF.lStructSize, CHOOSEFONT
  m2m MbCF.Flags, CF_INITTOLOGFONTSTRUCT or CF_SCREENFONTS
  lea edx, MbLF
  mov MbCF.lpLogFont, edx
  push edi
  mov edi, pHFont
  invoke GetObject, [edi], LOGFONT, edx
  invoke ChooseFont, addr MbCF
  .if eax
        invoke DeleteObject, [edi]
        invoke CreateFontIndirect, MbCF.lpLogFont
        .if eax
                mov [edi], eax
                invoke SendMessage, hCtrl, WM_SETFONT, eax, 1
        .endif
  .endif
  pop edi
  ret
MbFnt endp
Title: Re: GetLogFont
Post by: dedndave on May 04, 2013, 01:41:11 AM
i don't understand   :P

the global font handle, [pHFont], already has a font handle in it ?
you reference it with GetObject, but i'm not sure what you are getting the LOGFONT object of
Title: Re: GetLogFont
Post by: jj2007 on May 04, 2013, 02:06:31 AM
Quote from: dedndave on May 04, 2013, 01:41:11 AM
i don't understand   :P

the global font handle, [pHFont], already has a font handle in it ?

Yes, exactly.

Quoteyou reference it with GetObject, but i'm not sure what you are getting the LOGFONT object of

The object is the font represented by its handle.

In any case, it works perfectly, tested on XP and W7-32. You can set the font multiple times, and the dialog shows the already selected font, so everything is fine. See attachment...
Title: Re: GetLogFont
Post by: dedndave on May 04, 2013, 02:20:39 AM
still makes no sense - lol
Title: Re: GetLogFont
Post by: qWord on May 04, 2013, 02:39:45 AM
why are you replacing the font object with a 1:1 copy of it self?

EDIT: OK, I ignored the ChooseFont()
Title: Re: GetLogFont
Post by: jj2007 on May 04, 2013, 03:29:20 AM
Quote from: dedndave on May 04, 2013, 02:20:39 AM
still makes no sense - lol

Which part?
Title: Re: GetLogFont
Post by: ragdog on May 04, 2013, 03:55:28 AM
Hi jochen

what is this for macros?

ClearLocalVariables uses edi esi
usedeb=0
PopUses


greets,
Title: Re: GetLogFont
Post by: jj2007 on May 04, 2013, 04:14:58 AM
Hi ragdog,
For ClearLocalVariables/PopUses see here (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1151).

usedeb=0 deactivates all deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) uses below that line. Some of my sources are full of debugging code, more useful than comments sometimes, and usedeb=0 is an easy way to just switch them off (or on, if needed), so that no code is generated (one "deb" costs several hundred bytes...).
Title: Re: GetLogFont
Post by: ragdog on May 05, 2013, 03:25:27 AM
Nice and thanks