Re[3]: Global Mouse Hook
От: MaximSL  
Дата: 18.06.08 22:41
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, VoidEx, Вы писали:

VE>>Из-за (1) у вас возвращается нуль, а из-за (2) — обращение по этому нулю.
А>Большое спасибо за помощь! Dll загружается, но хук все же не работает ...
А>Может быть у кого-нибудь есть что подсказать.

А>Вот мой конечный вариант кода:


А>--- код dll [сборка в MS VS2005] ---


А>
А>// mousehook.cpp : Defines the entry point for the DLL application.

А>#include "stdafx.h"

А>#pragma data_seg(".hdata") // секция в памяти общая для всех процессов
А>HWND hWndServer = NULL; // эта переменная может изменяться любым процессом, поэтому здесь не д.б. ничего лишнего
А>#pragma data_seg() // конец секции
А>#pragma comment(linker, "/section:.hdata,rws") // даем права этой секции

А>#ifdef __cplusplus 
А>#define EXPORT extern "C" __declspec(dllexport) 
А>#else 
А>#define EXPORT __declspec(dllexport) 
А>#endif

А>// объявление функции обратного вызова
А>LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam);

А>// глобальные переменные
А>HHOOK HookHandle; 
А>HINSTANCE DllInstance; 

А>#ifdef _MANAGED
А>#pragma managed(push, off)
А>#endif
А>//----------------------------------------------------------------------
А>EXPORT BOOL InstallMouseHook(HWND AWnd) {    
А>    if(hWndServer != NULL)
А>        return false;
    
А>    HookHandle = SetWindowsHookEx(WH_GETMESSAGE, 
А>        reinterpret_cast<HOOKPROC>(MouseProc), DllInstance, NULL);

А>    HookHandle = SetWindowsHookEx(WH_MOUSE, 
А>        reinterpret_cast<HOOKPROC>(MouseProc), DllInstance, NULL);
    
А>    if(HookHandle == NULL)
А>        return false;
А>    return true;
А> } 
А>//----------------------------------------------------------------------
А>EXPORT BOOL RemoveMouseHook(HWND AWnd //окно, чей хук должен быть снят
А>                            )
А>{ 
А>    if(AWnd != hWndServer)
А>        return false;
    
А>    BOOL unhooked = UnhookWindowsHookEx(HookHandle);
А>    if(unhooked)
А>        hWndServer = NULL;
А>    return unhooked;
А> } 
А>//----------------------------------------------------------------------
А>LRESULT CALLBACK MouseProc(int code, WPARAM wParam, LPARAM lParam) { 
А>    if(code < 0) { 
А>        CallNextHookEx(HookHandle, code, wParam, lParam);
А>        return 0;
А>    }

А>    LPMSG msg = (LPMSG)lParam;

А>    if( (hWndServer = FindWindow(L"TForm1", L"Form1")) == NULL )
А>        return 0;
А>    else {
А>        if(msg->message == WM_LBUTTONDOWN || msg->message == WM_LBUTTONUP ||
            msg->>message == WM_RBUTTONDOWN || msg->message == WM_RBUTTONUP )
А>            PostMessage(hWndServer, msg->message, 0, 0); 
А>    }
   
А>    // вызываем следующий хук в цепи 
А>    return CallNextHookEx(HookHandle, code, wParam, lParam); 
А> }
А>//----------------------------------------------------------------------
А>BOOL APIENTRY DllMain( HMODULE hModule,   // дескриптор экземпляра DLL
А>                       DWORD  reason,     // причина вызова
А>                       LPVOID lpReserved  // зарезервировано
А>                     )
А>{
А>    // вызывается каждый раз когда новый процесс грузит DLL в свою память
А>    if( reason == DLL_PROCESS_ATTACH ) {
А>        if( ! hWndServer ) {
А>            // cохраняем дескриптор экземпляра, он понадобится позднее для установки хука
А>            DllInstance = hModule;
А>            return true;
А>        }
А>    } else if( reason == DLL_PROCESS_DETACH ) {
А>        if( hWndServer != NULL )
А>            RemoveMouseHook(hWndServer);// ЕСЛИ сервер не снял хук, снимем его
А>        return true;
А>    }
А>    return TRUE;
А>}
А>//----------------------------------------------------------------------
А>#ifdef _MANAGED
А>#pragma managed(pop)
А>#endif
А>


А>--- исполняемое приложение — сервер [сборка в C++Builder 6.0] ---


А>
А>//---------------------------------------------------------------------------

А>#include <vcl.h>
А>#pragma hdrstop

А>#include "mshookmain.h"
А>//---------------------------------------------------------------------------
А>#pragma package(smart_init)
А>#pragma resource "*.dfm"
А>TForm1 *Form1;
А>typedef bool (__stdcall *MOUSEHOOKFCT)(HWND);
А>//---------------------------------------------------------------------------
А>__fastcall TForm1::TForm1(TComponent* Owner)
А>    : TForm(Owner)
А>{
А>}
А>//---------------------------------------------------------------------------
А>void __fastcall TForm1::Button1Click(TObject *Sender) {
А>    DllHandle = LoadLibrary("mousehook.dll");
А>    MOUSEHOOKFCT InstHook = reinterpret_cast<MOUSEHOOKFCT>
А>        (GetProcAddress(DllHandle, "InstallMouseHook"));
А>    if( ! InstHook )
А>        Label1->Caption = "Unable to set hook!";
А>}
А>//---------------------------------------------------------------------------
А>void __fastcall TForm1::Button2Click(TObject *Sender) {
А>    MOUSEHOOKFCT RemHook = reinterpret_cast<MOUSEHOOKFCT>
А>        (GetProcAddress(DllHandle, "RemoveMouseHook"));
А>    if( ! RemHook )
А>        Label1->Caption = "Unable to remove hook!";

А>    FreeLibrary(DllHandle);
А>}
А>//---------------------------------------------------------------------------
А>void __fastcall TForm1::ApplicationEvents1Message(tagMSG &Msg,
А>      bool &Handled)
А>{
А>    switch( Msg.message ) {
А>        case WM_LBUTTONDOWN :
А>            Label2->Caption = "LEFT MOUSE BUTTON PRESSED!";
А>            break;
А>        case WM_LBUTTONUP :
А>            Label2->Caption = "LEFT MOUSE BUTTON RELEASED!";
А>            break;
А>        case WM_RBUTTONDOWN :
А>            Label2->Caption = "RIGHT MOUSE BUTTON PRESSED!";
А>            break;
А>        case WM_RBUTTONUP :
А>            Label2->Caption = "RIGHT MOUSE BUTTON RELEASED!";
А>            break;
А>    }
А>}
А>


1) 2 хука — 2 HookHandle.
2) HookHandle — в секцию для расшаренных данных. Не забудьте, что расшаренные данные должны быть проинициализированы в обязательном порядке.
3) Защитите доступ к расшаренным переменным
4) Этот код убьет ваш хук когда закроется первое захученое приложение.

if( reason == DLL_PROCESS_DETACH ) {
if( hWndServer != NULL )
RemoveMouseHook(hWndServer);// ЕСЛИ сервер не снял хук, снимем его
return true;
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.