 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
Tekl
Joined: 24 Sep 2004 Posts: 814 Location: Germany
|
Posted: Tue Aug 23, 2005 12:11 am Post subject: How to call the standard Choose-Font-dialog? |
|
|
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 |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10667
|
Posted: Tue Aug 23, 2005 5:03 am Post subject: |
|
|
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:
| 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:
 |
|
| Back to top |
|
 |
Tekl
Joined: 24 Sep 2004 Posts: 814 Location: Germany
|
Posted: Tue Aug 23, 2005 10:09 am Post subject: |
|
|
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 |
|
| Back to top |
|
 |
Chris Site Admin
Joined: 02 Mar 2004 Posts: 10667
|
Posted: Tue Aug 23, 2005 11:59 am Post subject: |
|
|
| Thanks for posting your registry approach. Anyone wishing a GUI way to select a font will now have two scripts from which to choose. |
|
| Back to top |
|
 |
toralf
Joined: 31 Jan 2005 Posts: 3906 Location: Bremen, Germany
|
Posted: Tue Nov 28, 2006 9:32 pm Post subject: |
|
|
Do other options besides CF_EFFECTS or CF_SCREENFONTS exist for the dialog? _________________ Ciao
toralf  |
|
| Back to top |
|
 |
PhiLho
Joined: 27 Dec 2005 Posts: 6723 Location: France (near Paris)
|
|
| Back to top |
|
 |
majkinetor
Joined: 24 May 2006 Posts: 4114 Location: Belgrade
|
Posted: Wed Nov 29, 2006 1:03 pm Post subject: |
|
|
This should be function.
The one for the standard library. _________________
 |
|
| Back to top |
|
 |
Joy2DWorld
Joined: 04 Dec 2006 Posts: 537 Location: Galil, Israel
|
Posted: Sat Apr 21, 2007 7:33 pm Post subject: |
|
|
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 |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|