Форум программистов, компьютерный форум, киберфорум
C# .NET
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.58/40: Рейтинг темы: голосов - 40, средняя оценка - 4.58
55 / 44 / 5
Регистрация: 29.07.2009
Сообщений: 159
1

Как можно управлять лампочками (светодиодами) Num, Caps, Scroll

21.12.2010, 20:17. Показов 7892. Ответов 14
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Как можно управлять лампочками (светодиодами) Num, Caps, Scroll ? Сделал через эмуляцию нажатия NumLock, CapsLock и ScrollLock, но при этом буКвЫ сКАчУт, так что этот способ не подходит. В интернетах нашёл реализацию на C++, но как подобное провернуть на C# не знаю.
Заранее спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
21.12.2010, 20:17
Ответы с готовыми решениями:

Мигание лампочек Num, Caps, Scroll с временными паузами
Необходимо, чтобы определенная лампочка моргнула при выполнении определенного условия. ...

Включение/выключение caps num scroll
помогите сделать прогу которая Включает/выключает caps,num,scroll lock использую TASM 5.0 код пишу...

Acer aspire 5552G-N974G64Mikk Проблема с Caps Lock, Num Lock, Scroll Lock
Вообщем у меня такая же проблемма https://www.cyberforum.ru/notebooks/thread552722.html ...

Вывести на экран в символическом виде состояние NUM LOCK, CAPS LOCK и SCROLL LOCK
Помогите решить задачку на турбо си Выводить на экран в символическом виде состояние NUM LOCK,...

14
687 / 601 / 139
Регистрация: 08.05.2009
Сообщений: 1,098
21.12.2010, 20:39 2
C#
1
2
SendKeys.Send({CAPSLOCK});
SendKeys.Send({NUMLOCK});
1
55 / 44 / 5
Регистрация: 29.07.2009
Сообщений: 159
21.12.2010, 20:51  [ТС] 3
Бельфегор, спасибо за ответ, но я просил индикацию напрямую, а не через эмуляцию нажатия клавиш. Кстати, Вы забыли про кавычки
C#
1
2
SendKeys.Send("{CAPSLOCK}");
SendKeys.Send("{NUMLOCK}");
З.Ы.:Код не работает (индикации нет) да это и не важно, эмулировать нажатие клавиш я и без этого умею =)
0
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
21.12.2010, 20:52 4
Oxygen, реализацию на C++ представь сюда.
0
55 / 44 / 5
Регистрация: 29.07.2009
Сообщений: 159
21.12.2010, 21:04  [ТС] 5
Поскольку правилами форума запрещено давать ссылки на сторонние ресурсы, то выложу найденные мной исходники и саму софтину. (это C++ если не ошибаюсь)
Вложения
Тип файла: zip NTKbdLites_src.zip (6.1 Кб, 103 просмотров)
Тип файла: zip NTKbdLites_demo.zip (24.2 Кб, 75 просмотров)
0
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
21.12.2010, 21:21 6
В принципе перевести вполне возможно (с первого взгляда). Попробую сегодня или в ближайшие дни
1
687 / 601 / 139
Регистрация: 08.05.2009
Сообщений: 1,098
21.12.2010, 22:38 7
Код включает выключает num,scroll,caps lock-и по таймеру

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;
 
namespace WindowsFormsApplication1
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll")]
        static extern void keybd_event(byte bVk, byte bScan, uint dwFlags, UIntPtr dwExtraInfo);
        const byte CapsLock = 0x14,NumLock=0x90,ScrollLock=0x91;
        const uint KEYEVENTF_KEYUP = 0x02;
        bool tf=false;
       public Form1()
        {
            InitializeComponent();
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            switch (tf)
            {
                case false:
                    keybd_event(CapsLock, 0, 0, UIntPtr.Zero);
                    keybd_event(NumLock, 0, 0, UIntPtr.Zero);
                    keybd_event(ScrollLock, 0, 0, UIntPtr.Zero);
                    tf = true;
                    break;
                case true:
                    keybd_event(NumLock, 0, KEYEVENTF_KEYUP, UIntPtr.Zero);
                    keybd_event(CapsLock, 0, KEYEVENTF_KEYUP, UIntPtr.Zero);
                    keybd_event(ScrollLock, 0, KEYEVENTF_KEYUP, UIntPtr.Zero);
                    tf = false;
                    break;
            }
        }
    }
}
1
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
21.12.2010, 22:47 8
Лучший ответ Сообщение было отмечено как решение

