AddressOf 演算子
引数リストの特定の位置で関数ポインターを受け取る API プロシージャに対して、この演算子の後に指定されたプロシージャのアドレスを渡す単項演算子。
構文
AddressOfプロシージャ名
必須の procedurename には、アドレスを渡すプロシージャを指定します。 これは、呼び出しが行われるプロジェクトの標準モジュール内のプロシージャを表す必要があります。
注釈
プロシージャ名が引数リストに表示される場合、通常はプロシージャが評価され、プロシージャの戻り値のアドレスが渡されます。 AddressOf を使用すると、プロシージャの戻り値を渡すのではなく、 ダイナミック リンク ライブラリ (DLL) 内の Windows API 関数にプロシージャのアドレスを渡すことができます。 API 関数は、 アドレスを使用して、コールバックと呼ばれるプロセスである Basic プロシージャを呼び出すことができます。 AddressOf 演算子は、API プロシージャの呼び出しにのみ表示されます。
AddressOf を使用して Basic プロシージャ間でプロシージャのポインターを受け渡すこともできますが、Basic 内からそのポインターを使用して関数を呼び出すことはできません。 つまり、たとえば、Basic で記述された クラス は、このようなポインターを使用してそのコントローラーへのコールバックを行うことはできません。 AddressOf を使用して Basic 内のプロシージャ間でプロシージャのポインターを受け渡す場合、呼び出されるプロシージャの パラメーターの型は As Long と定義されている必要があります。
関数コールバックの概念について完全に理解しないまま AddressOf を使用した場合、予期しない結果が発生するおそれがあります。 コールバックの Basic 部分の動作、および関数アドレスを渡す先の DLL のコードについて理解しておく必要があります。 プログラムは 開発環境と同じプロセスで実行されるため、このような相互作用のデバッグは困難です。 通常の手順でのデバッグを実行できない場合もあります。
注:
Microsoft Visual C++ (または類似のツール) を使用して DLL をコンパイルし、独自のコールバック関数のプロトタイプを作成できます。 AddressOf を使用する場合、プロトタイプでは __stdcall 呼び出し規約を使用する必要があります。 既定の呼び出し規約 (__cdecl) では AddressOf が動作しません。
コールバックの呼び出し元がプログラム内にないため、コールバック プロシージャ内のエラーを呼び出し元に反映しないことが重要です。 コールバック プロシージャの先頭に On Error Resume Next ステートメントを記述することによって、このような伝達を防止できます。
例
次の例では、システム内のフォントをアルファベット順に並べ替えた一覧を含むリスト ボックスを持つフォームを作成しています。
この例を実行するには、リスト ボックスを持つフォームを作成します。 フォームのコードは次のとおりです。
Option Explicit
Private Sub Form_Load()
Module1.FillListWithFonts List1
End Sub
モジュールに次のコードを配置します。 EnumFontFamilies 関数の定義の 3 番目の引数は、プロシージャを表す Long です。 引数には、プロシージャから返される値ではなく、プロシージャのアドレスが含まれている必要があります。 EnumFontFamilies の呼び出しでは、3 番目の引数では 、AddressOf 演算子が EnumFontFamProc プロシージャのアドレスを返す必要があります。これは、Windows API 関数 EnumFontFamilies を呼び出すときに指定するコールバック プロシージャの名前です。 AddressOf EnumFontFamProc を EnumFontFamProc に渡すと、システム上のフォント ファミリごとに EnumFontFamProc が 1 回呼び出されます。 EnumFontFamilies に渡される最後の引数は、情報が表示されるリスト ボックスを指定します。
'Font enumeration types
Public Const LF_FACESIZE = 32
Public Const LF_FULLFACESIZE = 64
Type LOGFONT
lfHeight As Long
lfWidth As Long
lfEscapement As Long
lfOrientation As Long
lfWeight As Long
lfItalic As Byte
lfUnderline As Byte
lfStrikeOut As Byte
lfCharSet As Byte
lfOutPrecision As Byte
lfClipPrecision As Byte
lfQuality As Byte
lfPitchAndFamily As Byte
lfFaceName(LF_FACESIZE) As Byte
End Type
Type NEWTEXTMETRIC
tmHeight As Long
tmAscent As Long
tmDescent As Long
tmInternalLeading As Long
tmExternalLeading As Long
tmAveCharWidth As Long
tmMaxCharWidth As Long
tmWeight As Long
tmOverhang As Long
tmDigitizedAspectX As Long
tmDigitizedAspectY As Long
tmFirstChar As Byte
tmLastChar As Byte
tmDefaultChar As Byte
tmBreakChar As Byte
tmItalic As Byte
tmUnderlined As Byte
tmStruckOut As Byte
tmPitchAndFamily As Byte
tmCharSet As Byte
ntmFlags As Long
ntmSizeEM As Long
ntmCellHeight As Long
ntmAveWidth As Long
End Type
' ntmFlags field flags
Public Const NTM_REGULAR = &H40&
Public Const NTM_BOLD = &H20&
Public Const NTM_ITALIC = &H1&
' tmPitchAndFamily flags
Public Const TMPF_FIXED_PITCH = &H1
Public Const TMPF_VECTOR = &H2
Public Const TMPF_DEVICE = &H8
Public Const TMPF_TRUETYPE = &H4
Public Const ELF_VERSION = 0
Public Const ELF_CULTURE_LATIN = 0
' EnumFonts Masks
Public Const RASTER_FONTTYPE = &H1
Public Const DEVICE_FONTTYPE = &H2
Public Const TRUETYPE_FONTTYPE = &H4
Declare Function EnumFontFamilies Lib "gdi32" Alias _
"EnumFontFamiliesA" _
(ByVal hDC As Long, ByVal lpszFamily As String, _
ByVal lpEnumFontFamProc As Long, LParam As Any) As Long
Declare Function GetDC Lib "user32" (ByVal hWnd As Long) As Long
Declare Function ReleaseDC Lib "user32" (ByVal hWnd As Long, _
ByVal hDC As Long) As Long
Function EnumFontFamProc(lpNLF As LOGFONT, lpNTM As NEWTEXTMETRIC, _
ByVal FontType As Long, LParam As ListBox) As Long
Dim FaceName As String
Dim FullName As String
FaceName = StrConv(lpNLF.lfFaceName, vbUnicode)
LParam.AddItem Left$(FaceName, InStr(FaceName, vbNullChar) - 1)
EnumFontFamProc = 1
End Function
Sub FillListWithFonts(LB As ListBox)
Dim hDC As Long
LB.Clear
hDC = GetDC(LB.hWnd)
EnumFontFamilies hDC, vbNullString, AddressOf EnumFontFamProc, LB
ReleaseDC LB.hWnd, hDC
End Sub
関連項目
サポートとフィードバック
Office VBA またはこの説明書に関するご質問やフィードバックがありますか? サポートの受け方およびフィードバックをお寄せいただく方法のガイダンスについては、Office VBA のサポートおよびフィードバックを参照してください。