Название: События перемещения мыши Отправлено: virtual_root от Июль 02, 2012, 13:34 Добрый день. Ребята подскажите,пожалуйста, как мне решить следующую задачу:
Требуется ловить события перемещения мыши вне моей программы. Не по таймеру, а каждое перемещение отлавливать и вызывать соответствующую функцию. Может в QT есть решения для этого,чтобы WinAPI не использовать? Название: Re: События перемещения мыши Отправлено: Bepec от Июль 02, 2012, 13:39 Это платформо зависимый код нужен.
Qt это вроде как не позволяет, кроме как таймером. И вообще - чем тебе winApi ненравится??? Название: Re: События перемещения мыши Отправлено: Alex Custov от Июль 02, 2012, 14:04 только через платформо-зависимый код
Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 03, 2012, 09:25 А может вы подскажите как это через winAPI реализовать? С помощью хуков не подходит, так как попросили без перехвата мыши...
Я читала что можно через системные события сделать. Кто-нибудь работал с системными событиями, можете,пожалуйста, подсказать, как с ними работать. Название: Re: События перемещения мыши Отправлено: Bepec от Июль 03, 2012, 09:35 Уважаемый. Как вы собираетесь ПЕРЕХВАТЫВАТЬ события передвижения мыши, БЕЗ ПЕРЕХВАТА событий мыши?
Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 03, 2012, 09:49 мне нужно как-бы подписаться на это событие. Завести соответствующее событие в системе и ловить, а как мне это сделать?
Я наверное чего-то не понимаю. Для создания события в windows я использую: Код: event = CreateEvent( NULL, FALSE, FALSE, NULL ); А где мне указать что меня интересует событие перемещения мыши, чтобы можно было допутим в бесконечном цикле его ожидать?Название: Re: События перемещения мыши Отправлено: Bepec от Июль 03, 2012, 10:06 Кхм... Вы походу многое путаете...
Чтобы перехватить событие нужен хук. КреатеЕвент - создаёт событие. Не перехватывает, не изменяет, не подписывается, а создаёт. Вы или многого не понимаете, или знаете что-то о чём незнаю я (ну и заодно со мной msdn :D) Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 03, 2012, 10:24 Верес, помогите мне пожалуйста разобраться!) Как мне получать событие перемещения мыши без её перехвата? Или это попросту не возможно? Я думала, что нужно просто подписаться на это событие,правда не знаю как...) в гугле что-то не могу найти похожего решения, только с хуками.
Название: Re: События перемещения мыши Отправлено: Bepec от Июль 03, 2012, 10:42 Уважаемый. Как вы собираетесь ПЕРЕХВАТЫВАТЬ события передвижения мыши, БЕЗ ПЕРЕХВАТА событий мыши? Прочитайте слова, выделенные синим :) Если они вас не смутят, тогда вы аки бог. Чтобы получать события мыши - нужно поставить хук. В вашем случае нужен глобальный хук. Хук - это как раз функция, которая вызывается при перехвате событий, указанных в её параметрах(ну при инициализации). Собственно хук вам и нужен. А "Строить не строя" и "Ломать не ломая" - это уже к всевышнему. Он такие чудеса может делать :) Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 03, 2012, 10:49 спасибо большое!)
Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 03, 2012, 12:45 Ребята, помогите, кто знает разобраться с хуками.
Мне нужно создать хук, который перехватывает событие перемещения мыши вне области программы. Почитав на форумах и в msdn, я написала следующий код: dll библиотека, в которой содержится фун-я обработчик события для хука: файл .h: Код: #ifndef HOOKFUNCTIONS_H #define HOOKFUNCTIONS_H #include "hookFunctions_global.h" class HOOKFUNCTIONSSHARED_EXPORT HookFunctions { public: int cxPoint; int cyPoint; HookFunctions(); LRESULT CALLBACK MouseHook(int nCode,WPARAM wParam,LPARAM lParam); int x(); int y(); FILE *file; long buffer[100]; int numwritten; }; #endif // HOOKFUNCTIONS_H файл .cpp: Код: #include "hookfunctions.h" HookFunctions::HookFunctions() { } // функция-фильтр, которая обрабатывает наш хук. LRESULT CALLBACK HookFunctions::MouseHook(int nCode,WPARAM wParam,LPARAM lParam) { if((HC_ACTION == nCode)) { cxPoint = LOWORD(lParam); // извлекаем младший байт, это и есть координата х мыши cyPoint = HIWORD(lParam); // извлекаем старший байт, это и есть координата у мыши if (fopen("test.txt","a+")){ numwritten = fwrite((char *)buffer, sizeof(long), 100,file); fclose(file); } } return CallNextHookEx(0, nCode, wParam, lParam); } int HookFunctions::x(){ return cxPoint; } int HookFunctions::y(){ return cyPoint; } файл main.cpp в котором я и создаю хук: Код: #include <iostream> #include <windows.h> using namespace std; int main() { HOOKPROC hkprcSysMsg; static HINSTANCE hinstDLL; static HHOOK hhookSysMsg; hinstDLL = LoadLibrary(TEXT("hookFunctions.dll")); hkprcSysMsg = (HOOKPROC)GetProcAddress(hinstDLL, "MouseHook"); // MouseHook функция из библиотеки hhookSysMsg = SetWindowsHookEx( WH_MOUSE, hkprcSysMsg, hinstDLL, 0); return 0; } Получается, что в функции обработчике в библиотеки я записываю координаты курсора в файл. Но ничего не записывается! Помогите, пожалуйста. Возможно как-то получать эти координаты из библиотеки в основной программе, не записывая их в файл? Название: Re: События перемещения мыши Отправлено: Bepec от Июль 03, 2012, 13:14 Да можно.
Вот только что вы тут творите я не очень понимаю :D Даже не так - вообще не понимаю :D И мейн у вас закрывается мгновенно, не так ли? А то, что функция для хука у вас в классе - ну незнаю. Никогда так не делал :D И функция в dll у вас не экспортирована похоже... Что сказать - эммм... откуда вы это содрали? :D Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 03, 2012, 13:37 Вы не поверите, не откуда, сама написала. Я совсем запуталась с этими хуками. Просто прочла в msdn и здесь http://www.rsdn.ru/article/baseserv/apicallsintercepting.xml
И как мне показалось что нужно обязательно dll-ку делать. Если можно без неё я буду счастлива, только как это сделать? Я просто создала консольный проектик, чтоб поучиться работать с хуками. Переписала код так: Код: #include <iostream> Проект собирается, но результата никакого. Координаты мыши в консоль не выводятся...#include <windows.h> using namespace std; LRESULT CALLBACK MouseHook(int nCode, WPARAM wParam, LPARAM lParam) { int x = LOWORD(lParam); // извлекаем младший байт, это и есть координата х мыши int y = HIWORD(lParam); // извлекаем старший байт, это и есть координата у мыши cout<< x <<y; return 0; } int main() { static HHOOK hhookSysMsg; hhookSysMsg = SetWindowsHookEx(WH_MOUSE,MouseHook,GetModuleHandle(NULL),0); return 0; } Что я не так снова сделала? :) Может нужно вместо WH_MOUSE что-то другое указать, чтобы отлавливать перемещения мыши ? Название: Re: События перемещения мыши Отправлено: Bepec от Июль 03, 2012, 13:41 Ожидайте ответа через ммм... 15-20 минут. Не раньше )
Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 03, 2012, 13:46 буду ждать) спасибо вам за терпение)) :)
Название: Re: События перемещения мыши Отправлено: Bepec от Июль 03, 2012, 14:34 Это код устанавливающий хук.
Код: /*static HINSTANCE hLib; static HHOOK hHook;*/ HOOKPROC hProc = NULL; hLib = LoadLibrary("keyhook"); _ASSERTE(hLib); hProc = (HOOKPROC)GetProcAddress(hLib, "HookProcMouse"); _ASSERTE(hProc); hHook = SetWindowsHookEx(WH_MOUSE, hProc, hLib, NULL); _ASSERTE(hHook); Код: #include "stdafx.h" #include <atltypes.h> #include <fstream> #define __GLOBAL_HOOK extern "C" __declspec(dllexport) LRESULT CALLBACK HookProcMouse(int nCode, WPARAM wParam, LPARAM lParam) { // если сообщение не удалено из очереди(не особо заморачивайтесь по этому поводу) if (nCode != HC_ACTION ) return CallNextHookEx(NULL, nCode, wParam, lParam); // Если событие передвижения мыши if (wParam == WM_MOUSEMOVE) { // то получаем указатель на структуру MOUSEHOOKSTRUCT *tmp = (MOUSEHOOKSTRUCT*)lParam; // открываем файл для записи, записываем и закрываем(координаты x и y) std::ofstream out("c:/123", std::ios::app); out << xs << tmp->pt.x << tmp->pt.y << std::endl; out.close(); } else { // иначе если сообщение другого типа, создаём 321, пишем, закрываем std::ofstream out("c:/321", std::ios::app); char xs = wParam; out << xs << std::endl; out.close(); } // передаём следующему хуку по цепочке(не вашим хукам, а уже чужим) return CallNextHookEx(NULL, nCode, wParam, lParam); } Деф файл dl.def - он позволяет задать точные имена экспортируемым функциям. Если его не будет, название ф-ции будет что-то типа 1@HookProcMouse1@2 рандомно. Код: LIBRARY "dl" DESCRIPTION 'keyhook Windows Dynamic Link Library' EXPORTS ; Explicit exports can go here HookProcMouse В принципе и всё ) Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 03, 2012, 15:16 спасибо большое, сейчас буду пробовать к себе в qt это всё применить.
Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 04, 2012, 10:25 Верес, подскажите мне ещё разок пожалуйста. Я сделала снова библиотеку как у вас. Но я не знаю как мне в Qt .def файл привязать к библиотеки, как это сделать? У меня проект вылетает с ошибкой на assert(hProc). Я так понимаю это он не может найти функцию?
и ещё мне пришлось так заменить строку с подключением библиотеки: Код: hLib = LoadLibrary(L"libMouseAPI"); Ну думаю это ничего не меняет? Сам dll файл лежит рядом с .exe файлом программы где я подключаю его.Название: Re: События перемещения мыши Отправлено: Bepec от Июль 04, 2012, 10:48 LoadLibrary загружает библиотеку из файла с названием, которое вы укажете :) Название должно совпадать с названием dll.
hProc выдаёт ассерт - значит у вас не находится функция, экспортируемая из dll. Откройте тоталкоммандер и нажмите ф3 на вашей dll. Там должна вкладочка быть import/export. В нижнем поле указано будет название вашей функции. Если def не подцепился, то оно будет отличаться от заданного в программе. Если нет Тотала, то dependency walker вам в помощь. Почитать про деф файл: http://msdn.microsoft.com/ru-ru/library/d91k01sh.aspx Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 04, 2012, 12:32 У меня ничего не выходит.. уже два дня бьюсь над ней..
Переписала в таком виде: Код: #include <QtCore/QCoreApplication> Проверила под дебагом, библиотека загружается, фун-ю видит, но когда запускаю падаю в #include <windows.h> #include <assert.h> #include <cassert> #include <QLibrary> int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QLibrary myLib("./libMouseAPI"); myLib.load(); myLib.loadHints(); if (!myLib.isLoaded()) exit(0); typedef LRESULT CALLBACK (*MyPrototype)(int, WPARAM, LPARAM); MyPrototype myFunction = (MyPrototype) myLib.resolve("HookProcMouse"); if (!myFunction) exit(0); static HHOOK hHook; hHook = SetWindowsHookEx(WH_MOUSE, myFunction, GetModuleHandle(NULL), NULL); assert(hHook); return a.exec(); } Код: assert(hHook); Наверное я что-то неправильно указываю в фун-и:Код: SetWindowsHookEx(WH_MOUSE, myFunction, GetModuleHandle(NULL), NULL); Как мне её правильно оформить, чтобы она принимала мой указатель на функцию? И ещё вопросик, Верес, вы не подскажите, а можно как-то без dll обойтись всё в одном файле сделать? И то что у меня консольный проект не играет никакой роли? Название: Re: События перемещения мыши Отправлено: Bepec от Июль 04, 2012, 12:40 Консольный - вообще никакой разницы.
Dll необлходима для глобального хука. Без dll глобальный хук не сделашь. Только в своей программе. Выкладывайте свой проект, будем смотреть. Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 04, 2012, 12:50 ой, спасибо :)
Вот библиотека и проект. Буду ждать) Название: Re: События перемещения мыши Отправлено: Bepec от Июль 04, 2012, 13:18 А вы уверены, что второй проект у вас компилится?
Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 04, 2012, 13:33 да, компилировался. Но когда запускался падал с assert(hHook);
Сейчас сделала локальный хук, в том же проекте изменила файл main.cpp. Вот что получилось: Код: #include <QtCore/QCoreApplication> #include <windows.h> #include <assert.h> #include <cassert> #include <QLibrary> #include <fstream> #include <QDebug> LRESULT CALLBACK HookProcMouse(int nCode, WPARAM wParam, LPARAM lParam) { // если сообщение не удалено из очереди(не особо заморачивайтесь по этому поводу) if (nCode != HC_ACTION ) return CallNextHookEx(NULL, nCode, wParam, lParam); // Если событие передвижения мыши if (wParam == WM_MOUSEMOVE) { // то получаем указатель на структуру MOUSEHOOKSTRUCT *tmp = (MOUSEHOOKSTRUCT*)lParam; // открываем файл для записи, записываем и закрываем(координаты x и y) char xs = wParam; std::ofstream out("c:/123", std::ios::app); out << xs << tmp->pt.x << tmp->pt.y << std::endl; out.close(); int x = tmp->pt.x; // извлекаем младший байт, это и есть координата х мыши int y = tmp->pt.y; // извлекаем старший байт, это и есть координата у мыши qDebug()<<x << y; } else { // иначе если сообщение другого типа, создаём 321, пишем, закрываем std::ofstream out("c:/321", std::ios::app); char xs = wParam; out << xs << std::endl; out.close(); } // передаём следующему хуку по цепочке(не вашим хукам, а уже чужим) return CallNextHookEx(NULL, nCode, wParam, lParam); } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); /* QLibrary myLib("./libMouseAPI"); myLib.load(); myLib.loadHints(); if (!myLib.isLoaded()) exit(0); typedef LRESULT CALLBACK (*MyPrototype)(int, WPARAM, LPARAM); MyPrototype myFunction = (MyPrototype) myLib.resolve("HookProcMouse"); if (!myFunction) exit(0);*/ static HHOOK hHook; hHook = SetWindowsHookEx(WH_MOUSE_LL, HookProcMouse, GetModuleHandle(NULL), NULL); assert(hHook); return a.exec(); } Всё работает, координаты приходят! Хоть какой-то успех за два дня! Но вот с глобальным всё так же плохо... Пожалуйста, Верес, помогите) Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 04, 2012, 15:42 Я нашла решение. Можно использовать локальные и с помощью сигналов пересылать данные. Спасибо вам большое)
Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 04, 2012, 16:33 Верес, вы не подскажите а как антивирусник Касперского обойти? Он ругается на хуки?
Хакеры это как-то же делают ;) Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 04, 2012, 16:46 Ещё вопросик. Я так же написала класс который отлавливает все нажатия на клавиатуре, правда с хуками. А можно это как-то средствами qt сделать? Мне собственно нужно подсчитывать сколько было нажато клавиш в каждую минуту времени. Подскажите пожалуйста кроссплатформенное решение кто-нибудь.
Название: Re: События перемещения мыши Отправлено: Bepec от Июль 04, 2012, 16:48 Мне уже начинает надоедать :D
Вы хотите перехватывать нажатия клавиш без перехвата? :) Перечитайте третий помоему ответ на ваш вопрос в этой теме. PS вы видимо неправильно ставите хуки, или же творите что-то страшное. Ибо каспер на правильно поставленный глобальный хук не ругается. Название: Re: События перемещения мыши Отправлено: lighting от Июль 05, 2012, 09:02 Bepec ты решил тут мастер-класс по троянописанию устроить? :)
Название: Re: События перемещения мыши Отправлено: Bepec от Июль 05, 2012, 10:16 lighting - если Windows описала механизм создания хуков, описала их Api, использует их везде где только можно и РЕКОМЕНДУЕТ их использовать, это можно назвать троянописанием? :D
PS вот методы сокрытия хука я раскрывать не собираюсь :D А так это - необходимые основы для многих программ. Название: Re: События перемещения мыши Отправлено: virtual_root от Июль 05, 2012, 16:08 А может всё-таки раскроете методы сокрытия хуков? ???
Название: Re: События перемещения мыши Отправлено: Bepec от Июль 05, 2012, 23:35 -
это не тема для разработки обычных программ. |