Como: Implementar funções Callback
O procedimento e o exemplo a seguir demonstram como um aplicativo gerenciado, usando invocação de plataforma, pode imprimir o valor do identificador para cada janela no computador local. Especificamente, o uso de procedimento e exemplo de EnumWindows funcionar para percorrer a lista do windows e uma função de retorno de chamada gerenciada (retorno nomeado) para imprimir o valor do identificador de janela.
Para implementar uma função de retorno de chamada
Examine a assinatura para o EnumWindows a função antes de prosseguir com a implementação. EnumWindows tem a seguinte assinatura:
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
Um indício de que essa função requer um retorno de chamada é a presença da lpEnumFunc argumento. É comum ver o lp o prefixo de (ponteiro longo) combinado com o Func sufixo no nome de argumentos que levam um ponteiro para uma função de retorno de chamada. Para obter documentação sobre as funções do Win32, consulte Microsoft Platform SDK.
Crie a função de retorno de chamada gerenciados. O exemplo declara um tipo delegate, chamado CallBack, que leva dois argumentos (hwnd e lparam). O primeiro argumento é um identificador de janela; o segundo argumento é definido pelo aplicativo. Nesta versão, ambos os argumentos devem ser inteiros.
Geralmente, as funções de retorno de chamada retornam valores diferentes de zero para indicar sucesso e zero para indicar falha. Este exemplo define explicitamente o valor de retorno true para continuar a enumeração.
Criar um delegado e passá-lo como um argumento para o EnumWindows função. Invocação de plataforma converte o delegado em um formato familiar de retorno de chamada automaticamente.
Certifique-se de que o coletor de lixo não recuperou o delegado antes que a função de retorno de chamada conclui seu trabalho. Quando você passa um delegado como um parâmetro ou passa um delegado contido como um campo em uma estrutura, ela permanece uncollected para a duração da chamada. Então, como é o caso no exemplo a seguir de enumeração, a função de retorno de chamada conclui seu trabalho antes da chamada retorna e não requer nenhuma ação adicional pelo chamador gerenciado.
Se, no entanto, a função de retorno de chamada pode ser chamada após a chamada retorna, o chamador gerenciado deve tomar medidas para garantir a que o delegado permanecerá uncollected até que a função de retorno de chamada seja concluída. Para obter informações detalhadas sobre como evitar a coleta de lixo, consulte Interop Marshaling com a invocação de plataforma.
Exemplo
Imports System
Imports System.Runtime.InteropServices
Public Delegate Function CallBack( _
hwnd As Integer, lParam As Integer) As Boolean
Public Class EnumReportApp
Declare Function EnumWindows Lib "user32" ( _
x As CallBack, y As Integer) As Integer
Public Shared Sub Main()
EnumWindows(AddressOf EnumReportApp.Report, 0)
End Sub 'Main
Public Shared Function Report(hwnd As Integer, lParam As Integer) _
As Boolean
Console.Write("Window handle is ")
Console.WriteLine(hwnd)
Return True
End Function 'Report
End Class 'EnumReportApp
using System;
using System.Runtime.InteropServices;
public delegate bool CallBack(int hwnd, int lParam);
public class EnumReportApp
{
[DllImport("user32")]
public static extern int EnumWindows(CallBack x, int y);
public static void Main()
{
CallBack myCallBack = new CallBack(EnumReportApp.Report);
EnumWindows(myCallBack, 0);
}
public static bool Report(int hwnd, int lParam)
{
Console.Write("Window handle is ");
Console.WriteLine(hwnd);
return true;
}
}
using namespace System;
using namespace System::Runtime::InteropServices;
// A delegate type.
delegate bool CallBack(int hwnd, int lParam);
// Managed type with the method to call.
ref class EnumReport
{
// Report the window handle.
public:
[DllImport("user32")]
static int EnumWindows(CallBack^ x, int y);
static void Main()
{
EnumReport^ er = gcnew EnumReport;
CallBack^ myCallBack = gcnew CallBack(&EnumReport::Report);
EnumWindows(myCallBack, 0);
}
static bool Report(int hwnd, int lParam)
{
Console::Write(L"Window handle is ");
Console::WriteLine(hwnd);
return true;
}
};
int main()
{
EnumReport::Main();
}