проблема с SetWindowsHookEx

Общие вопросы, не зависящие от языка реализации.

Модераторы: Duncon, Hawk, Romeo, Eugie

Ответить
loginz
Сообщения: 4
Зарегистрирован: 22 апр 2010, 05:25

Здравствуйте!
Не нашел в форумах ответ, поэтому создаю тему!
при вызове функции SetWindowsHookEx функция-обработчик KeyboardProc содержит одни и те же коды нажатых клавиш. (в файле "key.log" одна и таже повторяющаяся битовая последовательность для разных нажатий, см. ниже)

Почему? Что не так в коде? подскажите пожалуйста.
Система vista 64. Borland 2009
код dll:

Код: Выделить всё

#include <windows.h> 
#include <fstream.h> 
#pragma argsused 

struct keys{ 
int code; 
WPARAM wParam; 
LPARAM lParam;}; 

keys sym; 
int count=0; 

extern "C" __declspec(dllexport) LPARAM CALLBACK KeyboardProc( int code, WPARAM wParam, LPARAM lParam) 
{ 
if (wParam == WM_KEYDOWN) { 

sym.code = code; 
sym.wParam = wParam; 
sym.lParam = lParam; 

ofstream out("key.log", ios::app); 

if (out == 0) { MessageBoxA(0, "Error open file", "Error open file", 0); } 

out.write((char *)&sym, sizeof(keys)); 
out.close(); 
} 

return CallNextHookEx(0, code, wParam, lParam); 
} 

=================================== ========= 

фрагмент кода программы (при нажатии Button1 устанавливаем хук): 
void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 

static HHOOK hhook; 
static HINSTANCE hlib = LoadLibrary((LPCTSTR) "..\\..\\..\\dll\\debug\\Project1.d ll"); 

if (!hlib) { MessageBox(0, "Error", "ErrorLoad dll", 0); } 

static HOOKPROC mykey = (HOOKPROC)GetProcAddress(hlib, "KeyboardProc"); 

if (!mykey) { MessageBox(0, "Error", "ErrorLoad function", 0); } 

hhook = SetWindowsHookEx(WH_KEYBOARD_LL, mykey, hlib, NULL); 

Form1->SpinEdit1->Value = (LPARAM)hhook; 

if ( !hhook ) { 
MessageBox(0, "Error", "ErrorLoad hook", 0); 

} 

} 
Аватара пользователя
Duncon
Сообщения: 2085
Зарегистрирован: 10 окт 2004, 14:11
Откуда: Питер
Контактная информация:

Ты потенциально пишешь клавиатурного шпиона, никто помогать не будет..
[syntax=Delphi] [/syntax]
loginz
Сообщения: 4
Зарегистрирован: 22 апр 2010, 05:25

1) Почему так, что такого неординарного?
2) задачи разные бывают! в принципе дело каждого как использовать этот код: если ты засылаешь его как трояна и т.п. - то ты злоумышленник, если ты используешь для изучения работы функции и дальнейшей выработки "анти"мер - то другое
3) вообще это лабораторная работа в университете
я не вижу "криминала" в этом вопросе
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

1. LParam в LowLevelKeyboardProc - это указатель на структуру типа KBDLLHOOKSTRUCT. Чтобы получить виртуальный код и пр., нужно ее разыменовать:

Код: Выделить всё

KBDLLHOOKSTRUCT* pkh = (KBDLLHOOKSTRUCT*)lParam;
// pkh->vkCode - доступ до полей
2. Глобальный хук, как WH_KEYBOARD_LL, должен размещать свою процедуру в отдельной dll. Поскольку вы разрабатываете на x64, имейте в виду, что сообщения из 32-битых процессов ваша программа не перехватит. Для полного охвата вам нужно 2 пары программы-установщика хука и dll (32- и 64-битные).

3. Установку хука лучше выполнять не по нажатию кнопки, а при инициализации программы (до создания главного окна), отключение - перед завершением (после выхода из цикла обработки сообщений).

4. Криминала действительно никакого нет: хуки - стандартный механизм Windows API для перехвата сообщений. Правда, сильно снижающий системную производительность и потенциально подверженный конфликтам (речь о глобальных хуках). Впрочем, лучше об этом почитать первоисточник: http://msdn.microsoft.com/en-us/library ... 85%29.aspx
The global hooks are a shared resource, and installing one affects all applications in the same desktop as the calling thread. All global hook functions must be in libraries. Global hooks should be restricted to special-purpose applications or to use as a development aid during application debugging. Libraries that no longer need a hook should remove its hook procedure.
BulldozerBSG
Сообщения: 270
Зарегистрирован: 09 янв 2010, 04:14
Контактная информация:

Ув. Duncon, я не вижу ни какого криминала. Существует множество программ использующих данный механихм для обработки глобал хоткей. Да к примеру Winamp, очень удобно управлять через клавиатуру когда он свернут в терее.
Аватара пользователя
Romeo
Сообщения: 3126
Зарегистрирован: 02 мар 2004, 17:25
Откуда: Крым, Севастополь
Контактная информация:

Поддерживаю. Ничего коварного в этом нету.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
loginz
Сообщения: 4
Зарегистрирован: 22 апр 2010, 05:25

Спасибо, Eugie.
Наскоро попробовал .... вроде как работает. сейчас до ума доведу свою программу.
конечно, если это указатель, то все стяновится ясно, но я читал msdn-документацию на функцию KeyboardProc.
Она описана как (http://msdn.microsoft.com/en-us/library ... S.85).aspx) :
LRESULT CALLBACK KeyboardProc(
__in int code,
__in WPARAM wParam,
__in LPARAM lParam);

получается и WPARAM также указатель на unsigned int (беззнаковое целое) ?
еще не подскажите, что значит "__in" в msdn-документациях? довольно часто встречается
Eugie
Сообщения: 708
Зарегистрирован: 17 фев 2004, 23:59
Откуда: SPb

Вы спутали KeyboardProc с LowLevelKeyboardProc, у них разные прототипы.

__in, __out, __inout - это т.н. аннотации параметров:
__in - входной параметр (должен быть инициализирован до вызова функции)
__out - выходной параметр (через него функция возвращает значение)
__inout - одновременно входной и выходной параметр (должен быть инициализирован до вызова и возвращает значение)

Аннотации помогают более строго выполнять статический контроль типов на стадии до и во время компиляции. Подробнее см. http://blogs.msdn.com/wdkdocs/archive/2 ... lysis.aspx
loginz
Сообщения: 4
Зарегистрирован: 22 апр 2010, 05:25

Все, разобрался, событие ж, на которое я ставлю hook _LL ! поэтому и функция ...LowLevel...
еще раз благодарю! :D
Аватара пользователя
WinMain
Сообщения: 929
Зарегистрирован: 14 янв 2005, 10:30
Откуда: Москва
Контактная информация:

Подобная тема обсуждалась уже на форуме: http://forum.developing.ru/showthread.php?16557
Ответить