AutoHotkey Community

It is currently May 26th, 2012, 10:17 pm

All times are UTC [ DST ]




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: August 23rd, 2005, 12:11 am 
Offline

Joined: September 24th, 2004, 3:00 pm
Posts: 814
Location: Germany
Hi,

does anyone know, how I can get the common choosefont-dialog into a ahk-script? I tried it with

Code:
DllCall("COMDLG32.DLL\ChooseFontA")


but that does not work, because there are some parameteres needed. I don't know how to translate the docs to a dllcall.

Or is there another way to let a user choose the font inside the gui? I just need fontface, style and size. Is the registry (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts) a reliable source for the installed fonts?

Tekl


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 23rd, 2005, 5:03 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
I'm glad you asked because I've been meaning to try this but have been procrastinating. Below is a script that seems to work but probably needs some refinement. It displays the following dialog:

Image
Code:
Gui, Add, Button, Default gButtonSelectFont, Press this to show font-picker dialog
Gui, Add, Text, w60 right, Font face:
Gui, Add, Edit, x+10 ReadOnly vFontFace
Gui, Add, Text, w60 right xm, Font size:
Gui, Add, Edit, x+10 ReadOnly vFontSize
Gui, Add, Text, w60 right xm, RGB Color:
Gui, Add, Edit, x+10 ReadOnly vColor

; Most of the setup for the font picker dialog needs to be done only once,
; which is why this section is here rather than in the button's subroutine.
SizeOfStructForChooseFont = 60
OffsetToFontFaceName = 28
SizeOfFontFaceName = 32
SizeOfStructForLogFont := OffsetToFontFaceName + SizeOfFontFaceName
VarSetCapacity(StructForChooseFont, SizeOfStructForChooseFont, 0)
VarSetCapacity(StructForLogFont, SizeOfStructForLogFont)  ; No need to zero it.
InsertInteger(SizeOfStructForChooseFont, StructForChooseFont, 0)  ; DWORD lStructSize
Gui, +LastFound
GuiHWND := WinExist()  ; Relies on the line above to get the unique ID of GUI window.
InsertInteger(GuiHWND, StructForChooseFont, 4)  ; HWND hwndOwner (makes dialog "modal").
InsertInteger(&StructForLogFont, StructForChooseFont, 12)  ; LPLOGFONT lpLogFont
InsertInteger(0x101, StructForChooseFont, 20)
; Above is DWORD Flags: CF_EFFECTS = 0x100, CF_SCREENFONTS = 1 (omit printer fonts)

Gui, Show
return

ButtonSelectFont:
if not DllCall("comdlg32\ChooseFontA", str, StructForChooseFont)  ; Display the dialog.
   return  ; The user canceled the dialog.
; Otherwise, the user pressed OK in the dialog, so determine what was selected.
VarSetCapacity(FontFace, SizeOfFontFaceName)
DllCall("RtlMoveMemory", str, FontFace, Uint, &StructForLogFont + OffsetToFontFaceName, Uint, SizeOfFontFaceName)
GuiControl,, FontFace, %FontFace%
GuiControl,, FontSize, % ExtractInteger(StructForChooseFont, 16) // 10
SetFormat, integer, hex  ; Show RGB color extracted below in hex format.
GuiControl,, Color, % BGRtoRGB(ExtractInteger(StructForChooseFont, 24))
SetFormat, integer, d
return

GuiClose:
ExitApp

ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; See DllCall documentation for details.
{
   SourceAddress := &pSource + pOffset  ; Get address and apply the caller's offset.
   result := 0  ; Init prior to accumulation in the loop.
   Loop %pSize%  ; For each byte in the integer:
   {
      result := result | (*SourceAddress << 8 * (A_Index - 1))  ; Build the integer from its bytes.
      SourceAddress += 1  ; Move on to the next byte.
   }
   if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
      return result  ; Signed vs. unsigned doesn't matter in these cases.
   ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
   return -(0xFFFFFFFF - result + 1)
}

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; To preserve any existing contents in pDest, only pSize number of bytes starting at
; pOffset are altered in it. The caller must ensure that pDest has sufficient capacity.
{
   mask := 0xFF  ; This serves to isolate each byte, one by one.
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
   {
      DllCall("RtlFillMemory", UInt, &pDest + pOffset + A_Index - 1, UInt, 1  ; Write one byte.
         , UChar, (pInteger & mask) >> 8 * (A_Index - 1))  ; This line is auto-merged with above at load-time.
      mask := mask << 8  ; Set it up for isolation of the next byte.
   }
}

