Procedure: Callback-functies implementeren
In de volgende procedure en het voorbeeld ziet u hoe een beheerde toepassing, met behulp van platform aanroepen, de handlewaarde voor elk venster op de lokale computer kan afdrukken. In de procedure en het voorbeeld wordt de functie EnumWindows gebruikt om de lijst met vensters en een beheerde callback-functie (CallBack) te doorlopen om de waarde van de venstergreep af te drukken.
Een callback-functie implementeren
Bekijk de handtekening voor de functie EnumWindows voordat u verder gaat met de implementatie. EnumWindows heeft de volgende handtekening:
BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
Een aanwijzing dat deze functie een callback vereist, is de aanwezigheid van het argument lpEnumFunc . Het is gebruikelijk om het voorvoegsel lp (lange aanwijzer) te zien in combinatie met het Func-achtervoegsel in de naam van argumenten die een aanwijzer naar een callback-functie nemen. Zie de Microsoft Platform SDK voor documentatie over Win32-functies.
Maak de beheerde callback-functie. In het voorbeeld wordt een gemachtigdentype gede declareert, genaamd
CallBack
, waarbij twee argumenten (hwnd en lparam) worden gebruikt. Het eerste argument is een ingang voor het venster; het tweede argument is toepassingsgedefinieerde. In deze release moeten beide argumenten gehele getallen zijn.Callback-functies retourneren over het algemeen niet-nulwaarden om succes aan te geven en nul om fouten aan te geven. In dit voorbeeld wordt de retourwaarde expliciet ingesteld op true om door te gaan met de opsomming.
Maak een gemachtigde en geef deze door als argument aan de functie EnumWindows . Met platformaanroep wordt de gemachtigde automatisch geconverteerd naar een vertrouwde callback-indeling.
Zorg ervoor dat de garbagecollector de gemachtigde niet vrij maakt voordat de callback-functie het werk voltooit. Wanneer u een gemachtigde als parameter doorgeeft of een gemachtigde doorgeeft die is opgenomen als een veld in een structuur, blijft deze niet opgehaald voor de duur van de aanroep. Net zoals in het volgende opsommingsvoorbeeld, voltooit de callback-functie het werk voordat de aanroep wordt geretourneerd en is er geen extra actie van de beheerde aanroeper vereist.
Als de callback-functie echter kan worden aangeroepen nadat de aanroep is geretourneerd, moet de beheerde aanroeper stappen ondernemen om ervoor te zorgen dat de gemachtigde niet-opgehaald blijft totdat de callback-functie is voltooid. Zie het voorbeeld GCHandle voor een voorbeeld.
Voorbeeld
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();
}