Решение

Бельфегор, мИнуС тАКоГо ВарИаНта... я думаю тебе понятен

Это не полностью переписанный пример, не хватает только реализации мигания в потоке.
Oxygen, это уж сам как-нибудь а то не интересно будет:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
using System.Runtime.InteropServices;
...
    unsafe static class FlashLights
    {
        const uint GENERIC_WRITE = 0x40000000;
        const uint OPEN_EXISTING = 0x3;
 
        const uint IOCTL_KEYBOARD_QUERY_INDICATORS = 0xB0040;
        const uint IOCTL_KEYBOARD_SET_INDICATORS = 0xB0008;
 
        enum DOS_DEVICES : uint
        {
            RAW_TARGET_PATH = 0x00000001,
            REMOVE_DEFINITION = 0x00000002,
            EXACT_MATCH_ON_REMOVE = 0x00000004,
            NO_BROADCAST_SYSTEM = 0x00000008,
            LUID_BROADCAST_DRIVE = 0x00000010
        }
 
        public enum KEYBOARD_KEY : uint
        {
            CAPS_LOCK_ON = 4,
            NUM_LOCK_ON = 2,
            SCROLL_LOCK_ON = 1
        }
 
        struct KEYBOARD_INDICATOR_PARAMETERS
        {
            internal ushort UnitId;     // Unit identifier.
            internal ushort LedFlags;   // LED indicator state.
        }
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool DefineDosDevice (
            [In] DOS_DEVICES dwFlags,
            [In] string lpDeviceName,
            [In] string lpTargetPath
            );
 
        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr CreateFile (
            [In] string lpFileName,
            [In] uint dwDesiredAccess,
            [In] uint dwShareMode,
            [In] IntPtr lpSecurityAttributes,
            [In] uint dwCreationDisposition,
            [In] uint dwFlagsAndAttributes,
            [In] IntPtr hTemplateFile
            );
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool CloseHandle ( [In] IntPtr hObject );
 
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        static extern bool DeviceIoControl (
            [In] IntPtr hDevice,
            [In] uint dwIoControlCode,
            [In] KEYBOARD_INDICATOR_PARAMETERS* lpInBuffer,
            [In] uint nInBufferSize,
            [Out] KEYBOARD_INDICATOR_PARAMETERS* lpOutBuffer,
            [In] uint nOutBufferSize,
            [Out] uint* lpBytesReturned,
            [In, Out] IntPtr lpOverlapped
            );
 
        static IntPtr hKbdDev;
        /// <summary>
        /// Должно вызываться первым для того чтобы подготовить устройство для использования.
        /// </summary>
        /// <returns>Номер ошибки.</returns>
        public static int OpenKeyboardDevice () {
            if (!DefineDosDevice(DOS_DEVICES.RAW_TARGET_PATH, "Kbd", "\\Device\\KeyboardClass0"))
                return Marshal.GetLastWin32Error();
 
            hKbdDev = CreateFile("\\\\.\\Kbd", GENERIC_WRITE, 0U, IntPtr.Zero, OPEN_EXISTING, 0U, IntPtr.Zero);
 
            if (hKbdDev == (IntPtr)(-1))
                return Marshal.GetLastWin32Error();
 
            return 0;
        }
        /// <summary>
        /// Закрывает устройство.
        /// </summary>
        /// <returns>Номер ошибки.</returns>
        public static int Close () {
            int err = 0;
 
            if (!DefineDosDevice(DOS_DEVICES.REMOVE_DEFINITION, "Kbd", null))
                err = Marshal.GetLastWin32Error();
 
            if (!CloseHandle(hKbdDev))
                err = Marshal.GetLastWin32Error();
 
            return err;
        }
        /// <summary>
        /// Мигание одной из 3х лампочек: NUM, SCROLL, CAPS.
        /// </summary>
        /// <param name="LightFlag">Индикатор.</param>
        /// <param name="Duration">Промежуток времени между затуханием и появлением.</param>
        /// <returns>Номер ошибки.</returns>
        public static int FlashKeyboardLight ( KEYBOARD_KEY LightFlag, int Duration ) {
            KEYBOARD_INDICATOR_PARAMETERS
                inBuff = new KEYBOARD_INDICATOR_PARAMETERS(),
                outBuff = new KEYBOARD_INDICATOR_PARAMETERS();
 
            uint LedFlag = (uint)LightFlag;
            uint ledFlagsMask;
            uint toggle;
            uint dataLen = (uint)Marshal.SizeOf(typeof(KEYBOARD_INDICATOR_PARAMETERS));
            uint retLength = 0;
 
            inBuff.UnitId = 0;
            outBuff.UnitId = 0;
 
            if (!DeviceIoControl(hKbdDev, IOCTL_KEYBOARD_QUERY_INDICATORS,
                &inBuff, dataLen, &outBuff, dataLen, &retLength, IntPtr.Zero))
                return Marshal.GetLastWin32Error();
 
            ledFlagsMask = (outBuff.LedFlags & (~LedFlag));
            toggle = (outBuff.LedFlags & LedFlag);
 
            for (int i = 0; i < 2; i++) {
                toggle ^= 1;
                inBuff.LedFlags = (ushort)(ledFlagsMask | (LedFlag * toggle));
 
                if (!DeviceIoControl(hKbdDev, IOCTL_KEYBOARD_SET_INDICATORS,
                    &inBuff, dataLen, null, 0, &retLength, IntPtr.Zero))
                    return Marshal.GetLastWin32Error();
 
                System.Threading.Thread.Sleep(Duration);
            }
 
            return 0;
        }
    }