BGRtoRGB(pColorBGR)
; This can also convert in the opposite direction, just give it an RGB color instead.
{
   return (pColorBGR & 0xFF) << 16 | ((pColorBGR >> 8) & 0xFF) | (pColorBGR >> 16)
}


I think the following color picker dialog could be displayed using a technique similar to above, but I haven't tried it yet:

Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 23rd, 2005, 10:09 am 
Offline

Joined: September 24th, 2004, 3:00 pm
Posts: 814
Location: Germany
Hi Chris,

thanks, that's a good base. In the meantime I tried it with the registry-entries like this:

Code:
   Loop, HKEY_LOCAL_MACHINE, SOFTWARE\Microsoft\Windows NT\CurrentVersion\Fonts, 0 ,0
   {
      StringGetPos, tempPos, A_LoopRegname, (
      If tempPos > 2
         StringLeft, LoopRegname, A_LoopRegname, % tempPos-1
      Else
         LoopRegname = %LoopRegname%
      AllFonts = %LoopRegname%|%AllFonts%
   }
...
; The GUI-Part
   Gui, Add, Text, xs+10 y+30, %lng_Font%
   Gui, Add, ComboBox, x+5 yp-3 w300 vFont gsub_ChangeFont, %AllFonts%
   Gui, Add, Text, x+10 yp+3, %lng_FontSize%
   Gui, Add, ComboBox, x+5 yp-3 w50 vFontSize gsub_ChangeFont, 8|9|10|11|12|14|16|18|20|24|36|48
   GuiControl,ChooseString, Font, %Font%
   GuiControl,ChooseString, FontSize, %FontSize%
...
;The result is used like this
   Gui, Font,s%FontSize%,%Font%

Interesting, that Names like "Arial Bold" also work directly and not only via Gui, Font, bold, Arial

For me, this way has some advantages. 1st It's less complicated, 2nd Less code and 3rd With the g-Label it's possible to change the font immediatly

Tekl


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: August 23rd, 2005, 11:59 am 
Offline

Joined: March 2nd, 2004, 3:36 pm
Posts: 10720
Thanks for posting your registry approach. Anyone wishing a GUI way to select a font will now have two scripts from which to choose.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 28th, 2006, 9:32 pm 
Offline

Joined: January 31st, 2005, 9:50 am
Posts: 3910
Location: Bremen, Germany
Do other options besides CF_EFFECTS or CF_SCREENFONTS exist for the dialog?

_________________
Ciao
toralf
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 29th, 2006, 12:50 pm 
Offline

Joined: December 27th, 2005, 1:46 pm
Posts: 6837
Location: France (near Paris)
http://msdn2.microsoft.com/en-us/library/ms646914.aspx
http://msdn2.microsoft.com/en-us/library/ms646832.aspx

_________________
Image vPhiLho := RegExReplace("Philippe Lhoste", "^(\w{3})\w*\s+\b(\w{3})\w*$", "$1$2")


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: November 29th, 2006, 1:03 pm 
Offline

Joined: May 24th, 2006, 2:49 pm
Posts: 4511
Location: Belgrade
This should be function.

The one for the standard library.

_________________
Image


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 21st, 2007, 7:33 pm 
Offline

Joined: December 4th, 2006, 10:35 am
Posts: 561
Location: Galil, Israel
Seemed to be missing return of the font type: Bold, Italics, etc..


this basically works:

Code:
FType :=  ExtractInteger(StructForChooseFont, 49,0,2) & 0x07 FontType := (Ftype = 4) ? "Norm" : (Ftype = 3) ? "bold italic" : (Ftype = 2) ? "italic" : (Ftype = 1) ? "bold" : ""




and (hopefully maybe when more time allows, will come back and update), here is the very cool Select Font as a function if might be helpful for 'beginners' to clip and use:

Code:
fontselect(Font, Options)
msgbox Font: %font%`n%Options%
exitapp

FontSelect( byref Font,byref Options, x = "", y = ""){
if (!x) and (!y)
    NOGUI
   
SizeOfStructForChooseFont = 60
OffsetToFontFaceName = 28
SizeOfFontFaceName = 32
SizeOfStructForLogFont := OffsetToFontFaceName + SizeOfFontFaceName
VarSetCapacity(StructForChooseFont, SizeOfStructForChooseFont, 0)
VarSetCapacity(StructForLogFont, SizeOfStructForLogFont)  ; No need to zero it.
InsertInteger(SizeOfStructForChooseFont, StructForChooseFont, 0)  ; DWORD lStructSize
if !NOGUI
       gui show, x%x%  y%y%
Gui, +LastFound
GuiHWND := WinExist()  ; Relies on the line above to get the unique ID of GUI window.
InsertInteger(GuiHWND, StructForChooseFont, 4)  ; HWND hwndOwner (makes dialog "modal").
InsertInteger(&StructForLogFont, StructForChooseFont, 12)  ; LPLOGFONT lpLogFont
InsertInteger(0x101, StructForChooseFont, 20)
; Above is DWORD Flags: CF_EFFECTS = 0x100, CF_SCREENFONTS = 1 (omit printer fonts)


;ButtonSelectFont:

if not DllCall("comdlg32\ChooseFontA", str, StructForChooseFont) {  ; Display the dialog.
                if !NOGUI
               gui, destroy
   return  ; The user canceled the dialog.
} ; Otherwise, the user pressed OK in the dialog, so determine what was selected.
if !NOGUI
            gui, destroy
VarSetCapacity(FontFace, SizeOfFontFaceName)
DllCall("RtlMoveMemory", str, FontFace, Uint, &StructForLogFont + OffsetToFontFaceName, Uint, SizeOfFontFaceName)
; FontFace .
fontsize :=  ExtractInteger(StructForChooseFont, 16) // 10

SetFormat, integer, hex
Fontcolor :=   BGRtoRGB(ExtractInteger(StructForChooseFont, 24))SetFormat, integer, D

FType :=  ExtractInteger(StructForChooseFont, 49,0,2) & 0x07 ; ExtractInteger(StructForChooseFont, 48,0,2) > 8 & 0x0f
FontType := (Ftype = 4) ? "Norm" : (Ftype = 3) ? "bold italic" : (Ftype = 2) ? "italic" : (Ftype = 1) ? "bold" : ""



Font := FontFace
if fontsize
   Options .= "S" . fontsize
if FontColor {
   SetFormat, integer, hex  ; Show RGB color extracted below in hex format.
   Options .= " C" . FontColor
   SetFormat, integer, d
}
if FontType
   Options .= " " . FontType

return

}

ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; See DllCall documentation for details.
{
   SourceAddress := &pSource + pOffset  ; Get address and apply the caller's offset.
   result := 0  ; Init prior to accumulation in the loop.
   Loop %pSize%  ; For each byte in the integer:
   {
      result := result | (*SourceAddress << 8 * (A_Index - 1))  ; Build the integer from its bytes.
      SourceAddress += 1  ; Move on to the next byte.
   }
   if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
      return result  ; Signed vs. unsigned doesn't matter in these cases.
   ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
   return -(0xFFFFFFFF - result + 1)
}

InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; To preserve any existing contents in pDest, only pSize number of bytes starting at
; pOffset are altered in it. The caller must ensure that pDest has sufficient capacity.
{
   mask := 0xFF  ; This serves to isolate each byte, one by one.
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
   {
      DllCall("RtlFillMemory", UInt, &pDest + pOffset + A_Index - 1, UInt, 1  ; Write one byte.
         , UChar, (pInteger & mask) >> 8 * (A_Index - 1))  ; This line is auto-merged with above at load-time.
      mask := mask << 8  ; Set it up for isolation of the next byte.
   }
}

BGRtoRGB(oldValue)
{
  Value := (oldValue & 0x00ff00)
  Value += ((oldValue & 0xff0000) >> 16)
  Value += ((oldValue & 0x0000ff) << 16) 
  return Value
}





ok, first update.. and this is a working but still slightly incomplete function , simply have not been ably yet to come back back to polish off... It does (mostly) work... ,


Code:
FontSelect( byref Font,byref Options, byref StructForChooseFont , x = "300", y = "100") {



SizeOfStructForChooseFont = 60
OffsetToFontFaceName = 28
SizeOfFontFaceName = 32
SizeOfStructForLogFont := OffsetToFontFaceName + SizeOfFontFaceName
VarSetCapacity(StructForLogFont, SizeOfStructForLogFont)  ; No need to zero it.
if !StructForChooseFont {
   VarSetCapacity(StructForChooseFont, SizeOfStructForChooseFont, 0)
   InsertInteger(&StructForLogFont, StructForChooseFont, 12)  ; LPLOGFONT lpLogFont
   InsertInteger(SizeOfStructForChooseFont, StructForChooseFont, 0)  ; DWORD lStructSize
   InsertInteger(0x101, StructForChooseFont, 20)
; Above is DWORD Flags: CF_EFFECTS = 0x100, CF_SCREENFONTS = 1 (omit printer fonts)
}
; gui show, x%x%  y%y%
Gui, +LastFound
GuiHWND := WinExist()  ; Relies on the line above to get the unique ID of GUI window.
InsertInteger(GuiHWND, StructForChooseFont, 4)  ; HWND hwndOwner (makes dialog "modal").

;ButtonSelectFont:

if not DllCall("comdlg32\ChooseFontA", str, StructForChooseFont) {  ; Display the dialog.
;   gui, destroy
   return  ; The user canceled the dialog.
} ; Otherwise, the user pressed OK in the dialog, so determine what was selected.
;gui, destroy
VarSetCapacity(FontFace, SizeOfFontFaceName)
DllCall("RtlMoveMemory", str, FontFace, Uint, &StructForLogFont + OffsetToFontFaceName, Uint, SizeOfFontFaceName)
; FontFace .
regexmatch(Options,"( S\d++)",hasSize)
regexmatch(Options,"( C\s*0\s*[xX]\s*[0-9ABCDEFabcdef]++)",hasColor)
regexmatch(Options,"i)(Norm|bold italic|italic|bold)",hasType)
Options =

;;tooltip % ExtractInteger(StructForChooseFont, 16)  "`n" ExtractInteger(StructForChooseFont, 16) / 10
fontsize :=  ExtractInteger(StructForChooseFont, 16) // 10
SetFormat, integer, hex  ; Show RGB color extracted below in hex format.
Fontcolor :=   BGRtoRGB(ExtractInteger(StructForChooseFont, 24))
SetFormat, integer, d
;SetFormat, integer, hex
;tooltip % ExtractInteger(StructForChooseFont, 48,0,4) "`n" ExtractInteger(StructForChooseFont, 49,0,2) & 0x07 "`n" ExtractInteger(StructForChooseFont, 50,0,4) "`n"

FType :=  ExtractInteger(StructForChooseFont, 49,0,2) & 0x07 ; ExtractInteger(StructForChooseFont, 48,0,2) > 8 & 0x0f
FontType := (Ftype = 4) ? "Norm" : (Ftype = 3) ? "bold italic" : (Ftype = 2) ? "italic" : (Ftype = 1) ? "bold" : ""

;tooltip % Ftype "  " FontType

Font := FontFace
Options .= (fontsize) ? " S" . fontsize  : hasSize
if (FontColor != "") {
   SetFormat, integer, hex  ; Show RGB color extracted below in hex format.
   Options .= " C" . FontColor
   SetFormat, integer, d
} else
   Options .= hasColor
   
 
Options .= (FontType) ? " " . FontType : " " . hasType

return

}

_________________
Joyce Jamce


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 13th, 2011, 3:33 pm 
Offline

Joined: October 18th, 2006, 8:07 pm
Posts: 169
Tekl, I think your line 7 should be:

Code:
         LoopRegname = %A_LoopRegname%

Really useful - thanks!


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: April 13th, 2011, 3:54 pm 
Offline

Joined: October 18th, 2006, 8:07 pm
Posts: 169
p.s. I also added:
Code:
sort,allfonts,D| ;sort list alphabetically


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: AndyJenk, Google [Bot], hyper_, JSLover, Leef_me, patgenn123, rbrtryn, XstatyK and 71 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group