しばらく動きが無い様なので書き込んでみます。
.ttf 等から取得したいということですが、
多様な種類のフォントを対象にしたい場合
内部を自分で調べて行くのは無理があるので、
ここはそれとは別の考え方で取得してみます。
手法というか手順としては、
1:現時点でインストールされているフォント名一覧を取得
2:AddFontResource API 関数を使って任意のフォントファイルを一時的に追加する
3:一時的に追加した物を含む、現時点でインストールされているフォント名一覧を取得
4:1と3の一覧の差から指定したフォントファイル名のフォント名を割り出す
という感じです。
HSP にはフォント名の一覧を取得する命令は無い(と思う)ので自分で取得します。
しかしフォント名一覧を取得するためにはフォントの列挙をしますが、
HSP はそれをするのに必須なコールバック関数がありません。
これまでは自分で専用の機械語を埋め込んだり
それが出来るプラグインを別に入手して使用してきましたが、
幸い最近になって、それが手軽に実現できる素晴らしいモジュールを作られた方がいるので
今回はそれを使わせてもらって処理してみました。
性質上、他で偶然同じタイミングでフォントのインストールがあると
それも同時に取得してしまうかもしれません(未確認ですが)
ほぼ起こらない問題でしょうが心配ならば
数回実行して結果が安定なら確定とすると良いかもしれません。
一応使いやすいように無理やりモジュールにまとめてみました
以下モジュールとサンプルです。
// tds12 さんのコールバックモジュールを使用させていただきます
// http://hsp.tv/play/pforum.php?mode=all&num=62130
#ifndef _MODCLBK3B2_AS
#ifdef _MODCLBK3A1_AS
#undef _MODCLBK3A1_AS
#undef newclbk3
#undef clbkargprotect
#undef CLBKMODE_CDECL
#undef _newclbk3
#undef modclbk_term
#endif
#ifdef _MODCLBK3B2_AS
#undef clbk_getthisptr
#endif
#define global _MODCLBK3A1_AS
#define global _MODCLBK3B1_AS
#define global _MODCLBK3B2_AS
#define global _MODCLBK3B3_AS
#define global newclbk3(%1,%2 = 0,%3,%4 = 0) tmpclbklb@modclbk3b3=%3:%1=_newclbk3(%2,tmpclbklb@modclbk3b3,%4)
//新しい関数ポインタを取得する
// %1...関数ポインタを受け取る変数
// %2...引数の数
// %3...呼び出されるラベル
// %4...作成のモード(CLBKMODE)
#define global clbkargprotect(%1) lp@modclbk3b3=lparam:wp@modclbk3b3=wparam:dupptr args@modclbk3b3,lp@modclbk3b3,wp@modclbk3b3*4,4:dim %1,wp@modclbk3b3:memcpy %1,args@modclbk3b3,wp@modclbk3b3*4
//引数を取得する
// %1...引数を受け取るための変数
#module "modclbk3b2"
#define ctype uintbitshiftright(%1,%2) (((%1&$7fffffff)>>%2)|((1&(%1>>31))<<(31-%2)))
#uselib "msvcrt.dll"
#cfunc malloc "malloc" int
#func free "free" int
#uselib "kernel32.dll"
#func VirtualProtect "VirtualProtect" var,int,int,var
#cfunc LoadLibrary "LoadLibraryA" sptr
#cfunc GetProcAddress "GetProcAddress" int,sptr
#func FreeLibrary "FreeLibrary" int
#define global CLBKMODE_CDECL $00000001
// 呼び出し規約をcdeclに設定する
// 通常はthiscall(clbk_getthisptrを呼ばなければstdcall)で、CLBKMODE_CDECL定数を指定した時のみcdeclになります。
#defcfunc _newclbk3 int _argmax,var clbklb,int mode
// int _argmax ... 関数の引数の数
// var clbklb ... 呼び出すサブルーチンが入った変数
// int mode ... コールバック関数のモード(CLBKMODE_)
dim _x,1
mref ctx,68
ilb=0
memcpy ilb,clbklb,4,0,0
argmax = _argmax
if inited == 0{
inited = 1
dim ptrtable
ptrmax = 0
hcrt = LoadLibrary("msvcrt.dll")
ptrtomalloc = GetProcAddress(hcrt,"malloc")
ptrtofree = GetProcAddress(hcrt,"free")
thisptr = 0
}
code_callptr = lpeek(ctx,168 + 48)//
if argmax>0{
dim clbk,57
clbk(0) = $83ec8b55,$45c730ec,$000000fc,$f845c700
clbk(4) = $00000000,$00e045c7,$c7000000,$0000e445
clbk(8) = $45c70000,$000000ec,$d845c700,$00000000
clbk(12) = $8bd84d89,$e0c1f845,$4d8b5002,$83d1ffe0
clbk(16) = $458904c4,$f445c7d4,$00000000,$00dc45c7
clbk(20) = $c7000000,$0000f045,$45c70000,$000000e8
clbk(24) = $0c558d00,$8be85589,$4d8bd445,$c7088908
clbk(28) = $0001d045,$09eb0000,$83d0558b,$558901c2
clbk(32) = $f8458bd0,$7dd04539,$e84d8b1a,$8904c183
clbk(36) = $558be84d,$d4458bd0,$8be84d8b,$0c89fc49
clbk(40) = $8bd5eb90,$458bf455,$8b0289f8,$558bdc4d
clbk(44) = $681189d4,$00000000,$ffec458b,$04c483d0
clbk(48) = $8bf04d8b,$fc558911,$00e845c7,$8b000000
clbk(52) = $8b50d445,$d1ffe44d,$8b04c483,$e58bfc45
clbk(56) = $0000c25d
lpoke clbk,$10,argmax:lpoke clbk,$17,ptrtomalloc:lpoke clbk,$1e,ptrtofree
lpoke clbk,$25,code_callptr:lpoke clbk,$2c,varptr(thisptr)
lpoke clbk,$48,varptr(ctx) + 36:lpoke clbk,$4f,varptr(ctx) + 40
lpoke clbk,$56,varptr(ctx) + 784:lpoke clbk,$b4,ilb
if ((mode & $f) == CLBKMODE_CDECL) == 0:wpoke clbk,$e2,(argmax * 4) & $ffff
funcsize = 228
}
if argmax==0{
dim clbk,25
clbk(0) = $83ec8b55,$45c718ec,$000000fc,$f045c700
clbk(4) = $00000000,$00f845c7,$c7000000,$0000e845
clbk(8) = $45c70000,$000000f4,$ec45c700,$00000000
clbk(12) = $8bec4d89,$00c7f845,$00000000,$c7e84d8b
clbk(16) = $00000001,$00006800,$558b0000,$83d2fff0
clbk(20) = $458b04c4,$89088bf4,$458bfc4d,$5de58bfc
clbk(24) = $000000c3
lpoke clbk,$10,code_callptr:lpoke clbk,$17,varptr(ctx) + 36
lpoke clbk,$1e,varptr(ctx) + 40:lpoke clbk,$25,varptr(ctx) + 784
lpoke clbk,$2c,varptr(thisptr):lpoke clbk,$46,ilb
funcsize = 100
}
clbkptr = malloc(funcsize)
dupptr clbkfunc,clbkptr,funcsize,4
memcpy clbkfunc,clbk,funcsize
VirtualProtect clbkfunc,funcsize,$40,_x
ptrtable(ptrmax) = clbkptr
ptrmax++
return clbkptr
#defcfunc clbk_getthisptr
//Thisポインタを取得する。
//コールバックとして呼び出された直後に別変数へコピーしなければならない。
return thisptr
#deffunc modclbk_term onexit
repeat ptrmax
free ptrtable(cnt)
loop
if inited{
FreeLibrary hcrt
}
ptrmax = 0
return
#global
#endif
// インストールフォント一覧取得モジュール
// http://hsp.tv/play/pforum.php?mode=all&num=62130#65032
// の kanahiron さんの書き込みを参考に書き直した物
#module mod_enumfont
#uselib "gdi32.dll"
#func global EnumFontFamiliesEx "EnumFontFamiliesExA" sptr,sptr,sptr,sptr,sptr
// インストール済みのフォント名一覧を取得
#deffunc get_enumfont var fontlist, int charset,\
local pfunc, local lf, local num, local sep, local tmp, local name, local prm
// コールバックポインタ取得
newclbk3 pfunc, 4, *CALLBACK_EnumFontFamExProc
// フォント名列挙関数のパラメータに渡す LOGFONT 構造体を準備
sdim lf, 60 :poke lf, 23, charset
// コールバック処理内で使用する変数を準備
num = 0 ; 列挙数
sep = "\n" ; フォント名の区切り文字
fontlist = "" ; 書き込み先
tmp = "" ; フォント名のバックアップ
// フォント名列挙のコールバック開始
EnumFontFamiliesEx hdc, varptr(lf), pfunc, 0, 0
return num
// コールバック関数に見立てたラベル
*CALLBACK_EnumFontFamExProc
// コールバック関数のパラメータを取得
clbkargprotect prm
// パラメータからフォント名を取得
#if 01
dupptr name, prm + 28, 32, 2
#else
dupptr name, prm + 60, 64, 2
#endif
// フィルタリング
if peek(name) != '@' & name ! tmp { ; 横書き用でダブらないフォント名
if num > 0 :fontlist += sep
fontlist += name
num ++
}
tmp = name ; 次の判定のためにフォント名をバックアップ
return 1
#global
// 指定した2つの文字列の行要素を相殺し違いのみを取り出すモジュール
// 気分的に sqlele を使ってみるの巻き
#include "sqlele.hsp"
#module mod_strsymdif
// 2つの文字列から互いに固有の行を取得
#deffunc get_strsymdif var result, var s1, var s2, local num
sql_open ":memory:"
sql_q "create table tmp1(data text unique)" ; テーブル作成
sql_q "create table tmp2(data text unique)" ; テーブル作成
add_db "insert into tmp1 values('%s')", s1 ; s1 を一行ずつ全行追加
add_db "insert into tmp2 values('%s')", s2 ; s2 を一行ずつ全行追加
; tmp2 が含まれない tmp1 と、tmp1 が含まれない tmp2 を、結合した結果を result に受け取る
get_db "select data from tmp1 where data not in(select data from tmp2) union select data from tmp2 where data not in(select data from tmp1) order by data", result
num = stat
sql_close
return num
// ローカル命令 改行ごとにデータベーステーブルに追加
#deffunc local add_db str sql, var str_add, local idx, local stt, local tmp
repeat
getstr tmp, str_add, idx
stt = stat
idx += strsize
sql_q strf(sql, tmp)
if stt = 0 :break
loop
return
// ローカル命令 データベーステーブルからデータを取得し改行区切り文字列に仕立て直す
#deffunc local get_db str sql, var str_get, local num
str_get = ""
sql_q sql
num = stat
repeat num
if cnt > 0 :str_get += "\n"
str_get += sql_v("data")
sql_next
loop
return num
#global
// 指定したフォントファイル名のフォント名を取得するモジュール
// 一時的なインストール前後のフォントリストから推測する手法
#module mod_getfontname
// フォントを一時的に使えるようにするAPI
#uselib "gdi32.dll"
#func AddFontResource "AddFontResourceA" str
#func RemoveFontResource "RemoveFontResourceA" str
#define ANSI_CHARSET $00000000
#define DEFAULT_CHARSET $00000001
#define SHIFTJIS_CHARSET $00000080
#define CHARSET DEFAULT_CHARSET
// 一時的なフォントを追加前後のフォントリストの差からフォント名を取得する
// パラメータには フォント名を受け取る変数, 取得対象のフォントファイルのパス を渡す
#deffunc get_fontname var fontname, str path_fontfile, local fontlist1, local fontlist2
get_enumfont fontlist1, CHARSET ; はじめに実行時のインストールフォント一覧を取得
AddFontResource path_fontfile ; 任意のフォントを一時的にインストール
get_enumfont fontlist2, CHARSET ; 一時的にインストールした状態のフォント一覧を取得
RemoveFontResource path_fontfile ; 一時的にインストールしたフォントを取り除く
get_strsymdif fontname, fontlist1, fontlist2 ; 2つのフォントリストの重複を取り除いたものを取得
return stat
#global
// 以下サンプル
// フォントパス
fontpath = "font.ttf" ; ←ここに取得したいフォントファイルのパスを指定する
// 指定したフォントファイル名からフォント名を取得する
get_fontname fontname, fontpath
mes "フォント名 = " + fontname
mes "取得数 = " + stat
いい加減な作りでお恥ずかしいですが
こちらで試した限りではなんとか取得できている様です。
他にも、TrueType フォントだけで十分ならばこちらもどうぞ
http://zuzazann.boy.jp/wiki/index.php?get_font_info