Использование:
C#
1
2
3
4
FlashLights.OpenKeyboardDevice();
for (int i = 0; i < 3; i++)
    FlashLights.FlashKeyboardLight(FlashLights.KEYBOARD_KEY.CAPS_LOCK_ON, 350);
FlashLights.Close();
Обязательно вызывать метод Close когда завершил работу с индикаторами!

При желании можно переписать без использования unsafe.

З.Ы. т.к. работа ведется с функциями, которые работают с устройствами на довольно низком уровне (а именно функция DeviceIoControl), то я за возможные последствия не отвечаю
4
55 / 44 / 5
Регистрация: 29.07.2009
Сообщений: 159
22.12.2010, 13:34  [ТС] 9
SSTREGG, спасибо большое! С потоками сам разберусь =)
0
19 / 34 / 11
Регистрация: 09.10.2010
Сообщений: 420
22.02.2012, 00:35 10
SSTREGG, к сожалению на внешней клавиатуре не моргает, на ноутбуке -да. Как это можно исправить?
0
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
22.02.2012, 01:37 11
ai-zer, данный код работает для клавиатур подключенных через PS/2, через USB не работает.
0
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
23.06.2013, 01:46 12
Лучший ответ Сообщение было отмечено NickoTin как решение

Решение

Описание способа, который не зависит от типа клавиатуры.

Код на C
KbdLED.h
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef KBDLED_H_
#define KBDLED_H_
 
#include <Windows.h>
 
#define KEYBOARD_CAPS_LOCK_ON     4
#define KEYBOARD_NUM_LOCK_ON      2
#define KEYBOARD_SCROLL_LOCK_ON   1
 
typedef PVOID HKBD;
 
