Сообщество программистов Autodesk в СНГ

Статьи => Опубликованные статьи => Тема начата: Александр Ривилис от 13-02-2014, 03:30:06

Название: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 13-02-2014, 03:30:06
Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Константин75 от 22-04-2019, 14:16:58
Добрый день!
У меня есть вопрос по данному коду, заранее прошу меня извинить за незнание матчасти.

Пытаюсь применить данный код, для того чтобы отследить нажатие пользователем определённой клавиши, но никаких событий не происходит.
Создал AutoCAD .NET Wizard для VS 2015 (2013, 2012) шаблон и поместил в раздел MyCommands.cs внутрь процедуры (функции) данный код - получил ошибку. Вставил код  после объявления пространства имён и имя класса, то всё компилируется без ошибок, но в AutoCade срабатывания не происходит.

AutoCad 2012x64

(https://i.postimg.cc/sBYbvzC3/2019-04-22-14-00-19.png) (https://postimg.cc/sBYbvzC3)
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 22-04-2019, 14:23:12
Выложи проект полностью - проверю.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Константин75 от 22-04-2019, 14:50:51
Приложил архив
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 22-04-2019, 19:17:21
Приложил архив
Проверь этот код:
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using System.Runtime.InteropServices;
  6. using System.Windows;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(AutoCAD_CSharp_plug_in1.MyCommands))]
  10.  
  11. namespace AutoCAD_CSharp_plug_in1
  12. {
  13.   public class MyCommands
  14.   {
  15.     // Для AutoCAD 2013 64 бит
  16.     // Для предыдущих версий импортируем из acad.exe (вместо accore.dll)
  17.     [DllImport("acad.exe",
  18.       CharSet = CharSet.Unicode,
  19.       CallingConvention = CallingConvention.Cdecl,
  20.       EntryPoint = "?acedRegisterFilterWinMsg@@YAHQ6AHPEAUtagMSG@@@Z@Z")]
  21.     private static extern int acedRegisterFilterWinMsg(
  22.       WindowHookProc callBackFunc);
  23.     const int WM_KEYDOWN = 0x100; // Нажатие клавиши
  24.     const int WM_KEYUP = 0x101; // Отжатие клавиши
  25.     const int VK_ADD = 0x6B; // Клавиша +
  26.  
  27.     // Функция обратного вызова для хука
  28.     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  29.     public delegate int WindowHookProc(
  30.           ref System.Windows.Forms.Message msg);
  31.  
  32.     private static int WindowsHook(
  33.       ref System.Windows.Forms.Message msg)
  34.     {
  35.       // проверяем структуру msg на то, что нас интересует,
  36.       // например, клавиши, движения мыши, и т.д.
  37.  
  38.       if (msg.Msg == WM_KEYDOWN)
  39.       {
  40.         if (msg.WParam == (IntPtr)VK_ADD)
  41.           // делаем что нужно
  42.           MessageBox.Show("Нажата клавиша +");
  43.       }
  44.  
  45.       return 0;
  46.     }
  47.  
  48.     private static WindowHookProc callBackFunc = null;
  49.  
  50.     [CommandMethod("registerHook")]
  51.     public static void CmdRegisterHook()
  52.     {
  53.       callBackFunc = new WindowHookProc(WindowsHook);
  54.       acedRegisterFilterWinMsg(callBackFunc);
  55.     }
  56.   }
  57. }
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Константин75 от 23-04-2019, 09:24:48
Нет. Не работает.
Почистил от мусора, вставил только этот код. Компилируется без ошибок. В Автокаде ничего не происходит. Нажимаю +, он отображается в командной строке и всплывают подсказки. Пробовал и другие символы - никакой реакции.
По идее всё должно работать. Может на рабочем компьютере не позволяет система безопасности, может уже установлены какие перехватчики?
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 23-04-2019, 09:39:49
Нажимаю +, он отображается в командной строке и всплывают подсказки. Пробовал и другие символы - никакой реакции.
У меня работает. У тебя был совсем неправильный проект, который я очистил. В связи с тем, что пути к acad.exe и к ObjectARX SDK не совпадают я правил проект, удалял лишнее. Можешь попробовать с этим проектом.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 23-04-2019, 09:47:54
Константин75,
Надеюсь команду registerHook ты не забываешь запустить?
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Константин75 от 23-04-2019, 10:15:09
Константин75,
Надеюсь команду registerHook ты не забываешь запустить?
Конечно не запускал(. Прошу меня извинить. Всё заработало!
Реагирует на + который на основной клавиатуре, на дополнительной надеюсь разберусь.
Спасибо огромное за помощь!!!
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 23-04-2019, 11:30:16
Константин75,
Надеюсь команду registerHook ты не забываешь запустить?
Конечно не запускал(. Прошу меня извинить. Всё заработало!
Реагирует на + который на основной клавиатуре, на дополнительной надеюсь разберусь.
Спасибо огромное за помощь!!!

Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using System.Runtime.InteropServices;
  6. using System.Windows;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(AutoCAD_CSharp_plug_in1.MyCommands))]
  10.  
  11. namespace AutoCAD_CSharp_plug_in1
  12. {
  13.   public class MyCommands
  14.   {
  15.     // Для AutoCAD 2013 64 бит
  16.     // Для предыдущих версий импортируем из acad.exe (вместо accore.dll)
  17.     [DllImport("acad.exe",
  18.       CharSet = CharSet.Unicode,
  19.       CallingConvention = CallingConvention.Cdecl,
  20.       EntryPoint = "?acedRegisterFilterWinMsg@@YAHQ6AHPEAUtagMSG@@@Z@Z")]
  21.     private static extern int acedRegisterFilterWinMsg(
  22.       WindowHookProc callBackFunc);
  23.     const int WM_KEYDOWN = 0x100; // Нажатие клавиши
  24.     const int WM_KEYUP = 0x101; // Отжатие клавиши
  25.     const int VK_ADD = 0x6B; // Клавиша +
  26.     const int VK_OEM_PLUS = 0xBB; // Клавиша + на цифровой клавиатуре
  27.  
  28.     // Функция обратного вызова для хука
  29.     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  30.     public delegate int WindowHookProc(
  31.           ref System.Windows.Forms.Message msg);
  32.  
  33.     private static int WindowsHook(
  34.       ref System.Windows.Forms.Message msg)
  35.     {
  36.       // проверяем структуру msg на то, что нас интересует,
  37.       // например, клавиши, движения мыши, и т.д.
  38.  
  39.       if (msg.Msg == WM_KEYDOWN)
  40.       {
  41.         if (msg.WParam == (IntPtr)VK_ADD || msg.WParam ==  (IntPtr)VK_OEM_PLUS)
  42.           // делаем что нужно
  43.           MessageBox.Show("Нажата клавиша +");
  44.       }
  45.  
  46.       return 0;
  47.     }
  48.  
  49.     private static WindowHookProc callBackFunc = null;
  50.  
  51.     [CommandMethod("registerHook")]
  52.     public static void CmdRegisterHook()
  53.     {
  54.       callBackFunc = new WindowHookProc(WindowsHook);
  55.       acedRegisterFilterWinMsg(callBackFunc);
  56.     }
  57.   }
  58. }

