Dela via


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 proceduren och exemplet funktionen EnumWindows 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 för funktionen EnumWindows 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 argumentet lpEnumFunc . Det är vanligt att se lp-prefixet (långpekare) kombinerat med Func-suffixet i namnet på argument som tar en pekare till en motringningsfunktion. 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-zerovärden för att indikera lyckade och noll för att indikera fel. I det här exemplet anges uttryckligen returvärdet till true för att fortsätta uppräkningen.

  3. Skapa ett ombud och skicka det som ett argument till funktionen EnumWindows . Plattformsanrop konverterar ombudet till ett välbekant återanropsformat automatiskt.

  4. Se till att skräpinsamlaren inte återtar ombudet innan återanropsfunktionen slutför sitt arbete. När du skickar ett ombud som en parameter, eller skickar ett ombud som ingår som ett fält i en struktur, förblir det osamlat under anropets varaktighet. 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 återanropsfunktionen kan anropas efter att anropet har returnerats måste den hanterade anroparen vidta åtgärder för att säkerställa att ombudet förblir osamlat tills återanropsfunktionen har slutförts. Ett exempel finns i exemplet GCHandle.

Exempel

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