Freigeben über


Vorgehensweise: Implementieren von Rückruffunktionen

Das folgende Verfahren und Beispiel veranschaulichen, wie eine verwaltete Anwendung mithilfe des Plattformaufrufs den Handlewert für jedes Fenster auf dem lokalen Computer drucken kann. Die Prozedur und das Beispiel verwenden die EnumWindows Funktion, um die Liste der Fenster zu durchlaufen und eine verwaltete Rückruffunktion (mit dem Namen CallBack) zu verwenden, um den Wert des Fensterhandles auszugeben.

So implementieren Sie eine Rückruffunktion

  1. Sehen Sie sich die Signatur für die EnumWindows Funktion an, bevor Sie mit der Implementierung fortfahren. EnumWindows hat die folgende Signatur:

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
    

    Ein Hinweis darauf, dass diese Funktion einen Rückruf erfordert, ist das Vorhandensein des lpEnumFunc Arguments. Häufig wird das lp Präfix (long pointer) zusammen mit dem Func Suffix im Namen von Argumenten angezeigt, die einen Zeiger auf eine Rückruffunktion übergeben. Dokumentation zu Win32-Funktionen finden Sie im Microsoft Platform SDK.

  2. Erstellen Sie die verwaltete Rückruffunktion. Im Beispiel wird ein Delegattyp deklariert, der zwei CallBackArgumente akzeptiert (hwnd und lparam). Das erste Argument ist ein Handle für das Fenster; das zweite Argument ist anwendungsdefiniert. In dieser Version müssen beide Argumente ganze Zahlen sein.

    Rückruffunktionen geben in der Regel Nichtzerowerte zurück, um Erfolg und Null anzugeben, um fehler anzuzeigen. In diesem Beispiel wird der Rückgabewert explizit auf true gesetzt, um die Enumeration fortzusetzen.

  3. Erstellen Sie einen Delegaten, und übergeben Sie ihn als Argument an die EnumWindows Funktion. Der Plattformaufruf konvertiert den Delegat automatisch in ein vertrautes Rückrufformat.

  4. Stellen Sie sicher, dass der Garbage Collector den Delegaten nicht zurückfordert, bevor die Rückruffunktion ihre Arbeit abschließt. Wenn Sie eine Stellvertretung als Parameter übergeben oder eine Stellvertretung übergeben, die als Feld in einer Struktur enthalten ist, bleibt sie für die Dauer des Aufrufs unabgespeichert. Wie im folgenden Enumerationsbeispiel ist die Rückruffunktion also abgeschlossen, bevor der Aufruf zurückgegeben wird und keine zusätzliche Aktion durch den verwalteten Aufrufer erforderlich ist.

    Wenn die Rückruffunktion jedoch nach dem Rückruf aufgerufen werden kann, muss der verwaltete Aufrufer Schritte ausführen, um sicherzustellen, dass der Delegat bis zum Abschluss der Rückruffunktion nicht erfasst wird. Ein Beispiel finden Sie im GCHandle-Beispiel.

Example

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();
}

Siehe auch