Sdílet prostřednictvím


Postupy: Implementace funkcí zpětného volání

Následující postup a příklad ukazují, jak spravovaná aplikace pomocí vyvolání platformy může vytisknout hodnotu popisovače pro každé okno v místním počítači. Konkrétně procedura a příklad používají EnumWindows funkci k procházení seznamu oken a spravované funkce zpětného volání (s názvem CallBack) k vytištění hodnoty popisovače okna.

Implementace funkce zpětného volání

  1. Než budete pokračovat v implementaci, podívejte se na signaturu funkce EnumWindows. EnumWindows má následující podpis:

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
    

    Jedním vodítkem, že tato funkce vyžaduje zpětné volání, je přítomnost argumentu lpEnumFunc . Předpona lp (dlouhý ukazatel) se běžně zobrazuje v kombinaci s Func příponou v názvu argumentů, které přebírají ukazatel na funkci zpětného volání. Dokumentaci k funkcím Win32 najdete v sadě Microsoft Platform SDK od společnosti Microsoft.

  2. Vytvořte spravovanou funkci zpětného volání. Příklad deklaruje typ delegáta nazvaný CallBack, který přijímá dva argumenty (hwnd a lparam). Prvním argumentem je popisovač okna; druhý argument je definovaný aplikací. V této verzi musí být oba argumenty celé číslo.

    Funkce zpětného volání obecně vracejí nenulové hodnoty, které označují úspěch a nulu označující selhání. Tento příklad explicitně nastaví návratovou hodnotu na true, aby pokračovalo ve výčtu.

  3. Vytvořte delegáta a předejte ho jako argument funkci EnumWindows . Platform invoke automaticky převede delegáta na známý formát zpětného volání.

  4. Ujistěte se, že garbage collector nezrecykluje delegáta před dokončením práce funkce zpětného volání. Když delegáta předáte jako parametr nebo předáte delegáta obsaženého jako pole ve struktuře, zůstane po dobu trvání volání beze změny. Stejně jako v následujícím příkladu výčtu funkce zpětného volání dokončí svou práci před vrácením volání a nevyžaduje žádnou další akci spravovaného volajícího.

    Pokud je však možné vyvolat funkci zpětného volání poté, co se volání vrátí, musí spravovaný volající provést kroky, aby bylo zajištěno, že delegát zůstane nesebrán, dokud funkce zpětného volání neskončí. Příklad najdete v ukázce 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();
}

Viz také