typedef struct _KBD_DEVPATH_LIST {
    struct _KBD_DEVPATH_LIST* Next;
    DWORD chLength;
    DWORD cbSize;
    TCHAR DevicePath[ANYSIZE_ARRAY];
} KBD_DEVPATH_LIST, *PKBD_DEVPATH_LIST;
 
PKBD_DEVPATH_LIST GetKeyboardsList();
 
BOOL FreeKeyboardsListMemory(PKBD_DEVPATH_LIST pFirst);
 
HKBD OpenKeyboard(PKBD_DEVPATH_LIST kbd);
 
BOOL CloseKeyboard(HKBD hKbd);
 
BOOL SetLedState(HKBD hKbd, USHORT ledFlags);
 
#endif
KbdLED.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "KbdLED.h"
#include <SetupAPI.h>
 
#pragma comment(lib, "Setupapi.lib")
 
#if defined(_UNICODE)
#define _T(x) L ##x
#else
#define _T(x) x
#endif
 
#define IOCTL_KEYBOARD_SET_INDICATORS   CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0002, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
#define GET_DIDD(x) ((PSP_DEVICE_INTERFACE_DETAIL_DATA)((PBYTE)(x) + FIELD_OFFSET(KBD_DEVPATH_LIST, cbSize)))
 
const GUID GUID_DEVINTERFACE_KEYBOARD = { 0x884b96c3, 0x56ef, 0x11d1, 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd };
 
typedef struct _KEYBOARD_INDICATOR_PARAMETERS {
    //
    // Unit identifier.  Specifies the device unit for which this
    // request is intended.
    //
    USHORT UnitId;
 
    //
    // LED indicator state.
    //
    USHORT LedFlags;
} KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS;
 
PKBD_DEVPATH_LIST GetKeyboardsList()
{
    HDEVINFO                 hKbdDev = NULL;
    DWORD                    devIndex;
    SP_DEVICE_INTERFACE_DATA devIntfsData = {0};
    PKBD_DEVPATH_LIST        retList = NULL;
    PKBD_DEVPATH_LIST        previous = NULL;
 
    hKbdDev = SetupDiGetClassDevs( &GUID_DEVINTERFACE_KEYBOARD, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
 
    if ( INVALID_HANDLE_VALUE == hKbdDev ) {
        OutputDebugString(_T("SetupDiGetClassDevs call failed.\r\n"));
        return NULL;
    }
 
    devIntfsData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
 
    for (devIndex = 0;
         SetupDiEnumDeviceInterfaces(hKbdDev, NULL, &GUID_DEVINTERFACE_KEYBOARD, devIndex, &devIntfsData);
         devIndex++)
    {
        DWORD               buffSize;
        PKBD_DEVPATH_LIST   current;
 
        SetupDiGetDeviceInterfaceDetail( hKbdDev, &devIntfsData, NULL, 0, &buffSize, NULL );
 
        if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) {
            OutputDebugString(_T("SetupDiGetDeviceInterfaceDetail first call failed.\r\n"));
            continue;
        }
 
        current = malloc(FIELD_OFFSET(KBD_DEVPATH_LIST, cbSize) + buffSize);
 
        if ( !current ) {
            OutputDebugString(_T("malloc call failed.\r\n"));
            continue;
        }
 
        current->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        current->chLength = (buffSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA, DevicePath)) / sizeof(TCHAR);
 
        if ( !SetupDiGetDeviceInterfaceDetail(hKbdDev, &devIntfsData, GET_DIDD(current), buffSize, NULL, NULL) ) {
            OutputDebugString(_T("SetupDiGetDeviceInterfaceDetail second call failed.\r\n"));
            free(current);
            continue;
        }
        
        if ( previous )
            previous->Next = current;
        if ( !retList )
            retList = current;
 
        current->Next = NULL;
        previous = current;
    }
 
    SetupDiDestroyDeviceInfoList(hKbdDev);
    return retList;
}
 
