Каталог решений - Внешняя компонента — универсальный, надежный перехватчик клавиатурных событий

Внешняя компонента — универсальный, надежный перехватчик клавиатурных событий

Внешняя компонента — универсальный, надежный перехватчик клавиатурных событий

В наличии

Перехват нажатия клавиш в 1С реализован с привязкой к фокусу формы. Если форма (или главное окно процесса 1С) теряет фокус, то перехват перестает работать.
Чтобы решить эту проблему, была разработана соответствующая внешняя компонента.

Категория:

Описание

Как работает.

Использован механизм SetWindowsHookEx с флагом "WH_KEYBOARD_LL".

Механизм перехвата работает через отправку сообщений процессу приложения, установившему перехват. Это влечет за собой 2 последствия.

1.Внедрение DLL компоненты (т.е. нашего кода) для обработки callback-вызовов в адресное пространство других процессов не происходит. 

2. При остановке потока 1с, установившего перехват (ошибка в коде, остановка отладчиком, зависание процесса 1с и т.д.) никаких негативных последствий ни для других процессов, ни для операционной системы не происходит. Субьективно это воспринимается пользователем как кратковременная (1-3 сек), однократная задержка реакции на нажатие кнопки. В этом случае операционка просто исключает обработчик зависшего процесса из цепочки обработчиков перехвата. Для возобновления перехвата — потребуется его перезапустить.

Механизм сильно Generic и поэтому теоретически будет работать довольно надежно на всех семействах операционок от Майки (Windows 9x, Windows NT, Windows Server) — 32 и 64-разрядных. Без каких-либо дополнительных фреймворков и сред.

Кроме очевидного использования — для перехвата нажатия кнопок в 1с — вне зависимости от положения фокуса, навскидку видятся еще следующие применения:

— в качестве перехватчика данных, получаемых от других устройств клавиатурного ввода (сканеры, ридеры и т.д.)

— иное применение :).

Установка компоненты:

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	УстановитьВнешнююКомпоненту("ОбщийМакет.KbdHook");
	ПодключитьВнешнююКомпоненту("ОбщийМакет.KbdHook", "СС",ТипВнешнейКомпоненты.Native);
	
	//ПодключитьВнешнююКомпоненту("C:\C++\KbdHook\x64\Release\KbdHook64.dll", "СС", ТипВнешнейКомпоненты.Native);
	
	ВК =  Новый("AddIn.СС.KbdHook");
КонецПроцедуры

Запуск перехвата:

&НаКлиенте
Процедура УстановитьКрючок(Команда)
    //Если параметр Истина, то компонента возвращает - строчное представление шестнадцатеричного значения двойного слова (4 байта).
    //Если ложь - системную интерпретацию названия нажатой кнопки (зависит от локализации ОС).

	Сообщить(ВК.УстановитьПерехват(истина));

КонецПроцедуры

Остановка перехвата:

&НаКлиенте
Процедура СнятьКрючок(Команда)
	Сообщить(ВК.СнятьПерехват());
КонецПроцедуры

Обработка callback-вызова:

//Модуль приложения
Процедура ОбработкаВнешнегоСобытия(Источник, Событие, Данные)
	 Оповестить(Событие,Данные,Источник)
КонецПроцедуры


//Модуль формы
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	
	ЧтениеДжей = новый ЧтениеJSON;
	ЧтениеДжей.УстановитьСтроку(Параметр);
	стк = ПрочитатьJSON(ЧтениеДжей);
	ЧтениеДжей.Закрыть();
	
	ЭтаФорма.Реквизит1 = ЭтаФорма.Реквизит1 + стк.key;
	Сообщить(Параметр);
КонецПроцедуры

Json-структура, возвращаемая в 1с компонентой:

{
	"Alt" : false,
	"Ctrl" : false,
	"Key" : "0x00390001",
	"Shift" : false
}

Немного о структуре поля Key.

Если включен режим возврата скан-кода нажатой клавиши, то возвращается строка вида:

0x00100001

Справа-налево:

байт 0: всегда = 1.

байт 1: всегда = 0.

байт 2: скан-код нажатой клавиши (https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/scancode.doc)

байт 3: флаг — является-ли нажатая клавиша расширенной клавишей (клавиша Windows, Системное меню и т.д.), возможные значения: 0-1.

Самый старший байт — слева.

Тестировалось на платформе версии: 8.3.18.1334

Исходники: https://github.com/KotVezdehod/KbdHook

has been added to your cart:
Оформление заказа