3 / 3 / 2
Регистрация: 27.06.2013
Сообщений: 94
1

Программно эмулировать нажатие клавиш, различая регистр и раскладку клавиатуры

22.02.2015, 05:32. Показов 2369. Ответов 3
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Функция keybd_event корректно воспринимает только большие латинские буквы. Регистр и раскладка определяются нажатием клавиш CapsLock и Shift и текущей раскладкой клавиатуры. Знаю, как делать, если символы - английские буквы и цифры. Определяю нажата ли клавиша CapsLock, определяю, верхний или нижний символ, и эмулирую при необходимости нажатие Shift. Есть ли простой и универсальный способ программно отправить символ, как он есть в прочитанной строке?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.02.2015, 05:32
Ответы с готовыми решениями:

Как эмулировать нажатие клавиш клавиатуры?
Интересует нажатие клавиши вниз - keyCode: 40 При фокусе select необходимо программное нажатие. ...

Как в HTML эмулировать нажатие клавиш клавиатуры?
Подскажите, пожалуйста, как в HTML странице программно эмулировать нажатие клавиш клавиатуры. ...

Как эмулировать нажатие клавиш int 16h
Здравствуйте, работаю вот с 05h, хочу эмулировать нажатие клавиши. mov al, 02h mov ah, 05h mov...

Как эмулировать нажатие клавиш в иное приложение
Проблема Делал приложение которое должно в другую программу вводить сэмулированные нажатия...

3
120 / 142 / 46
Регистрация: 31.10.2014
Сообщений: 721
Записей в блоге: 1
22.02.2015, 06:05 2
SendInput
0
3 / 3 / 2
Регистрация: 27.06.2013
Сообщений: 94
23.02.2015, 01:54  [ТС] 3
Пишу на C# с использованием WinAPI. Задаю в этом разделе, так как раздела WinAPI для C# нет. Для тестирования просто запускаю программу и открываю Блокнот Windows. Установлена задержка по таймеру, пока открывается Блокнот. Реальное приложение делает необходимое окно активным через WinAPI.
Пример c SendInput взял отсюда: http://www.ownedcore.com/forum... ple-c.html
Сократил то, что не используется. Добавил флаг WindowsAPI.KEYEVENTF_SCANCODE, без него программа не работает. С флагом WindowsAPI.KEYEVENTF_SCANCODE или с флагом WindowsAPI.KEYEVENTF_UNICODE работает, но все равно не различает корректно регистр и раскладку. С флагом WindowsAPI.KEYEVENTF_SCANCODE выдает jhjjhgjg12345678901;5;/890- вместо исходной строчки. Что здесь не так?

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
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Input;
using System.Diagnostics;
 
