Operador AddressOf

Operador unario que causa que la dirección del procedimiento al que precede se pase a un procedimiento de API que espera un puntero de función en una posición de la lista de argumento.

Sintaxis

AddressOfprocedurename

El procedurename especifica el procedimiento cuya dirección se va a pasar. Debe representar un procedimiento en un módulo estándar del proyecto en el que se realiza la llamada.

Comentarios

Cuando el nombre de un procedimiento se muestra en una lista de argumentos, el procedimiento suele evaluarse y se suele pasar el valor de retorno de la dirección del procedimiento. AddressOf permite pasar la dirección del procedimiento a una función de API de Windows en una biblioteca de vínculos dinámicos (DLL), en lugar de pasar el valor devuelto del procedimiento. La función de API puede usar la dirección para llamar al procedimiento Basic, un proceso conocido como devolución de llamada. El operador AddressOf solo se muestra en la llamada al procedimiento API.

Aunque puede usar AddressOf para pasar los punteros del procedimiento en procedimientos Basic, no puede llamar ninguna función a través de dicho puntero desde Basic. Esto significa, por ejemplo, que una clase escrita en Basic no puede realizar una devolución de llamada a su controlador mediante dicho puntero. Cuando use AddressOf para pasar un puntero de procedimientos mediante procedimientos en Basic, el parámetro del procedimiento llamado debe escribirse como As Long.

El uso de AddressOf puede dar lugar a resultados impredecibles si no comprende totalmente el concepto de devoluciones de llamadas a funciones. Debe comprender cómo funciona la parte de la devolución de llamadas, así como el código de la DLL a la que está pasando la dirección de la función. La depuración de estas interacciones es difícil porque el programa se ejecuta en el mismo proceso que el entorno de desarrollo. En algunos casos, es posible que no se pueda usar la depuración sistemática.

Nota:

[!NOTA] Puede crear sus propios prototipos de funciones de devolución de llamada en DLL compiladas con Microsoft Visual C++ (o con herramientas similares). Para trabajar con AddressOf, su prototipo debe usar la convención de llamada __stdcall. La convención de llamada predeterminada (__cdecl) no funcionará con AddressOf.

Dado que el autor de la llamada de una devolución de llamada no está dentro del programa, es importante que un error en el procedimiento de devolución de llamada no se propague al autor de la llamada. Para ello, coloque la instrucción On Error Resume Next al principio del procedimiento de devolución de llamada.

Ejemplo:

El ejemplo siguiente crea un formulario con un cuadro de lista que contiene una lista ordenada alfabéticamente con las fuentes de su sistema.

Para ejecutar este ejemplo, cree un formulario con un cuadro de lista. El código del formulario es el siguiente:

Option Explicit

Private Sub Form_Load()
    Module1.FillListWithFonts List1
End Sub

Coloque el código siguiente en un módulo. El tercer argumento de la definición de la función EnumFontFamilies es una instrucción Long que representa un procedimiento. El argumento debe contener la dirección del procedimiento, en lugar del valor que devuelve el procedimiento. En la llamada a EnumFontFamilies, el tercer argumento requiere que el operador AddressOf devuelva la dirección del procedimiento EnumFontFamProc, que es el nombre del procedimiento de devolución de llamada que se proporciona al llamar a la función API de Windows, EnumFontFamilies. Windows llama a EnumFontFamProc una vez para cada familia de fuentes del sistema al pasar AddressOf EnumFontFamProc a EnumFontFamilies. El último argumento pasado a EnumFontFamilies especifica el cuadro de lista en el que se muestra la información.

'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

Consulte también

Soporte técnico y comentarios

¿Tiene preguntas o comentarios sobre VBA para Office o esta documentación? Vea Soporte técnico y comentarios sobre VBA para Office para obtener ayuda sobre las formas en las que puede recibir soporte técnico y enviar comentarios.