Visszahívási függvények implementálásának útmutatója

Az alábbi eljárás és példa bemutatja, hogyan kinyomtathatja egy platformhívást használó felügyelt alkalmazás a helyi számítógépen lévő ablakok leíró értékeit. Az eljárás és a példa az EnumWindows funkciót használja az ablakok listájának lépésenkénti végigjárására, valamint egy felügyelt visszahívási függvény (CallBack) az ablakleíró értékének kinyomtatására.

Visszahívási függvény implementálása

  1. Mielőtt továbblép a megvalósításra, tekintse meg a EnumWindows függvény aláírását. EnumWindows a következő aláírást tartalmazza:

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
    

    Az egyik jel, hogy a függvény visszahívást igényel, az lpEnumFunc argumentum jelenléte. Gyakran előfordul, hogy a lp (hosszú mutató) előtag és az Func utótag szerepel azon argumentumok nevében, amelyek egy visszahívási függvényhez viszik az egérmutatót. A Win32-függvényekkel kapcsolatos dokumentációt a Microsoft Platform SDK-ban találja.

  2. Hozza létre a felügyelt visszahívási függvényt. A példa deklarál egy delegálttípust, amelynek neve CallBackkét argumentumot vesz fel (hwnd és lparam). Az első argumentum az ablak hivatkozása; a második argumentum az alkalmazás által definiált. Ebben a kiadásban mindkét argumentumnak egész számnak kell lennie.

    A visszahívási függvények általában nem nulla értékeket adnak vissza a sikeresség jelzésére, és nullát a hiba jelzésére. Ez a példa kifejezetten beállítja a visszatérési értéket true-re az enumerálás folytatásához.

  3. Hozzon létre egy delegáltat, és adja át argumentumként a EnumWindows függvénynek. A platformhívások automatikusan ismerős visszahívási formátummá alakítják a delegáltat.

  4. Győződjön meg arról, hogy a szemétgyűjtő nem vonja vissza a meghatalmazottat, mielőtt a visszahívási függvény befejezi a munkáját. Amikor egy meghatalmazottat ad át paraméterként, vagy egy struktúrában mezőként tárolt meghatalmazottat ad át, az a hívás időtartama alatt nem kerül begyűjtésre. A következő számbavételi példához hasonlóan a visszahívási függvény a hívás visszatérése előtt befejezi a munkáját, és nem igényel további műveletet a felügyelt hívótól.

    Ha azonban a visszahívási függvény a hívás visszatérése után is meghívható, a kezelt hívónak lépéseket kell tennie annak érdekében, hogy a delegált ne kerüljön összeszedésre, amíg a visszahívási függvény be nem fejeződik. Példaként tekintse meg a GCHandle-mintát.

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

Lásd még