Так должно реагировать и на плюс на цифровой клавиатуре.

Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Константин75 от 23-04-2019, 13:34:18
Да, Спасибо Большое, Всё работает!
Нужно где-то пометить правильный ответ? пока не нашёл такой кнопки.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 23-04-2019, 13:45:54
Нужно где-то пометить правильный ответ? пока не нашёл такой кнопки.
Эта кнопка появляется только у тех, кто начинает тему и у администраторов/модераторов. Я отметил решение.
Есть еще [+] и [-], для реакции на сообщение.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 02-10-2022, 18:34:54
Добрый вечер! Подскажите, вроде бы всё сделал как в последнем примере, ошибок при компиляции никаких нет, вводить "registerHook" не забываю :-) , но как только ввожу, автокад (2022) зависает, а Visual Studio выводит сообщения

(https://i.ibb.co/3M9cQWQ/image.png) (https://ibb.co/P9vg040)
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 02-10-2022, 18:46:16
Кулаков Михаил,
Попробуй вместо:
Код - C# [Выбрать]
  1.     [DllImport("acad.exe",
  2.       CharSet = CharSet.Unicode,
  3.       CallingConvention = CallingConvention.Cdecl,
  4.       EntryPoint = "?acedRegisterFilterWinMsg@@YAHQ6AHPEAUtagMSG@@@Z@Z")]
  5.     private static extern int acedRegisterFilterWinMsg(
  6.       WindowHookProc callBackFunc);
использовать:
Код - C# [Выбрать]
  1. //    [DllImport("acad.exe",
  2.     [DllImport("accore.dll",
  3.       CharSet = CharSet.Unicode,
  4.       CallingConvention = CallingConvention.Cdecl,
  5.       EntryPoint = "?acedRegisterFilterWinMsg@@YA_NQ6A_NPEAUtagMSG@@@Z@Z")]
  6.     private static extern bool acedRegisterFilterWinMsg(
  7.       WindowHookProc callBackFunc);
Эта сигнатура начиная с версии AutoCAD 2019
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 02-10-2022, 19:02:40
Спасибо, что быстро ответили, но к сожалению, не помогло. Все тоже самое.

Концовка выходных данных VS2019 (если это как-то нужно):
Вызвано исключение: "System.EntryPointNotFoundException" в ClassLibrary1.dll
Поток 0x2bd8 завершился с кодом 0 (0x0).
Вызвано исключение: "System.AccessViolationException" в accoremgd.dll
Необработанное исключение типа "System.AccessViolationException" в accoremgd.dll
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

Программа "[26100] acad.exe" завершилась с кодом -1 (0xffffffff).
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 02-10-2022, 19:15:18
Кулаков Михаил,
Я исправил свой ответ. Попробуй еще раз.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 02-10-2022, 19:24:54
Всё супер, огромное спасибо!!! Удивляюсь как заработало у Константин75
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 02-10-2022, 19:27:58
Удивляюсь как заработало у Константин75
Видимо он использовал AutoCAD 2012  там "acad.exe", а не "accore.dll" и другая сигнатура функции.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 02-10-2022, 19:30:40
Не подскажите, как вернуть прежний хук?
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 02-10-2022, 19:31:56
Не подскажите, как вернуть прежний хук?
Не понял вопроса.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 02-10-2022, 19:39:25
В данном примере, мы установили хук и отлавливаем нажатие на клавиши и выводим сообщение. Как сделать, чтобы, например, по нажатию кнопки на ленте (или по вызову функции, не важно) отменить вывод сообщений, а вернуть стандартную реакцию на нажатие клавиш.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 02-10-2022, 19:41:46
а вернуть стандартную реакцию на нажатие клавиш.
Т.е. убрать свой хук? Тогда нужно использовать обертку для функции acedRemoveFilterWinMsg.
Без проверки:
Код - C# [Выбрать]
  1. [DllImport("accore.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl,
  2.   EntryPoint = "?acedRemoveFilterWinMsg@@YA_NQ6A_NPEAUtagMSG@@@Z@Z")]
  3. private static extern bool acedRemoveFilterWinMsg(WindowHookProc callBackFunc);
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 02-10-2022, 20:53:18
Я в начале воспользовался ссылкой https://www.caduser.ru/forum/post195914.html#p195914 (https://www.caduser.ru/forum/post195914.html#p195914), у меня после команды UnregisterHook хук не отменился, а стал дублироваться, т.е. сообщение теперь стало выводиться дважды. Увидел, что Вы подкорректировали ответ, и
Код - C# [Выбрать]
  1. private static extern int acedRemoveFilterWinMsg(WindowHookProc callBackFunc);
стало
Код - C# [Выбрать]
  1. private static extern bool acedRemoveFilterWinMsg(WindowHookProc callBackFunc);
Но, к сожалению, сообщения так дважды и выводятся. На всякий случай, привожу свой код. Может у меня глаз "замылился"
Код - C# [Выбрать]
  1. // Для AutoCAD 2013 64 бит
  2.         // Для предыдущих версий импортируем из acad.exe (вместо accore.dll)
  3.         [DllImport("accore.dll",
  4.             CharSet = CharSet.Unicode,
  5.             CallingConvention = CallingConvention.Cdecl,
  6.             //EntryPoint = "?acedRegisterFilterWinMsg@@YAHQ6AHPEAUtagMSG@@@Z@Z")]
  7.             EntryPoint = "?acedRegisterFilterWinMsg@@YA_NQ6A_NPEAUtagMSG@@@Z@Z")] //с версии AutoCAD2019
  8.         private static extern int acedRegisterFilterWinMsg(WindowHookProc callBackFunc);
  9.  
  10.         // For AutoCAD 2013 64 bit
  11.         // On previous versions, import from acad.exe (instead accore.dll)
  12.         [DllImport("accore.dll", CharSet = CharSet.Unicode,
  13.             CallingConvention = CallingConvention.Cdecl,
  14.             EntryPoint = "?acedRemoveFilterWinMsg@@YA_NQ6A_NPEAUtagMSG@@@Z@Z")]
  15.         private static extern bool acedRemoveFilterWinMsg(WindowHookProc callBackFunc);
  16.  
  17.         const int WM_KEYDOWN = 0x100; // Нажатие клавиши
  18.         const int WM_KEYUP = 0x101; // Отжатие клавиши
  19.         const int VK_ADD = 0x6B; // Клавиша +
  20.         const int VK_OEM_PLUS = 0xBB; // Клавиша + на цифровой клавиатуре
  21.  
  22.  
  23.         // Функция обратного вызова для хука
  24.         [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  25.         public delegate int WindowHookProc(ref System.Windows.Forms.Message msg);
  26.  
  27.         private static int WindowsHook(
  28.           ref System.Windows.Forms.Message msg)
  29.         {
  30.             // проверяем структуру msg на то, что нас интересует,
  31.             // например, клавиши, движения мыши, и т.д.
  32.  
  33.             if (msg.Msg == WM_KEYDOWN)
  34.             {
  35.                 if (msg.WParam == (IntPtr)VK_ADD || msg.WParam == (IntPtr)VK_OEM_PLUS)
  36.                     // делаем что нужно
  37.                     MessageBox.Show("Нажата клавиша +");
  38.             }
  39.  
  40.             return 0;
  41.         }
  42.  
  43.         private static WindowHookProc callBackFunc = null;
  44.  
  45.         [CommandMethod("registerHook")]
  46.         public static void CmdRegisterHook()
  47.         {
  48.             callBackFunc = new WindowHookProc(WindowsHook);
  49.             acedRegisterFilterWinMsg(callBackFunc);
  50.         }
  51.  
  52.         [CommandMethod("UnregisterHook")]
  53.         public static void CmdUnRegisterHook()
  54.         {
  55.             acedRemoveFilterWinMsg(callBackFunc);
  56.         }
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 02-10-2022, 21:12:45
Странно, вы вроде только переформатировали моё сообщение (не нашел отличий в тексте), но сейчас оно работает нормально. Где-то я что-то не так делал. Еще раз, большое спасибо
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 02-10-2022, 21:59:57
Код - C# [Выбрать]
  1. using System;
  2. using Autodesk.AutoCAD.Runtime;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.EditorInput;
  5. using System.Runtime.InteropServices;
  6. using System.Windows;
  7.  
  8. // This line is not mandatory, but improves loading performances
  9. [assembly: CommandClass(typeof(WinHook.MyCommands))]
  10.  
  11. namespace WinHook
  12. {
  13.   public class MyCommands
  14.   {
  15.     [DllImport("accore.dll",
  16.         CharSet = CharSet.Unicode,
  17.         CallingConvention = CallingConvention.Cdecl,
  18.         EntryPoint = "?acedRegisterFilterWinMsg@@YA_NQ6A_NPEAUtagMSG@@@Z@Z")] //с версии AutoCAD2019
  19.     private static extern bool acedRegisterFilterWinMsg(WindowHookProc callBackFunc);
  20.  
  21.     [DllImport("accore.dll", CharSet = CharSet.Unicode,
  22.         CallingConvention = CallingConvention.Cdecl,
  23.         EntryPoint = "?acedRemoveFilterWinMsg@@YA_NQ6A_NPEAUtagMSG@@@Z@Z")]
  24.     private static extern bool acedRemoveFilterWinMsg(WindowHookProc callBackFunc);
  25.  
  26.     const int WM_KEYDOWN = 0x100; // Нажатие клавиши
  27.     const int WM_KEYUP = 0x101; // Отжатие клавиши
  28.     const int VK_ADD = 0x6B; // Клавиша +
  29.     const int VK_OEM_PLUS = 0xBB; // Клавиша + на цифровой клавиатуре
  30.  
  31.  
  32.     // Функция обратного вызова для хука
  33.     [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
  34.     public delegate bool WindowHookProc(ref System.Windows.Forms.Message msg);
  35.  
  36.     private static bool WindowsHook(
  37.       ref System.Windows.Forms.Message msg)
  38.     {
  39.       // проверяем структуру msg на то, что нас интересует,
  40.       // например, клавиши, движения мыши, и т.д.
  41.  
  42.       if (msg.Msg == WM_KEYDOWN)
  43.       {
  44.         if (msg.WParam == (IntPtr)VK_ADD || msg.WParam == (IntPtr)VK_OEM_PLUS)
  45.           // делаем что нужно
  46.           MessageBox.Show("Нажата клавиша +");
  47.       }
  48.  
  49.       return false;
  50.     }
  51.  
  52.     private static WindowHookProc callBackFunc = null;
  53.  
  54.     [CommandMethod("registerHook")]
  55.     public static void CmdRegisterHook()
  56.     {
  57.       if (callBackFunc != null)
  58.       {
  59.         acedRemoveFilterWinMsg(callBackFunc);
  60.       }
  61.       callBackFunc = new WindowHookProc(WindowsHook);
  62.       acedRegisterFilterWinMsg(callBackFunc);
  63.     }
  64.  
  65.     [CommandMethod("UnregisterHook")]
  66.     public static void CmdUnRegisterHook()
  67.     {
  68.       if (callBackFunc != null)
  69.       {
  70.         acedRemoveFilterWinMsg(callBackFunc);
  71.         callBackFunc = null;
  72.       }
  73.     }
  74.  
  75.   }
  76.  
  77. }
  78.  
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 06-10-2022, 20:14:28
Александр, не подскажите еще как сделать, чтобы на событие был ответ только моего плагина, а сам AutoCAD его не получал? Сейчас получается, что после отработки WindowsHook, например, обработки нажатия клавиши, AutoCAD также обрабатывает это нажатие
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 06-10-2022, 20:20:12

Александр, не подскажите еще как сделать, чтобы на событие был ответ только моего плагина, а сам AutoCAD его не получал? Сейчас получается, что после отработки WindowsHook, например, обработки нажатия клавиши, AutoCAD также обрабатывает это нажатие
Нужно возвращать из WindowsHook значение true
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 06-10-2022, 20:48:04
Если заменить на true, то после запуска плагина и ввода команды "registerHook" AutoCAD зависает. С false всё работает нормально, но не так как хочется
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 06-10-2022, 20:56:53
Если заменить на true, то после запуска плагина и ввода команды "registerHook" AutoCAD зависает.
Нужно отлаживать. Возможно ты зацикливаешь хук или наоборот не передаёшь в AutoCAD необходимые ему вещи.
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 06-10-2022, 20:58:13
Если заменить на true, то после запуска плагина и ввода команды "registerHook" AutoCAD зависает. С false всё работает нормально, но не так как хочется
О! Сообразил. Нужно вставить return true; сразу после MessageBox.Show("Нажата клавиша +");
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Кулаков Михаил от 06-10-2022, 21:11:05
Да, жаль я сам не догадался, что мы блокируем все сообщения, в том числе необходимые для работы AutoCAD. Спасибо!

PS Кнопку "Решение" я не нашёл (как указано у Вас в подписи)
Название: Re: Как реализовать Windows хук с использованием acedRegisterFilterWinMsg в .NET
Отправлено: Александр Ривилис от 06-10-2022, 21:27:09
PS Кнопку "Решение" я не нашёл (как указано у Вас в подписи)
Кнопка "Решения" появляется только у автора темы и только если в теме еще не было отмечено "Решение".