Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
olegoner
160 / 74 / 4
Регистрация: 22.04.2012
Сообщений: 221
#1

Ловушка на нажатие клавиши клавиатуры - C++

28.09.2013, 17:55. Просмотров 534. Ответов 0
Метки нет (Все метки)

Здравствуйте.
Пытаюсь разобраться с HOOKами. Задача: зафиксировать символы введённые в поле ввода другой программы, и если они образуют определённую последовательность, то надо их заменить на какое-либо заранее определённое слово.
Т.е. если я в строке Googlе, например, введу "QWERTY", то надо это слово там заменить на "ПРИМЕР",скажем.

Решил действовать так (пользуясь вычитанным в интернете и книжке рецептом).
1. Пишу dll библиотеку, в которой описаны функции устанавливающие hook и при выполнение определенных условий, отправляющие в окно стартового приложения сообщение.
2. И соответственно стартовое приложение, которое будет всё обрабатывать.

Процесс встал на первом пункте.

myDLL.h
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Macro for DLL exports in Win32, replaces Win16 __export
#define DllExport extern "C++" __declspec(dllexport)
#include <Windows.h>
// Prototype
DllExport void RunStopHook(bool State, HWND hRunsWindow);
 
 
///////////////////////////////////////////////////////////
//структура хранения данных о ловушке hook
//////////////////////////////////////////////////////////
typedef struct GDLLDATAtag 
{
    HHOOK SysHook; // дискриптор hook ловушки
    HWND RunsWindow; // дискриптор окна запускающего приложения 
}GDLLDATA;
 
typedef GDLLDATA *PGDLLDATA;// PGDLLDATA - указатель на структуру GDLLDATA
 
void OpenGlobalData();
void CloseGlobalData();
dllmain.cpp
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdafx.h"
 
HINSTANCE hInstc;//указатель на dllHINSTANCE 
 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH: OpenGlobalData();  
    //case DLL_PROCESS_DETACH: CloseGlobalData();
        break;
    }
 
    hInstc = (HINSTANCE)hModule;
    return TRUE;
}
myDLL.cpp
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
#include "stdafx.h"
 
 
// Глобальные переменные
  PGDLLDATA globalData; //указатель на структуру в АП Windows  
  HANDLE mMFHandle;
  UINT WM_MYKEYHOOK;// код нашего личного сообщения c символом в диапазоне от  0xC000 до 0xFFFF.
  UINT WM_MYHOOKERROR;// сообщение об ошибке
 
  
 
 
//#define MMFNAME "KeyMMF"; // имя объекта файлового отображения
 
//функция вызова при обработке события
LRESULT CALLBACK KeyboardProc( int code,WPARAM wParam,LPARAM lParam)
{
        if (code < 0)
        {
            //сообщение не обрабатывается и передаётся следующим ловушкам
            return CallNextHookEx((*globalData).SysHook,code,wParam,lParam); 
        }
        
        
        
        //если нажаты клавиши алфавита, цифры или пробел        
        if ((((lParam & KF_UP) == 0) && (wParam >= 65) && (wParam <= 90)) || (((lParam && KF_UP) == 0) && (wParam == VK_SPACE)) || (((lParam && KF_UP) == 0) && (wParam >= 48) && (wParam <= 57)))
        {
            HWND Wnd = 0; // дескриптор окна, который мы отправим обрабатывающе программе
            HWND topWnd = GetForegroundWindow();// получили HWND приоритетного окна
            Beep(267,500);//для тестирования
 
            if (topWnd > 0) //если активное окно найдено
            {
                
                DWORD lpdwProcessId; //переменная для кранения индетификатора потока приортиетного окна
                DWORD id = GetWindowThreadProcessId(Wnd,&lpdwProcessId);// получаем индетификатор потока
                
                GUITHREADINFO thrInfo;//создаём переменную (структуру), содержащая информацию о потоке
                thrInfo.cbSize = sizeof(GUITHREADINFO);
                if (GetGUIThreadInfo(id,&thrInfo) > 0)
                {
                    HWND focusWnd = thrInfo.hwndFocus;                  
                    if (focusWnd > 0) Wnd = focusWnd;                   
                    SetWindowText(focusWnd,TEXT("OLOLO")); //для тестирования
                    InvalidateRect(Wnd, 0, true);//для тестирования
                }               
            }
            SendMessage((*globalData).RunsWindow, WM_MYKEYHOOK, wParam,LPARAM(Wnd));
        }
                
        return CallNextHookEx((*globalData).SysHook, code, wParam, lParam);;
}
 
DllExport void RunStopHook(bool State, HWND hRunsWindow)
{
    if (State == true)
    {
        //установить hook, если он не установлен
        globalData->SysHook = SetWindowsHookEx(WH_KEYBOARD, &KeyboardProc, hInstc, 0);
        globalData->RunsWindow = hRunsWindow;           
        
    }
    else
    {
        //удаляю функцию фильтр, если она установлена
        UnhookWindowsHookEx(globalData->SysHook);
        CloseGlobalData();           
            
    }
}
 
void OpenGlobalData()
{
    WM_MYKEYHOOK = RegisterWindowMessage(TEXT("WM_MYKEYHOOK")); //регестрируем наши типы сообщений
    WM_MYHOOKERROR = RegisterWindowMessage(TEXT("WM_MYHOOKERROR"));
 
    mMFHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(GDLLDATA), TEXT("KeyMMF"));
 
    if (mMFHandle == 0)
    {           
        return;
    }
 
    //отображаем глобальные данные на АП вызывающего процесса и получаем указатель
   //на начало выделенного пространства
    globalData = (PGDLLDATA)MapViewOfFile(mMFHandle, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(GDLLDATA));
    if (globalData == NULL) 
    {
      CloseHandle(mMFHandle);      
      return;
    }
}
 
void CloseGlobalData()
{
  UnmapViewOfFile(globalData);
  CloseHandle(mMFHandle);
}
Всё прекрасно компилируется.

Для тестирования создал Win32 консольное приложение.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// TestMyDLL.cpp: определяет точку входа для консольного приложения.
//
 
#include "stdafx.h"
#include "myDLL.h"
 
int _tmain(int argc, _TCHAR* argv[])
{
    RunStopHook(true,0);
    getchar();
    getchar();
    RunStopHook(false,0);
    return 0;
}
Я ожидал, что при нажатии клавиши на клавиатуре произойдёт однократный сигнал Beep(267,500);

1. Однако, при вводе символа в поисковую строку браузера, например, происходит многократное повторение сигнала, и только спустя 4-10 секунд отображается символ.
А при вводе символа в окно блокнота, сигнала нет, а сам блокнот зависает.

2. Функция никак не реагирует на нажатие клавишь с цифрой.

Помогите, пожалуйста, разобраться с проблемой.

С ув. Олег
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
28.09.2013, 17:55
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Ловушка на нажатие клавиши клавиатуры (C++):

Реакция на нажатие клавиши независимо от раскладки клавиатуры - C++
Всем добрый день! Подскажите, пожалуйста, если необходимо, чтобы в консольном приложении происходило определенное действие при нажатии,...

Нажатие клавиши - C++
Всем доброго времени суток. Кто знает как имитировать нажатие button-а? Т.е. Что бы допустим таймер посылал команду и кнопка нажималась,...

Нажатие клавиши - C++
Здравствуйте дорогие друзья, Я начинающий программист и хотел бы задать такой вопрос: Как сделать так, чтобы при нажатии на клавишу,...

Нажатие клавиши - C++
Всем привет! как сделать так чтобы в окне output при нажатии Enter курсор переходил на новую строку

Имитировать нажатие клавиши - C++
Проблема такая, есть программа, кот запущена, с пользовательским интерфейсом. Нужно сделать для нее прогу, кот будет через допустим 2...

Нажатие клавиши программно - C++
Здравствуйте, а сложно сделать программу: Нажатие клавиши (прописаной в самом коде) в программе (прописаной в самом кодк) с определённыи...

0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
28.09.2013, 17:55
Привет! Вот еще темы с ответами:

Нажатие клавиши в консоли - C++
Есть ли метод для нажатия клавиши (любой) в консоли? Т.е. нажал, к примеру, на клавишу Номе и в консоли вывело &quot;Привет&quot; и тп.

Реакция на нажатие клавиши - C++
Проблема такая: обрабатываю нажатие клавиши- if ((GetAsyncKeyState(VK_LEFT)!=0)&amp;&amp;(... По нажатию я изменяю значение переменной...

Запретить нажатие клавиши Win - C++
Приветствую. Подскажите, как можно запретить нажатие клавиши Win?? Требуется чтобы приложение не реагировало на нажатие клавиши Win, и на...

Авто нажатие клавиши в консоли - C++
Народ помогите... вывожу cmd system(&quot;prog -i&quot;); выводит Y или N.. как программно без участия организовать ввод нужной буквы +...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru