【VBA×WindowsAPI】使用可能なフォント名をすべて列挙する

VBAでWindowsAPIを使っているとフォントを指定する場面に出くわすことがあります。そういった場合にフォント名を取得する必要が出てきますが、これもWindowsAPIで取得することができます。

フォントはグラフィックス デバイス インターフェイス(GDI)の一種でWindowsAPIではウィンドウに図形を描画する論理ペンや論理ブラシと同様のものとして扱われることが一般的です。

使用可能なフォント名をすべて列挙する

システム内にインストールされているフォントの名称はWindowsAPIのEnumFontFamiliesEx関数という関数で一括で取得することができます。この関数は引数に”関数”を入力する少し特殊な関数で、VBAで使用する場合はAddresOf演算子を使ってFunctionプロシージャを入力します。このような引数に関数を入力する関数をコールバック関数と呼び、EnumFontFamiliesEx関数に入力するコールバック関数はEnumFontFamExProcという名称を付けるのが一般的です。(VBAの場合は特に決まりなし)

VBAで使用可能なフォント名をすべて列挙するには下記のWindows APIを利用します。
それぞれ関数のより詳細な使い方の解説は各関数のリンクページを参照下さい。

icon-check-square EnumFontFamiliesEx関数 :システム内のフォントを列挙する
icon-check-square GetDC関数              :デバイスコンテキスト(DC)を取得する
icon-check-square ReleaseDC関数         :指定のDCを解放する

「そもそもWindows APIって何?」という方はコチラ(メインページ)も併せて参照下さい。

サンプルコード

システム内にインストールされているフォント名をイミディエイトウィンドウに列挙するサンプルコードは下記の通りです。出力と合わせてコレクションに文字列としてすべて格納もしています。

コード解説

icon-edit DCを取得/解放する

ウィンドウには描画関係の処理を行うためのデバイスコンテキスト(DC)というものが存在します。
このDCを介すことで、ウィンドウ内のピクセル情報を取得したり、図形の描画を行ったりすることが可能になります。DCを取得するにはまず対象のウィンドウのンドルを取得する必要があります。これはウィンドウを識別するためのID情報のようなもので、ハンドルを取得すれば”どの”ウィンドウに対して処理を行うのかを簡単に指示することができます。(Windows APIでは頻出ワードです)

EnumFontFamiliesEx関数では適当なDCを用意しておけばよいので、GetDC関数の引数を「0」で実行して画面全体のDCを取得します。ここで取得したDCは最終的にReleaseDC関数で解放する必要があるので注意が必要です。ReleaseDC関数もGetDC関数と同じく第1引数には「0」を入力し、第2引数には解放するDCを入力します。

icon-code GetDC関数 

hDc = GetDC(0)

icon-code RelaseDC関数 

Call ReleaseDC(0, hDc)

下記のフォント名取得後はどのタイミングで開放しても問題ありません。
 

icon-edit フォント名の取得

フォント名を列挙するにはEnumFontFamiliesEx関数を使って下記のように記載します。

icon-code EnumFontFamiliesEx関数 

Call EnumFontFamiliesEx(hDc, lpLogFont, AddressOf EnumFontFamExProc, 0, 0)

第1引数の「hWnd」には取得したDCを入力します。
第2引数の「lpLogFont」には文字セットを指定したLOGFONT構造体を入力します。構造体の「lfCharSet」の値を変更することで文字セットを指定することができ、取得するフォントが変化します。サンプルコードでは定数値としてANSIとShift-JIS、デフォルトの3種を用意していますがその他の文字セットも指定することが可能です。

第3引数にはコールバック関数として別途定義しているFunctionプロシージャのEnumFontFamExProc関数をAddresOf演算子とあわせて入力します。これにより、取得可能なフォントの数だけEnumFontFamExProc関数が繰り返し実行され、実行毎に取得できるフォントが順繰りに変化していきます。フォント名はEnumFontFamExProc関数の第1引数の「lpelfe」というLOGFONT構造体の「lfFaceName」内に格納されます。このときlfFaceName内の値はそのまま取得すると文字化けするのでStrConv関数でUnicodeに変換する必要があります。

第4,5引数は特に指定する必要が無いもののため「0」を入力して完了です。

関連情報

icon-share-square VBA×WindowsAPIまとめページ

その他のWindowsAPI関数は下記ページにまとまっているので合わせて参照下さい。

icon-share-square 参考

Microsoft公式:EnumFontFamiliesExW 関数 (wingdi.h) – Win32 apps
        EnumFontFamExProc callback function (Windows)

2024年3月2日Excel, VBA, Windows API

Posted by Lic