🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: borland.public.cppbuilder.nativeapi
Article #7265

Re: Global window hook

#7265
From: Remy Lebeau (TeamB)
Date: Thu, 24 Feb 2005 18:53
252 lines
8134 bytes
"roger" <rogersmail@ntlworld.com> wrote in message
news:421dc1e6@newsgroups.borland.com...

> typedef struct tagMSGGLOBAL
> {
>     HWND hHandle;
> } TMSGGLOBAL;
> typedef TMSGGLOBAL* PMSGGLOBAL;

You need to put the HHOOK handle into the shared memory as well.  Otherwise,
the hook will not work properly.  Each running process will get its own copy
of the DLL.  Each DLL instance will have its own copy of the local
variables.  If you do not put the HHOOK into the shared memory, then only
the DLL instance associated with your application's process will have a
valid HHOOK available.  The other DLL instances will not, and thus the CBT
callback will be passing an invalid HHOOK to CallNextHookEx().

Also, at no point are you assigning the HWND to point to your application's
window, so the DLL has no way of knowing where to send the WM_COPYDATA
message.  You should have the application pass its HWND as a parameter to
InstallHook().

> LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam);

You need to export the callback function.  Otherwise other processes will
not be able to call it correctly when needed.

With all of that said, try this code instead:


    --- MyHook.h ---

    #ifndef MyHookH
    #define MyHookH

    #include <windows.h>

    #ifdef COMPILING_DLL
        #define MYHOOKEXPORT __declspec(dllexport)
    #else
        #define MYHOOKEXPORT __declspec(dllimport)
    #endif

    #include <pshpack1.h>
    typedef struct tagMSGGLOBAL
    {
        HWND hHandle;
        HHOOK hHook;
    } TMSGGLOBAL;
    typedef TMSGGLOBAL* PMSGGLOBAL;
    #include <poppack.h>

    #ifdef __cplusplus
    extern "C" {
    #endif

    MYHOOKEXPORT PMSGGLOBAL __stdcall GetGlobalPointer(void);
    MYHOOKEXPORT bool __stdcall InstallHook(HWND);
    MYHOOKEXPORT bool __stdcall RemoveHook(void);

    #ifdef __cplusplus
    }
    #endif

    #endif


    --- Dll.cpp ---

    #define COMPILING_DLL
    #include "MyHook.h"

    HINSTANCE hInst = NULL;
    HANDLE hObjHandle = NULL;
    PMSGGLOBAL lpMsgGlobal = NULL;

    extern "C" __declspec(dllexport) LRESULT CALLBACK CBTProc(int nCode,
WPARAM wParam, LPARAM lParam);

    bool __fastcall MapFileMemory(DWORD dwAllocSize)
    {
        // Create a process wide memory mapped variable
        if( hObjHandle == NULL )
        {
            hObjHandle = CreateFileMapping(INVALID_HANDLE_VALUE, NULL,
PAGE_READWRITE, 0, dwAllocSize, "HookGlobalMemBlock");
            if( hObjHandle == NULL )
            {
                MessageBox(NULL, "Could not create file map object", "Hook
DLL", MB_OK);
                return false;
            }
        }

        // Get a pointer to our process wide memory mapped variable
        if( lpMsgGlobal == NULL )
        {
            lpMsgGlobal = (PMSGGLOBAL) MapViewOfFile(hObjHandle,
FILE_MAP_WRITE, 0, 0, dwAllocSize);
            if( lpMsgGlobal == NULL )
            {
                CloseHandle(hObjHandle);
                hObjHandle = NULL;
                MessageBox(NULL, "Could not map file", "Hook DLL", MB_OK);
                return false;
            }
            lpMsgGlobal->hHandle = NULL;
            lpMsgGlobal->hHook = NULL;
        }

        return true;
    }

    void __fastcall UnMapFileMemory(void)
    {
        // Delete our process wide memory mapped variable
        if( lpMsgGlobal != NULL )
        {
            UnmapViewOfFile(lpMsgGlobal);
            lpMsgGlobal = NULL;
        }

        if( hObjHandle != NULL )
        {
            CloseHandle(hObjHandle);
            hObjHandle = NULL;
        }
    }

    LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
    {
        if( (nCode >= 0) && (lpMsgGlobal->hHandle != NULL) )
        {
            if( (nCode == HCBT_CREATEWND) || (nCode == HCBT_DESTROYWND) )
            {
                HWND hWnd = reinterpret_cast<HWND>(wParam);
                char buffer[256] = {0};
                COPYDATASTRUCT cds;

                cds.dwData = 10000; // some arbitrary value unique to your
app
                cds.cbData = ::GetWindowText(hWnd, buffer, 256);
                cds.lpData = buffer;

                ::SendMessage(lpMsgGlobal->hHandle, WM_COPYDATA, 0,
reinterpret_cast<LPARAM>(&cds));
            }
        }
        return CallNextHookEx(lpMsgGlobal->hHook, nCode, wParam, lParam);
    }

    PMSGGLOBAL __stdcall GetGlobalPointer(void)
    {
        // Return a pointer to our process wide memory mapped variable
        return lpMsgGlobal;
    }

    bool __stdcall InstallHook(HWND hWnd)
    {
        if( lpMsgGlobal->hHook == NULL )
        {
            lpMsgGlobal->hHook = SetWindowsHookEx(WH_CBT, (HOOKPROC)CBTProc,
hInst, 0);
            if( lpMsgGlobal->hHook == NULL )
                MessageBox( NULL, "Could not set hook", "Hook DLL", MB_OK );
        }
        return (lpMsgGlobal->hHook != NULL);
    }

    bool __stdcall RemoveHook(void)
    {
        if( lpMsgGlobal->hHook != NULL )
        {
            if( UnhookWindowsHookEx(lpMsgGlobal->hHook) )
                lpMsgGlobal->hHook = NULL;
            else
                MessageBox(NULL, "Could not release hook", "Hook DLL",
MB_OK);
        }
        return (lpMsgGlobal->hHook == NULL);
    }

    #pragma argsused
    int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void*
lpReserved)
    {
        hInst = hinst;
        switch( reason )
        {
            case DLL_PROCESS_ATTACH:
                if( !MapFileMemory(sizeof(TMSGGLOBAL)) )
                    return 0;
                break;
            case DLL_PROCESS_DETACH:
                UnMapFileMemory();
                break;
        }
        return 1;
    }


    --- mainUnit.hpp ---

    class TForm1 : public TForm
    {
    __published:
        TMemo *Memo1;
    private:
        void __fastcall WMCopyData(TMessage &Message);
    public:
        __fastcall TForm1(TComponent* Owner);
        __fastcall ~TForm1();
        BEGIN_MESSAGE_MAP
            VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, WMCopyData)
        END_MESSAGE_MAP(TForm)
    };


    --- mainUnit.cpp ---

    #include "mainUnit.h"
    #include "MyHook.h"

    __fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
    {
        InstallHook(Handle);
    }

    __fastcall TForm1::~TForm1()
    {
        RemoveHook();
    }

    void __fastcall TForm1::WMCopyData(TMessage &Message)
    {
        COPYDATASTRUCT *cds =
reinterpret_cast<COPYDATASTRUCT*>(Message.LParam)
        if( cds->dwData == 10000 )
        {
            Memo1->Lines->Add(AnsiString(cds->lpData, cds->cbData));
            Message.Result = TRUE;
        }
        else
            // we're not interested in this message, pass to default
handling
            TForm::Dispatch(&Message);
    }


