以下程序與範例展示了受管理應用程式如何利用平台調用,為本地電腦上的每個視窗列印句柄值。 具體來說,程序和範例使用 EnumWindows 函式來遍歷視窗清單,並利用一個名為 CallBack 的管理回調函式來列印視窗句柄的值。
實作回調函式
在繼續實作之前,先看看
EnumWindows函式簽名。EnumWindows具有以下簽名:BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)此函式需要回調的一個線索是
lpEnumFunc參數的存在。 在參數名稱中,常見將lp(長指標)前綴與Func後綴結合,這些參數接收指向回調函數的指標。 關於 Win32 功能的相關文件,請參閱 Microsoft Platform SDK。建立管理回調函式。 範例宣告了一個代理型態,稱為
CallBack,該類型包含兩個參數(hwnd 和 lparam)。 第一個參數是視窗的控制代碼;第二個參數是由應用程式定義的。 在此釋出中,兩個參數都必須是整數。回調函式通常回傳非零值表示成功,零則表示失敗。 此範例明確將回傳值設為
true以繼續列舉。建立一個委派,並將其作為參數傳遞給
EnumWindows函數。 Platform invoke 會自動將代理轉換成熟悉的回撥格式。確保垃圾回收器在回調函式完成前不會重新奪回代理。 當你將委派作為參數傳遞,或將委派作為結構中的欄位傳遞時,該委派在呼叫期間不會被回收。 因此,如同以下列舉的範例,回呼函式在呼叫返回之前就完成它的工作,並且不需要由受控的呼叫者進行額外操作。
然而,如果回調函式可以在呼叫回傳後被呼叫,受管理呼叫者必須採取措施確保代理在回調函式結束前保持未被收集。 舉例可參考 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();
}