Cómo: Implementar funciones de devolución de llamada
Actualización: noviembre 2007
El siguiente procedimiento y el ejemplo incluido muestran la forma en que una aplicación administrada, utilizando la invocación de plataforma, puede imprimir el valor del identificador de cada ventana en el equipo local. Concretamente, utilizan la función EnumWindows para recorrer paso a paso la lista de ventanas y se utiliza una función de devolución de llamada administrada (denominada CallBack) para imprimir el valor del identificador de ventana.
Para implementar una función de devolución de llamada
Observe el prototipo de la función EnumWindows antes de continuar con la implementación. EnumWindows tiene el siguiente prototipo:
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
Una pista para saber que esta función requiere una devolución de llamada es la presencia del argumento lpEnumFunc. Es frecuente ver el prefijo lp (puntero largo) combinado con el sufijo Func en el nombre de los argumentos que tienen un puntero a una función de devolución de llamada. Para obtener la documentación de las funciones de Win32, vea Platform SDK.
Cree la función de devolución de llamada administrada. En el ejemplo se declara un tipo de delegado, denominado CallBack, que toma dos argumentos (hwnd y Iparam). El primer argumento es un identificador de la ventana; el segundo, viene definido por la aplicación. En esta versión, los dos argumentos tienen que ser enteros.
Generalmente, las funciones de devolución de llamada devuelven valores distintos de cero para indicar un resultado satisfactorio y cero para indicar que se ha producido un error. En este ejemplo, el valor devuelto se establece explícitamente en true para continuar la enumeración.
Cree un delegado y páseselo como argumento a la función EnumWindows. La invocación de plataforma convierte automáticamente el delegado a un formato de devolución de llamada conocido.
Asegúrese de que el recolector de elementos no utilizados no reclama el delegado antes de que la función de devolución de llamada complete su tarea. Cuando pase un delegado como parámetro, o pase un delegado contenido como campo en una estructura, se queda si recoger mientras dure la llamada. Por lo tanto, tal como ocurre en el siguiente ejemplo de enumeración, la función de devolución de llamada completa su tarea antes de que vuelva la llamada y no es necesaria ninguna acción adicional por parte del llamador administrado.
No obstante, si se puede invocar la función de devolución de llamada después de que vuelva la llamada, el llamador administrado debe seguir los pasos para asegurarse de que el delegado sigue sin recoger hasta que la función de devolución de llamada acaba. Para obtener información detallada sobre cómo evitar la recolección de elementos no utilizados, vea Cálculo de referencias interoperativo con invocación de plataforma.
Ejemplo
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::Runtime::InteropServices;
// A delegate type.
__delegate bool CallBack(int hwnd, int lParam);
// Managed type with the method to call.
__gc class EnumReport
{
// Report the window handle.
public:
bool Report(int hwnd, int lParam) {
Console::Write(L"Window handle is ");
Console::WriteLine(hwnd);
return true;
}
};
[DllImport("user32")]
extern "C" int EnumWindows(CallBack* x, int y);
void main(void) {
EnumReport* er = new EnumReport;
CallBack* myCallBack = new CallBack(er, &EnumReport::Report);
EnumWindows(myCallBack, 0);
}
Vea también
Conceptos
Funciones de devolución de llamada