Страница 1 из 1

проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 05:28
loginz
Здравствуйте!
Не нашел в форумах ответ, поэтому создаю тему!
при вызове функции 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); 

} 

} 

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 08:44
Duncon
Ты потенциально пишешь клавиатурного шпиона, никто помогать не будет..

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 09:27
loginz
1) Почему так, что такого неординарного?
2) задачи разные бывают! в принципе дело каждого как использовать этот код: если ты засылаешь его как трояна и т.п. - то ты злоумышленник, если ты используешь для изучения работы функции и дальнейшей выработки "анти"мер - то другое
3) вообще это лабораторная работа в университете
я не вижу "криминала" в этом вопросе

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 11:24
Eugie
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.

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 12:23
BulldozerBSG
Ув. Duncon, я не вижу ни какого криминала. Существует множество программ использующих данный механихм для обработки глобал хоткей. Да к примеру Winamp, очень удобно управлять через клавиатуру когда он свернут в терее.

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 12:28
Romeo
Поддерживаю. Ничего коварного в этом нету.

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 16:19
loginz
Спасибо, 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-документациях? довольно часто встречается

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 16:39
Eugie
Вы спутали KeyboardProc с LowLevelKeyboardProc, у них разные прототипы.

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

Аннотации помогают более строго выполнять статический контроль типов на стадии до и во время компиляции. Подробнее см. http://blogs.msdn.com/wdkdocs/archive/2 ... lysis.aspx

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 18:24
loginz
Все, разобрался, событие ж, на которое я ставлю hook _LL ! поэтому и функция ...LowLevel...
еще раз благодарю! :D

Re: проблема с SetWindowsHookEx

Добавлено: 22 апр 2010, 19:16
WinMain
Подобная тема обсуждалась уже на форуме: http://forum.developing.ru/showthread.php?16557