Gambit
Technical Details
Message-ID: <421e22b2$1@newsgroups.borland.com>
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!feeder2.on.meganewsservers.com!meganewsservers.com!textfeed1.on.meganewsservers.com!38.119.100.83.MISMATCH!news-out.nntp.be!propagator2-sterling.newsfeeds.com!news-in.newsfeeds.com!in.nntp.be!caladan.landsraad.net!newsgroups.borland.com!not-for-mail
References: <421d76a8@newsgroups.borland.com> <421d81d6@newsgroups.borland.com> <421d891c@newsgroups.borland.com> <421dc13d$1@newsgroups.borland.com> <421dc1e6@newsgroups.borland.com>

Show Full Headers
Complete Article Headers
X-Google-Thread: 10cc67,9b9eac270d6034d6
X-Google-Attributes: gid10cc67,public
X-Google-Language: ENGLISH,ASCII-7-bit
From: "Remy Lebeau \(TeamB\)" <no.spam@no.spam.com>
Newsgroups: borland.public.cppbuilder.nativeapi
References: <421d76a8@newsgroups.borland.com> <421d81d6@newsgroups.borland.com> <421d891c@newsgroups.borland.com> <421dc13d$1@newsgroups.borland.com> <421dc1e6@newsgroups.borland.com>
Subject: Re: Global window hook
Date: Thu, 24 Feb 2005 10:53:40 -0800
Lines: 254
X-Priority: 3
X-MSMail-Priority: Normal
X-Newsreader: Microsoft Outlook Express 6.00.2800.1409
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409
NNTP-Posting-Host: 68.69.17.41
Message-ID: <421e22b2$1@newsgroups.borland.com>
X-Trace: newsgroups.borland.com 1109271218 68.69.17.41 (24 Feb 2005 10:53:38 -0800)
Path: arc1-ca.pugleaf.net!g2news1.google.com!news4.google.com!news.glorb.com!feeder2.on.meganewsservers.com!meganewsservers.com!textfeed1.on.meganewsservers.com!38.119.100.83.MISMATCH!news-out.nntp.be!propagator2-sterling.newsfeeds.com!news-in.newsfeeds.com!in.nntp.be!caladan.landsraad.net!newsgroups.borland.com!not-for-mail