共用方式為


HOW TO:實作回呼函式

下列程序和範例示範 Managed 應用程式如何 (使用平台叫用) 列印本機電腦上每個視窗的控制代碼值。 特別的是,程序和範例會使用 EnumWindows 函式逐步執行視窗清單,並使用 Managed 回呼函式 (Callback Function) (名為 CallBack) 列印視窗控制代碼值。

若要實作回呼函式

  1. 在繼續進行實作之前,先查看 EnumWindows 函式的簽章。 EnumWindows 具有以下簽章:

    BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)
    

    有個跡象可以看出這個函式需要回呼函式,就是它有個 lpEnumFunc 引數。 常常可以看到 lp (長指標 (Long Pointer)) 前置詞與 Func 後置詞,組合使用於接受指向回呼函式之指標的引數名稱中。 如需 Win32 函式的文件,請參閱 Microsoft Platform SDK。

  2. 建立 Managed 回呼函式。 範例中宣告了一個用來接受兩個引數 (hwndlparam) 的委派型別 (Delegate Type),名稱為 CallBack。 第一個引數是視窗的控制代碼;第二個引數是應用程式定義的。 在這個版本中,這兩個引數都必須是整數。

    回呼函式通常會傳回非零值以表示成功,而零則表示失則。 這個範例是將傳回值明確地設定為 True 以繼續進行列舉。

  3. 建立委派物件,並將它當做引數傳遞給 EnumWindows 函式。 平台叫用會自動將這個委派物件轉換為熟悉的回呼格式。

  4. 在回呼函式完成工作之前,確定記憶體回收行程不會重新宣告委派。 當您將委派當做參數傳遞,或是傳遞內含在結構中當做欄位的委派時,在呼叫期間不會將它回收。 因此,在下面這個列舉型別的範例中,回呼函式會在呼叫傳回之前先完成它的工作,而且不會要求 Managed 呼叫端採取其他動作。

    但是,如果呼叫函式可在呼叫傳回之後再叫用,Managed 呼叫端必須採取一些步驟,以確保在回呼函式完成之前不會將委派回收。 如需避免記憶體回收的詳細資訊,請參閱平台叫用的 Interop 封送處理

範例

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

請參閱

概念

回呼函式

其他資源

呼叫 DLL 函式