Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Помигать диодами NumLock, CapsLock...


Автор: NUCLEuS 8.4.2006, 18:45
Привет всем!

Интересует как можно помигать диодами NUM_LOCK, CAPS_LOCK, SCROLL_LOCK. НО, реализовать это нужно через порт клавиатуры, а не с помощью Post/Send message. Т.е. на самом низком уровне. Вот. Буду очень благодарен, если кто нибудь сможет помочь.
Спасибо.


M
Girder
Поиск... http://forum.vingrad.ru/index.php?act=Search&f=2
Совсем не давно обсуждалось!

Автор: Poseidon 8.4.2006, 18:51
Способ для 9x (на NT не работает):
Код

var 
 KeyState : TKeyboardState; 
begin 
 GetKeyboardState(KeyState); 
 KeyState[VK_SCROLL] := KeyState[VK_SCROLL] xor 1; 
 KeyState[VK_CAPITAL] := KeyState[VK_CAPITAL] xor 1; 
 KeyState[VK_NUMLOCK] := KeyState[VK_NUMLOCK] xor 1; 
 SetKeyboardState (KeyState); 
end;  


Способ для NT (на 9x не работает):
Код

begin 
  keybd_event (VK_SCROLL, 0, KEYEVENTF_EXTENDEDKEY, 0); 
  keybd_event (VK_SCROLL, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0); 

  keybd_event (VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY, 0); 
  keybd_event (VK_CAPITAL, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0); 

  keybd_event (VK_NUMLOCK, 0, KEYEVENTF_EXTENDEDKEY, 0); 
  keybd_event (VK_NUMLOCK, 0, KEYEVENTF_EXTENDEDKEY or KEYEVENTF_KEYUP, 0); 
end; 

Автор: NUCLEuS 8.4.2006, 23:18
Poseidon, спасибо конечно, но это что, работа через порт?

Я имею ввиду напрямую smile
Добавлено @ 23:25
Girder
Извини что засоряю форум подобными сообщениями, но поиск не нашёл ничего стоящего...
Мож. это я так искал smile

Автор: Girder 9.4.2006, 13:41
Цитата(NUCLEuS @ 9.4.2006, 00:18 Найти цитируемый пост)
Я имею ввиду напрямую
А... ты об ентом. Но енто тоже имхо... обсуждалось. Искать лень... так что сделай типо так.

Скачиваеш TDriver(см. прикрепленную тему в ентом разделе)... устанавливаеш его...

Далее типо так:
Код
 Driver1.SetPort($50,$70,true);
 //while (Driver1.PortInOut[$64] and 2 <> 0) do;
 Driver1.PortInOut[$60]:=$ed;
 {0бит - включить светодиод Scroll Lock;
  1бит - включить светодиод Num Lock;
  2бит - включить светодиод Caps Lock;}
 Driver1.PortInOut[$60]:=$2; //включаем Num Lock


PS: Не проверял...

Автор: NUCLEuS 10.4.2006, 00:00
Girder, спасибо тебе большое smile Щас проверю.

Автор: NUCLEuS 10.4.2006, 00:18
Girder,
проверил - не работает smile

Вылетает на

Driver1.PortInOut[$60]:=$ed;

Если убрать эту строку, то вылетает на следующей (Driver1.PortInOut[$60]:=$2;).
Говорит

External exeption C0000008

Поправка : посмотрел в отладчике - вылет происходит из-за SetPort функции... А если её вызов убрать то будет Error : Privileged instruction. (как я понял эта функция может открывать порты I/O в NT (а я чёт думал что тут без ring0 не обойтись smile ))

Что тут можно сделать?

Автор: Girder 10.4.2006, 09:10
Цитата(NUCLEuS @ 10.4.2006, 01:18 Найти цитируемый пост)
Если убрать эту строку, то вылетает на следующей (Driver1.PortInOut[$60]:=$2;).
Говорит

External exeption C0000008
Просто жми F9 smile ... енто же исключение обрабатывается внутри компонента smile . Если тебе енто раздражает... то просто запускай не из под Delphi smile

Цитата(NUCLEuS @ 10.4.2006, 01:18 Найти цитируемый пост)
проверил - не работает

Ну просто там нету задержи... или к примеру можно сделать проверку занятости... т.е. вот так:
Код
 Driver1.SetPort($60,$70,true);
 while (Driver1.PortInOut[$64] and 2 <> 0) do;
 Driver1.PortInOut[$60]:=$ed;
 while (Driver1.PortInOut[$64] and 2 <> 0) do;
 Driver1.PortInOut[$60]:=$2; //Num Lock


PS: Проверил... работает smile Ты только NumLock отключи... так как енто я сделал "зажигание" его smile

Автор: NUCLEuS 10.4.2006, 14:19
Girder, да, работает, спасибо smile

Но мне как всегда хочется всё сделать самому и на самом низком уровне smile

Поэтому начал разбирать твой компонент и понял что без ring0 тут всё таки не обошлось smile
Насколько я понял, ты загнал свой ring0 драйвер в массив (gwiopm_sys) я подумал что это драйвер потому что первые байты 4D 5A (MZ) как раз PE заголовка. smile Классный способ, я даже и не думал что так можно сделать smile

Так вот, это уже Off Topic, но мне очень интересно, как ты написал этот самый драйвер, очень хочется увидеть исходник, я тоже хочу научиться писать ring0 драйвера... И интересно как твой драйвер функционирует? Просто даёт вызвавшему приложению ring0 права? Интересно очень...


И, если можешь, дай пожалуйста исходник этого драйвера smile

Автор: Girder 10.4.2006, 14:34
Он не мой.

PS: http://www.wideman-one.com/gw/tech/Delphi/iopm/gwiopm_code.htm
http://www.wideman-one.com/gw/tech/Delphi/iopm/

Автор: NUCLEuS 10.4.2006, 14:50
Girder,
ок,почитаю smile

А можешь объяснить эти строчки кода

Код

Driver1.SetPort($50,$70,true);


Start Port = $50
End Port = $70

Это ты разрешаешь работу с портами от $50 до $70 вызывающему приложению? Или не так smile

Код

Driver1.PortInOut[$60]:=$ed;


Это тоже непонятно ты посылаешь на порт $60 (кстати, почему $60?) 11101101, зачем?

Автор: Girder 10.4.2006, 15:37
1. Вообще-то в TDriver-е енто написано... что делает ента функция.
PS: Модифицируется карта разрешения ввода-вывода.

2. енто команда... Set/Reset Mode Indicators

Автор: NUCLEuS 10.4.2006, 19:34
Ок, огромное спасибо за всю информацию что ты мне дал smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)