namespace SendTextForms1
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            TextSend.SendText();
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
    
    class TextSend
    {   
        public static void SendText()
        {
            Thread.Sleep(3000);
 
            string teststring = "jhjJHGJG1234567890шгшгзщшЗШГЗШГЩЗШГЗШГЗГ!№;%:?*()_";
 
            for (int i = 0; i < teststring.Length; i++)
            {
                PressKey(teststring[i], true);
                PressKey(teststring[i], false);
            }
        }
 
        public static void PressKey(char ch, bool press)
        {
            byte vk = WindowsAPI.VkKeyScan(ch);
            ushort scanCode = (ushort)WindowsAPI.MapVirtualKey(vk, 0);
 
            if (press)
                KeyDown(scanCode);
            else
                KeyUp(scanCode);
        }
 
        public static void KeyDown(ushort scanCode)
        {
            INPUT[] inputs = new INPUT[1];
            inputs[0].type = WindowsAPI.INPUT_KEYBOARD;
            inputs[0].ki.dwFlags = WindowsAPI.KEYEVENTF_SCANCODE;
            inputs[0].ki.wScan = (ushort)(scanCode & 0xff);
 
            uint intReturn = WindowsAPI.SendInput(1, inputs, System.Runtime.InteropServices.Marshal.SizeOf(inputs[0]));
            if (intReturn != 1)
            {
                throw new Exception("Could not send key: " + scanCode);
            }
        }
 
        public static void KeyUp(ushort scanCode)
        {
            INPUT[] inputs = new INPUT[1];
            inputs[0].type = WindowsAPI.INPUT_KEYBOARD;
            inputs[0].ki.wScan = scanCode;
            inputs[0].ki.dwFlags = WindowsAPI.KEYEVENTF_SCANCODE | WindowsAPI.KEYEVENTF_KEYUP;
            uint intReturn = WindowsAPI.SendInput(1, inputs, System.Runtime.InteropServices.Marshal.SizeOf(inputs[0]));
            if (intReturn != 1)
            {
                throw new Exception("Could not send key: " + scanCode);
            }
        }
 
    }
    public class WindowsAPI
    {
        /// <summary>
        /// 
        /// </summary>
        public const uint WM_KEYDOWN = 0x100;
 
        /// <summary>
        /// 
        /// </summary>
        public const uint WM_KEYUP = 0x101;
 
        /// <summary>
        /// 
        /// </summary>
        public const uint WM_LBUTTONDOWN = 0x201;
 
        /// <summary>
        /// 
        /// </summary>
        public const uint WM_LBUTTONUP = 0x202;
 
        public const uint WM_CHAR = 0x102;
 
        /// <summary>
        /// 
        /// </summary>
        public const int MK_LBUTTON = 0x01;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_RETURN = 0x0d;
 
        public const int VK_ESCAPE = 0x1b;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_TAB = 0x09;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_LEFT = 0x25;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_UP = 0x26;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_RIGHT = 0x27;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_DOWN = 0x28;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_F5 = 0x74;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_F6 = 0x75;
 
        /// <summary>
        /// 
        /// </summary>
        public const int VK_F7 = 0x76;
 
        /// <summary>
        /// The GetForegroundWindow function returns a handle to the foreground window.
        /// </summary>
        /// 
        [DllImport("user32.dll")]
        public static extern byte VkKeyScan(char ch);
 
        [DllImport("user32.dll")]
        public static extern uint MapVirtualKey(uint uCode, uint uMapType);
 
        [DllImport("User32.dll")]
        public static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] input, int structSize);
 
        public const int INPUT_MOUSE = 0;
        public const int INPUT_KEYBOARD = 1;
        public const int INPUT_HARDWARE = 2;
        public const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
        public const uint KEYEVENTF_KEYUP = 0x0002;
        public const uint KEYEVENTF_UNICODE = 0x0004;
        public const uint KEYEVENTF_SCANCODE = 0x0008;
        public const uint XBUTTON1 = 0x0001;
        public const uint XBUTTON2 = 0x0002;
        public const uint MOUSEEVENTF_MOVE = 0x0001;
        public const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
        public const uint MOUSEEVENTF_LEFTUP = 0x0004;
        public const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
        public const uint MOUSEEVENTF_RIGHTUP = 0x0010;
        public const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        public const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
        public const uint MOUSEEVENTF_XDOWN = 0x0080;
        public const uint MOUSEEVENTF_XUP = 0x0100;
        public const uint MOUSEEVENTF_WHEEL = 0x0800;
        public const uint MOUSEEVENTF_VIRTUALDESK = 0x4000;
        public const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct MOUSEINPUT
    {
        int dx;
        int dy;
        uint mouseData;
        uint dwFlags;
        uint time;
        IntPtr dwExtraInfo;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct KEYBDINPUT
    {
        public ushort wVk;
        public ushort wScan;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct HARDWAREINPUT
    {
        uint uMsg;
        ushort wParamL;
        ushort wParamH;
    }
 
    [StructLayout(LayoutKind.Explicit)]
    public struct INPUT
    {
        [FieldOffset(0)]
        public int type;
        [FieldOffset(4)] //*
        public MOUSEINPUT mi;
        [FieldOffset(4)] //*
        public KEYBDINPUT ki;
        [FieldOffset(4)] //*
        public HARDWAREINPUT hi;
    }
}
0
3 / 3 / 2
Регистрация: 27.06.2013
Сообщений: 94
24.02.2015, 18:15  [ТС] 4
Отвечаю сам себе, если кому интересно. Правильный код.

http://stackoverflow.com/quest... yond-uffff

Получилось следующее, отправляет любые символы Unicode, включая русские и заглавные буквы. UTF-32 вряд ли нужен.

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
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Input;
using System.Diagnostics;
 
namespace SendTextForms3
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main()
        {
            TextSend.SendText();
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }
    }
 
    class TextSend
    {
        [DllImport("User32.dll")]
        public static extern uint SendInput(uint numberOfInputs, [MarshalAs(UnmanagedType.LPArray, SizeConst = 1)] INPUT[] input, int structSize);
 
        [DllImport("user32.dll")]
        public static extern IntPtr GetMessageExtraInfo();
        
        public static void SendText()
        {
            Thread.Sleep(3000);
 
            string teststring = @"`1234567890-=\qwertyuiop[]asdfghjkl;'zxcvbnm,./QWERTYUIOP[]ASDFGHJKL;'ZXCVBNM,./?ё1234567890-=\йцукенгшщзхъфывапролджэячсмитьбю.,Ё1234567890-=\ФЫВАПРОЛДЖЭЯЧСМИТЬБЮ.,";
 
            for (int i = 0; i < teststring.Length; i++)            
                SendCharUnicode(teststring[i]);            
        }
 
        public static void SendCharUnicode(char ch)
        {   
            INPUT[] input = new INPUT[2];
            input[0] = new INPUT();
            input[0].type = INPUT_KEYBOARD;
            input[0].ki.wVk = 0;
            input[0].ki.wScan = (ushort)ch;
            input[0].ki.time = 0;
            input[0].ki.dwFlags = KEYEVENTF_UNICODE;
            input[0].ki.dwExtraInfo = GetMessageExtraInfo();
            
            input[1] = new INPUT();
            input[1].type = INPUT_KEYBOARD;
            input[1].ki.wVk = 0;
            input[1].ki.wScan = (ushort)ch;
            input[1].ki.time = 0;
            input[1].ki.dwFlags = KEYEVENTF_UNICODE | KEYEVENTF_KEYUP;
            input[1].ki.dwExtraInfo = GetMessageExtraInfo();
            SendInput(2, input, Marshal.SizeOf(typeof(INPUT)));
        }
 
        public const int INPUT_MOUSE = 0;
        public const int INPUT_KEYBOARD = 1;
        public const int INPUT_HARDWARE = 2;
        public const uint KEYEVENTF_EXTENDEDKEY = 0x0001;
        public const uint KEYEVENTF_KEYUP = 0x0002;
        public const uint KEYEVENTF_UNICODE = 0x0004;
        public const uint KEYEVENTF_SCANCODE = 0x0008;
        public const uint XBUTTON1 = 0x0001;
        public const uint XBUTTON2 = 0x0002;
        public const uint MOUSEEVENTF_MOVE = 0x0001;
        public const uint MOUSEEVENTF_LEFTDOWN = 0x0002;
        public const uint MOUSEEVENTF_LEFTUP = 0x0004;
        public const uint MOUSEEVENTF_RIGHTDOWN = 0x0008;
        public const uint MOUSEEVENTF_RIGHTUP = 0x0010;
        public const uint MOUSEEVENTF_MIDDLEDOWN = 0x0020;
        public const uint MOUSEEVENTF_MIDDLEUP = 0x0040;
        public const uint MOUSEEVENTF_XDOWN = 0x0080;
        public const uint MOUSEEVENTF_XUP = 0x0100;
        public const uint MOUSEEVENTF_WHEEL = 0x0800;
        public const uint MOUSEEVENTF_VIRTUALDESK = 0x4000;
        public const uint MOUSEEVENTF_ABSOLUTE = 0x8000;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct MOUSEINPUT
    {
        int dx;
        int dy;
        uint mouseData;
        uint dwFlags;
        uint time;
        IntPtr dwExtraInfo;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct KEYBDINPUT
    {
        public ushort wVk;
        public ushort wScan;
        public uint dwFlags;
        public uint time;
        public IntPtr dwExtraInfo;
    }
 
    [StructLayout(LayoutKind.Sequential)]
    public struct HARDWAREINPUT
    {
        uint uMsg;
        ushort wParamL;
        ushort wParamH;
    }
 
    [StructLayout(LayoutKind.Explicit)]
    public struct INPUT
    {
        [FieldOffset(0)]
        public int type;
        [FieldOffset(4)] //*
        public MOUSEINPUT mi;
        [FieldOffset(4)] //*
        public KEYBDINPUT ki;
        [FieldOffset(4)] //*
        public HARDWAREINPUT hi;
    }
}
0
24.02.2015, 18:15
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.02.2015, 18:15
Помогаю со студенческими работами здесь

Эмулировать нажатие сочетания клавиш Alt+Tab
Всем привет! Как сэмулировать нажатие сочетания клавиш Alt+Tab, для появления окна с запущенными...

При нажатии заданной клавиши эмулировать нажатие сочетания клавиш
Ребят, посоветуйте гайд, о том как создать биндер клавиш на delphi, что бы при нажатии одной...

Как эмулировать нажатие сочетаний клавиш alt+стрелка влево?
ПОДСОБИТЕ ЧАЙНИКУ. Подсобите горе-программисту. ПОДСОБИТЕ ЧАЙНИКУ Дорогие друзья, как...

Эмулировать нажатие клавиш Alt+Tab каждые пять секунд
Буду краток,нужна программа которая через определенный интервал времени(например 5 сек.)...


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

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