Gör så här: Implementera återanropsfunktioner

Följande procedur och exempel visar hur ett hanterat program med plattformsanrop kan skriva ut referensvärdet för varje fönster på den lokala datorn. Mer specifikt använder EnumWindows proceduren och exemplet funktionen för att gå igenom listan över fönster och en hanterad återanropsfunktion (med namnet CallBack) för att skriva ut värdet för fönsterhandtaget.

Så här implementerar du en återanropsfunktion

  1. Titta på signaturen EnumWindows för funktionen innan du fortsätter med implementeringen. EnumWindows har följande signatur:

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
    

    En ledtråd till att den här funktionen kräver ett återanrop är förekomsten av lpEnumFunc argumentet. Det är vanligt att se prefixet lp (långpekare) kombinerat med suffixet Func i namnet på argument som tar en pekare till en callback-funktion. Dokumentation om Win32-funktioner finns i Microsoft Platform SDK.

  2. Skapa den hanterade återanropsfunktionen. Exemplet deklarerar en delegattyp med namnet CallBack, som tar två argument (hwnd och lparam). Det första argumentet är ett handtag till fönstret. det andra argumentet är programdefinierat. I den här versionen måste båda argumenten vara heltal.

    Återanropsfunktioner returnerar vanligtvis icke-nollvärden för att indikera framgång och noll för att indikera misslyckande. I det här exemplet anges uttryckligen returvärdet till true för att fortsätta uppräkningen.

  3. Skapa en delegering och skicka den som ett argument till funktionen EnumWindows. Plattformsanrop konverterar automatiskt delegeringen till ett välbekant återanropsformat.

  4. Se till att skräpsamlaren inte återtar den delegerade innan återanropsfunktionen slutför sitt arbete. När du skickar en delegering som en parameter, eller skickar en delegering som ingår som ett fält i en struktur, förblir den icke insamlad under varaktigheten av anropet. Så, som i följande uppräkningsexempel, slutför återanropsfunktionen sitt arbete innan anropet returneras och kräver ingen ytterligare åtgärd av den hanterade anroparen.

    Men om callbackfunktionen kan anropas efter att samtalet har återgått måste den hanterade anroparen vidta åtgärder för att säkerställa att den delegerade förblir inte insamlad tills callbackfunktionen har slutförts. Ett exempel finns i exemplet GCHandle.

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

Se även