#c# #delegates
#c# #делегаты
Вопрос:
В настоящее время, чтобы определить перехват события, я пишу:
delegate void WinEventHookDelegate(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
...
private WinEventHookDelegate WindowEventHookInstance;
...
private void WindowEventHook(IntPtr hWinEventHook, uint eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime)
...
WindowEventHookInstance = new WinEventHookDelegate(WindowEventHook);
Install();
...
SetWinEventHook(...
WindowEventHookInstance, // lpfnWinEventProc
...);
...
Т.е. я создаю 3 имени ( WinEventHookDelegate
, WindowEventHookInstance
, WindowEventHook
), 2 повторяющихся объявления прототипа и 1 присваивание, чтобы получить только указатель на функцию.
Могу ли я написать его менее избыточным и короче, может быть, в одной строке?
Комментарии:
1. Слишком много
...
и слишком мало{ }
. Важная часть, SetWinEventHook, также не определена.2. @HenkHolterman это из WinApi:learn.microsoft.com/en-us/windows/desktop/api/winuser /…
Ответ №1:
Вы можете использовать делегаты C # вместо определения своих собственных.
Для делегатов, которые указывают на функции void, такие как в вашем случае, вы можете использовать Action .
Вместо объявления и создания экземпляра делегата (или, в данном случае, делегата действия) вы можете вставить его непосредственно в свой метод SetWinEventHook следующим образом. Компилятор позаботится о создании экземпляра.
public void SetWinEventHook(Action<IntPtr, uint, IntPtr, int, int, uint, uint> myDelegate)
{
}
Теперь, чтобы запустить функцию, на которую указывает ваш делегат, сделайте это
myDelegate()
проблема, однако, в том, что этому делегату нужны 7 аргументов, которые, как вы объявили, ему понадобятся.
Чтобы обеспечить, что вы можете передать их в качестве второго аргумента в вашем методе SetWinEventHook следующим образом
public void SetWinEventHook(Action<IntPtr, uint, IntPtr, int, int, uint, uint> myDelegate, IntPtr a, uint b, IntPtr c, int d, int e, uint f, uint g)
{
myDelegate(a,b,c,d,e,f,g);
}
Итак, на данный момент вы, по сути,
1) Объявлен делегат
2) Создан экземпляр делегата
3) Создал метод hook для запуска делегата / функции
Теперь все, что вам нужно сделать, это вызвать SetWinEventHook и передать либо лямбда-выражение, либо функцию, написанную в другом месте, чтобы ваш делегат указывал на нее.
SetWinEventHook((a, b, c, d, r, f, g) => // using lambda here
{
},
new IntPtr(), 1, new IntPtr(), 2,3,4,5
);