BOOL FreeKeyboardsListMemory(PKBD_DEVPATH_LIST pFirst)
{
    PKBD_DEVPATH_LIST next = NULL;
 
    if ( !pFirst )
        return FALSE;
    
    do {
        next = pFirst->Next;
        free(pFirst);
        pFirst = next;
    } while ( next );
 
    return TRUE;
}
 
typedef struct _KBD_INFO
{
    HANDLE hDevice;
    PKBD_DEVPATH_LIST kbd;
} KBD_INFO, *PKBD_INFO;
 
HKBD OpenKeyboard(PKBD_DEVPATH_LIST kbd)
{
    PKBD_INFO kbdInfo;
    HANDLE    hDevice;
 
    if ( !kbd )
        return NULL;
 
    hDevice = CreateFile(kbd->DevicePath, 0, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
 
    if ( INVALID_HANDLE_VALUE == hDevice ) {
        OutputDebugString(_T("CreateFile call failed.\r\n"));
        return NULL;
    }
 
    kbdInfo = malloc(sizeof(KBD_INFO));
    kbdInfo->hDevice = hDevice;
    kbdInfo->kbd = kbd;
 
    return kbdInfo;
}
 
BOOL CloseKeyboard(HKBD hKbd)
{
    if ( !hKbd )
        return FALSE;
 
    if ( !CloseHandle((*(PKBD_INFO)hKbd).hDevice) )
        return FALSE;
 
    free(hKbd);
    return TRUE;
}
 
BOOL SetLedState(HKBD hKbd, USHORT ledFlags)
{
    KEYBOARD_INDICATOR_PARAMETERS kip;
    DWORD zero;
 
    if ( !hKbd )
        return FALSE;
 
    kip.LedFlags = ledFlags;
 
    return DeviceIoControl(
                (*(PKBD_INFO)hKbd).hDevice, IOCTL_KEYBOARD_SET_INDICATORS, 
                &kip, sizeof(kip), NULL, 0, &zero, NULL);
}
main.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <Windows.h>
#include "KbdLED.h"
 
int main()
{
    HKBD              hKbd;
    PKBD_DEVPATH_LIST kbdList;
 
    kbdList = GetKeyboardsList();
    hKbd = OpenKeyboard(kbdList);
 
    if ( !SetLedState(hKbd, KEYBOARD_CAPS_LOCK_ON) )
        printf("SetLedState failed...\r\n");
    
    CloseKeyboard(hKbd);
    FreeKeyboardsListMemory(kbdList);
    return 0;
}

Если кому-то нужно могу перевести на C#, но только если кому-то нужно...
1
3 / 3 / 0
Регистрация: 12.02.2015
Сообщений: 7
12.02.2015, 15:54 13
Цитата Сообщение от NickoTin Посмотреть сообщение
Описание способа, который не зависит от типа клавиатуры.

Код на C
KbdLED.h
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef KBDLED_H_
#define KBDLED_H_
 
#include <Windows.h>
 
#define KEYBOARD_CAPS_LOCK_ON     4
#define KEYBOARD_NUM_LOCK_ON      2
#define KEYBOARD_SCROLL_LOCK_ON   1
 
typedef PVOID HKBD;
 
typedef struct _KBD_DEVPATH_LIST {
    struct _KBD_DEVPATH_LIST* Next;
    DWORD chLength;
    DWORD cbSize;
    TCHAR DevicePath[ANYSIZE_ARRAY];
} KBD_DEVPATH_LIST, *PKBD_DEVPATH_LIST;
 
PKBD_DEVPATH_LIST GetKeyboardsList();
 
BOOL FreeKeyboardsListMemory(PKBD_DEVPATH_LIST pFirst);
 
HKBD OpenKeyboard(PKBD_DEVPATH_LIST kbd);
 
BOOL CloseKeyboard(HKBD hKbd);
 
BOOL SetLedState(HKBD hKbd, USHORT ledFlags);
 
#endif
KbdLED.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
#include "KbdLED.h"
#include <SetupAPI.h>
 
#pragma comment(lib, "Setupapi.lib")
 
#if defined(_UNICODE)
#define _T(x) L ##x
#else
#define _T(x) x
#endif
 
#define IOCTL_KEYBOARD_SET_INDICATORS   CTL_CODE(FILE_DEVICE_KEYBOARD, 0x0002, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
#define GET_DIDD(x) ((PSP_DEVICE_INTERFACE_DETAIL_DATA)((PBYTE)(x) + FIELD_OFFSET(KBD_DEVPATH_LIST, cbSize)))
 
const GUID GUID_DEVINTERFACE_KEYBOARD = { 0x884b96c3, 0x56ef, 0x11d1, 0xbc, 0x8c, 0x00, 0xa0, 0xc9, 0x14, 0x05, 0xdd };
 
typedef struct _KEYBOARD_INDICATOR_PARAMETERS {
    //
    // Unit identifier.  Specifies the device unit for which this
    // request is intended.
    //
    USHORT UnitId;
 
    //
    // LED indicator state.
    //
    USHORT LedFlags;
} KEYBOARD_INDICATOR_PARAMETERS, *PKEYBOARD_INDICATOR_PARAMETERS;
 
PKBD_DEVPATH_LIST GetKeyboardsList()
{
    HDEVINFO                 hKbdDev = NULL;
    DWORD                    devIndex;
    SP_DEVICE_INTERFACE_DATA devIntfsData = {0};
    PKBD_DEVPATH_LIST        retList = NULL;
    PKBD_DEVPATH_LIST        previous = NULL;
 
    hKbdDev = SetupDiGetClassDevs( &GUID_DEVINTERFACE_KEYBOARD, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
 
    if ( INVALID_HANDLE_VALUE == hKbdDev ) {
        OutputDebugString(_T("SetupDiGetClassDevs call failed.\r\n"));
        return NULL;
    }
 
    devIntfsData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
 
    for (devIndex = 0;
         SetupDiEnumDeviceInterfaces(hKbdDev, NULL, &GUID_DEVINTERFACE_KEYBOARD, devIndex, &devIntfsData);
         devIndex++)
    {
        DWORD               buffSize;
        PKBD_DEVPATH_LIST   current;
 
        SetupDiGetDeviceInterfaceDetail( hKbdDev, &devIntfsData, NULL, 0, &buffSize, NULL );
 
        if ( GetLastError() != ERROR_INSUFFICIENT_BUFFER ) {
            OutputDebugString(_T("SetupDiGetDeviceInterfaceDetail first call failed.\r\n"));
            continue;
        }
 
        current = malloc(FIELD_OFFSET(KBD_DEVPATH_LIST, cbSize) + buffSize);
 
        if ( !current ) {
            OutputDebugString(_T("malloc call failed.\r\n"));
            continue;
        }
 
        current->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
        current->chLength = (buffSize - FIELD_OFFSET(SP_DEVICE_INTERFACE_DETAIL_DATA, DevicePath)) / sizeof(TCHAR);
 
        if ( !SetupDiGetDeviceInterfaceDetail(hKbdDev, &devIntfsData, GET_DIDD(current), buffSize, NULL, NULL) ) {
            OutputDebugString(_T("SetupDiGetDeviceInterfaceDetail second call failed.\r\n"));
            free(current);
            continue;
        }
        
        if ( previous )
            previous->Next = current;
        if ( !retList )
            retList = current;
 
        current->Next = NULL;
        previous = current;
    }
 
    SetupDiDestroyDeviceInfoList(hKbdDev);
    return retList;
}
 
BOOL FreeKeyboardsListMemory(PKBD_DEVPATH_LIST pFirst)
{
    PKBD_DEVPATH_LIST next = NULL;
 
    if ( !pFirst )
        return FALSE;
    
    do {
        next = pFirst->Next;
        free(pFirst);
        pFirst = next;
    } while ( next );
 
    return TRUE;
}
 
typedef struct _KBD_INFO
{
    HANDLE hDevice;
    PKBD_DEVPATH_LIST kbd;
} KBD_INFO, *PKBD_INFO;
 
HKBD OpenKeyboard(PKBD_DEVPATH_LIST kbd)
{
    PKBD_INFO kbdInfo;
    HANDLE    hDevice;
 
    if ( !kbd )
        return NULL;
 
    hDevice = CreateFile(kbd->DevicePath, 0, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
 
    if ( INVALID_HANDLE_VALUE == hDevice ) {
        OutputDebugString(_T("CreateFile call failed.\r\n"));
        return NULL;
    }
 
    kbdInfo = malloc(sizeof(KBD_INFO));
    kbdInfo->hDevice = hDevice;
    kbdInfo->kbd = kbd;
 
    return kbdInfo;
}
 
BOOL CloseKeyboard(HKBD hKbd)
{
    if ( !hKbd )
        return FALSE;
 
    if ( !CloseHandle((*(PKBD_INFO)hKbd).hDevice) )
        return FALSE;
 
    free(hKbd);
    return TRUE;
}
 
BOOL SetLedState(HKBD hKbd, USHORT ledFlags)
{
    KEYBOARD_INDICATOR_PARAMETERS kip;
    DWORD zero;
 
    if ( !hKbd )
        return FALSE;
 
    kip.LedFlags = ledFlags;
 
    return DeviceIoControl(
                (*(PKBD_INFO)hKbd).hDevice, IOCTL_KEYBOARD_SET_INDICATORS, 
                &kip, sizeof(kip), NULL, 0, &zero, NULL);
}
main.c
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <Windows.h>
#include "KbdLED.h"
 
int main()
{
    HKBD              hKbd;
    PKBD_DEVPATH_LIST kbdList;
 
    kbdList = GetKeyboardsList();
    hKbd = OpenKeyboard(kbdList);
 
    if ( !SetLedState(hKbd, KEYBOARD_CAPS_LOCK_ON) )
        printf("SetLedState failed...\r\n");
    
    CloseKeyboard(hKbd);
    FreeKeyboardsListMemory(kbdList);
    return 0;
}

Если кому-то нужно могу перевести на C#, но только если кому-то нужно...
День добрый!
Мне очень нужен этот код на C#, поэтому прошу перевести, если можно, заранее спасибо.
0
Почетный модератор
Эксперт .NET
8722 / 3674 / 404
Регистрация: 14.06.2010
Сообщений: 4,513
Записей в блоге: 9
14.02.2015, 16:16 14
Проект в аттаче. Использование:
C#
1
2
3
4
5
6
7
foreach ( var kbd in new KeyboardEnumerator() )
{
    using ( kbd.Open() )
    {
        kbd.LedState = // led flags combination
    }
}
Определения "основной" клавиатуры нет.
Вложения
Тип файла: zip KeyboardLedState.zip (10.3 Кб, 86 просмотров)
1
3 / 3 / 0
Регистрация: 12.02.2015
Сообщений: 7
16.02.2015, 08:27 15
Отлично работает, спасибо большое!!!
0
16.02.2015, 08:27
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.02.2015, 08:27
Помогаю со студенческими работами здесь

Клавиатура мигает всеми тремя индикаторами Caps Lock, Scroll Lock и Num Lock и соответственно не работает!
Здравствуйте парни и девушки! Столкнулся с такой проблемой! Имеется клавиатура Genius Ergomedia...

Работа с клавиатурой (клавиши num lock, caps lock, scroll lock)
определить состояние статуса клавиш &quot; num lock, caps lock,scroll lock &quot; с отображением и их...

Как по 1му каналу ШИМ управлять 2мя светодиодами?
Можно ли легко организовать управление 2мя светодиодами по одному каналу ШИМ, так чтобы...

поочередное включение num-caps
Здравствуйте всем, нужна помощь, в этом языке вообще не силен, а дали лабу сделать... даже не знаю...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru