News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

GetLogFont

Started by jj2007, May 03, 2013, 10:04:19 AM

Previous topic - Next topic

jj2007

There was an old thread here 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:
; 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

dedndave

what control are you trying to get the font for ?

jj2007

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

dedndave

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

jj2007

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...

dedndave

still makes no sense - lol

qWord

why are you replacing the font object with a 1:1 copy of it self?

EDIT: OK, I ignored the ChooseFont()
MREAL macros - when you need floating point arithmetic while assembling!

jj2007


ragdog

Hi jochen

what is this for macros?

ClearLocalVariables uses edi esi
usedeb=0
PopUses


greets,

jj2007

Hi ragdog,
For ClearLocalVariables/PopUses see here.

usedeb=0 deactivates all deb 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...).

ragdog