Operador AddressOf

Um operador unário que faz com que o endereço do procedimento que ele precede seja passado para um procedimento de API que espera um ponteiro de função nessa posição na lista de argumentos .

Sintaxe

AddressOfprocedurename

O nome de procedimento necessário especifica o procedimento cujo endereço deve ser passado. Deve representar um procedimento em um módulo padrão no projeto em que a chamada é feita.

Comentários

Quando um nome de procedimento aparece em uma lista de argumentos, geralmente o procedimento é avaliado e o endereço do valor retornado pelo procedimento é passado. AddressOf permite que o endereço do procedimento seja passado para uma função de API do Windows em uma DLL (biblioteca de vínculo dinâmico), em vez de passar o valor de retorno do procedimento. A função de API pode então usar o endereço para chamar o procedimento Básico, um processo conhecido como retorno de chamada. O operador AddressOf aparece somente na chamada para o procedimento de API.

Embora você possa usar AddressOf para passar ponteiros de procedimento entre procedimentos básicos, você não pode chamar uma função por meio desse ponteiro de dentro de Básico. Isso significa, por exemplo, que uma classe escrita em Basic não pode fazer um retorno de chamada para seu controlador usando esse ponteiro. Ao usar AddressOf para passar um ponteiro de procedimento entre procedimentos dentro do Básico, o parâmetro do procedimento chamado deve ser digitado As Long.

O uso de AddressOf poderá causar resultados imprevisíveis se você não entender completamente o conceito de retornos de chamada de função. Você deve entender como funciona a parte Básica do retorno de chamada e também o código da DLL para a qual você está passando o endereço da função. Depurar essas interações é difícil porque o programa é executado no mesmo processo que o ambiente de desenvolvimento. Em alguns casos, a depuração sistemática pode não ser possível.

Observação

Você pode criar seus próprios protótipos de função de retorno de chamada em DLLs compiladas com o Microsoft Visual C++ (ou ferramentas semelhantes). Para trabalhar com AddressOf, seu protótipo deve usar a convenção de chamada de __stdcall. A convenção de chamada padrão (__cdecl) não funcionará com AddressOf.

Como o chamador de um retorno de chamada não está em seu programa, é importante que um erro no procedimento de retorno de chamada não seja propagado de volta para o chamador. Você pode fazer isso colocando a instrução On Error Resume Next no início do procedimento de retorno de chamada.

Exemplo

O exemplo a seguir cria um formulário com uma caixa de listagem contendo uma lista classificada alfabeticamente das fontes em seu sistema.

Para executar este exemplo, crie um formulário com uma caixa de listagem. O código do formulário é o seguinte:

Option Explicit

Private Sub Form_Load()
    Module1.FillListWithFonts List1
End Sub

Coloque o código a seguir em um módulo. O terceiro argumento na definição da função EnumFontFamilies é um Long que representa um procedimento. O argumento deve conter o endereço do procedimento, em vez do valor que o procedimento retorna. Na chamada para EnumFontFamilies, o terceiro argumento exige que o operador AddressOf retorne o endereço do procedimento EnumFontFamProc, que é o nome do procedimento de retorno de chamada que você fornece ao chamar a função da API do Windows, EnumFontFamilies. O Windows chama EnumFontFamProc uma vez para cada uma das famílias de fontes no sistema quando você passa AddressOf EnumFontFamProc para EnumFontFamilies. O último argumento passado para EnumFontFamilies especifica a caixa de listagem na qual as informações são exibidas.

'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

Confira também

Suporte e comentários

Tem dúvidas ou quer enviar comentários sobre o VBA para Office ou sobre esta documentação? Confira Suporte e comentários sobre o VBA para Office a fim de obter orientação sobre as maneiras pelas quais você pode receber suporte e fornecer comentários.