Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, 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;