Задача: поставить глобальный хук на клавиатуру, при нажатии любой клавиши создавать файл с заданным именем.
приложение:
#include <string>
#include <iostream>
#include <conio.h>
#include <windows.h>
static HHOOK* HookHandle = NULL;
HOOKPROC HookProc = NULL;
int main()
{
HINSTANCE DllHandle = LoadLibrary(L"SharedDll.dll");
if( DllHandle )
{
//хук - процедура
HookProc = (HOOKPROC) GetProcAddress( DllHandle, "_HookProc@12");
//хэндл библиотеки
HookHandle = (HHOOK*) GetProcAddress( DllHandle, "dllHook" );
//установка хука
*HookHandle = SetWindowsHookExW( WH_KEYBOARD, HookProc, DllHandle, NULL );
_getch();
MessageBox(NULL,L"text",L"title",NULL);
UnhookWindowsHookEx(*HookHandle);
FreeLibrary(DllHandle);
}
else
{
MessageBox(NULL,L"Failed to load library",L"error",0);
}
return 0;
}
DLL:
//секция разделяемой памяти
#include <windows.h>
#include <iostream>
#pragma data_seg(".myseg")
extern "C" __declspec(dllexport) HHOOK dllHook = NULL;
#pragma data_seg()
#pragma comment(linker, "/SECTION:.myseg,RWS")
extern "C" __declspec(dllexport)
LRESULT CALLBACK HookProc(
int code,
WPARAM wParam,
LPARAM lParam
)
{
fclose(fopen("c:\\PROVERKA.jpg","w"));
return CallNextHookEx(dllHook, code, wParam, lParam );
}
Я запускаю приложение, делаю его неактивным (т.к. хук не перехватывает нажатие клавиш на консоль), щёлкаю любую клавишу, и получаю PROVERKA.jpg на диске c:\.
Проблема: стоит мне заменить "c:\\PROVERKA.jpg" на "PROVERKA.jpg" или любое другое имя без абсолютного пути ("xxx.xxx"), то всё совершенно меняется. Поведение: запускаю программу, убираю на задний фон, щёлкаю любую клавишу — ничего не происходит. Когда в конце приложения выскакивает
MessageBox(NULL,L"text",L"title",NULL), то только тогда, делая активным любое окно (даже консоль), я получаю PROVERKA.jpg в той же папке, что и программа.
Как вообще такое может быть? Чем абсолютный путь так кардинально отличается от относительного в моей программе?
17.07.09 10:33: Перенесено модератором из 'C/C++. Прикладные вопросы' — Кодт
"только тогда, делая активным любое окно (даже консоль), я получаю PROVERKA.jpg в той же папке, что и программа."
Ну и нажимая какую-либо клавишу, естественно.
Здравствуйте, AlexJH, Вы писали:
AJH>Я запускаю приложение, делаю его неактивным (т.к. хук не перехватывает нажатие клавиш на консоль), щёлкаю любую клавишу, и получаю PROVERKA.jpg на диске c:\.
AJH>Проблема: стоит мне заменить "c:\\PROVERKA.jpg" на "PROVERKA.jpg" или любое другое имя без абсолютного пути ("xxx.xxx"), то всё совершенно меняется. Поведение: запускаю программу, убираю на задний фон, щёлкаю любую клавишу — ничего не происходит. Когда в конце приложения выскакивает
AJH>MessageBox(NULL,L"text",L"title",NULL), то только тогда, делая активным любое окно (даже консоль), я получаю PROVERKA.jpg в той же папке, что и программа.
AJH>Как вообще такое может быть? Чем абсолютный путь так кардинально отличается от относительного в моей программе?
Вы ставите глобальный хук. Ваша длл загружается в адресные пространства приложений. Если указываете полный путь "c:\file.dmp", то все будет записываться именно в этот файл от всех приложений. А когда указываете просто "file.dmp", то файл этот будет создаваться в папке каждого графического приложения, которое на момент нажатия клавиши активно.
По поводу консольного приложения и перехвата нажатий в консоле...
Нужно вызывать SetWindowsHookEx с WH_KEYBOARD_LL и также в длл создавать дополнительный поток:
LPTHREAD_START_ROUTINE WINAPI DispatchHookMsgThreadFunc(PVOID) {
MSG msg;
while( GetMessage(&msg, NULL, 0, 0) ) {
DispatchMessage(&msg);
}
return 0;
}
Таким образом можно будет отлавливать клавиши во всех графических приложениях включая cmd.
Почитайте про WH_KEYBOARD_LL
тут.