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

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

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Найти ошибку в коде http://www.cyberforum.ru/cpp-beginners/thread964231.html
надо ввести равные стороны 3-ка #include <iostream> using namespace std; int main() { float side1 , side2 , side3; cout<<"int ravnye storony 3-ka";
C++ Определить, сколько элементов стека, начиная от вершины, находится до элемента с минимальным значением Есть стек с числами от -50 до 50 Помогите :определить, сколько элементов стека, начиная от вершины, находится до элемента с минимальным значением. #include<iostream> #include<stdio.h>... http://www.cyberforum.ru/cpp-beginners/thread964226.html
C++ if (c==0)
#include <iostream> #include <conio.h> #include <complex> #include <math.h> int main() { double c;
C++ Вывод числа в двоичном представлении
Задача: представить число long double в двоичном коде. Использую для этого union, но на экран упорно выводится только половина числа. Почему?? #include <stdio.h> union LongD { long double l;...
C++ vector subscript out of range http://www.cyberforum.ru/cpp-beginners/thread964199.html
Доброго времени суток! Подскажите пожалуйста, где именно я ошибся, вроде не должен он за пределы выходить по коду: const int WIDTH = 10, HEIGHT = 6; ....
C++ Access violation writing location Добрый день! на строке ptr = ptr; бросает unhandeled exeption: Access violation writing location, не пойму почему, может уже туплю. Помогите понять! #include <TCHAR.h> #include <windows.h>... подробнее

Показать сообщение отдельно
olegoner
160 / 74 / 4
Регистрация: 22.04.2012
Сообщений: 221

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

28.09.2013, 17:55. Просмотров 535. Ответов 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru