BorlandTalk.com Forum Index BorlandTalk.com
Borland discussion newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Global window hook

 
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Native API)
View previous topic :: View next topic  
Author Message
roger
Guest





PostPosted: Thu Feb 24, 2005 6:39 am    Post subject: Global window hook Reply with quote



Can someone please tell me the best way(if poss) to hook via a DLL when
windows opens or closes a new window of any kind so that i can call the
FindWindow only when the window list changes..

Thanks in advance..



Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Feb 24, 2005 7:20 am    Post subject: Re: Global window hook Reply with quote




"roger" <rogersmail (AT) ntlworld (DOT) com> wrote


Quote:
Can someone please tell me the best way(if poss) to hook via
a DLL when windows opens or closes a new window of any
kind

Look at the WH_CBT hook. It has HCBT_CREATEWND and HCBT_DESTROYWND
notifications.


Gambit



Back to top
roger
Guest





PostPosted: Thu Feb 24, 2005 7:58 am    Post subject: Re: Global window hook Reply with quote



Thanks

"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote

Quote:

"roger" <rogersmail (AT) ntlworld (DOT) com> wrote in message
news:421d76a8 (AT) newsgroups (DOT) borland.com...

Can someone please tell me the best way(if poss) to hook via
a DLL when windows opens or closes a new window of any
kind

Look at the WH_CBT hook. It has HCBT_CREATEWND and HCBT_DESTROYWND
notifications.


Gambit





Back to top
roger
Guest





PostPosted: Thu Feb 24, 2005 11:58 am    Post subject: Re: Global window hook Reply with quote

Hi REMY...

I have found a snippet that you posted some while ago which i have created
and added the lib to the below project, but i am not getting any response
from the dll when a window opens or closes.

=============================
****** Header File contents *******
=============================

#ifndef mainUnitH
#define mainUnitH
//--------------------------------------------------------------------------
-
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>

//--------------------------------------------------------------------------
-
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMemo *Memo1;
void __fastcall WMCopyData(TMessage &Message);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
public:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, WMCopyData)
END_MESSAGE_MAP(TForm)
__fastcall TForm1(TComponent* Owner);
};
//--------------------------------------------------------------------------
-
extern PACKAGE TForm1 *Form1;
//--------------------------------------------------------------------------
-
#endif

==========================
******* cpp file contents *******
==========================
//--------------------------------------------------------------------------
-

#include <vcl.h>
#pragma hdrstop

#include "mainUnit.h"
//--------------------------------------------------------------------------
-
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
extern "C" {
bool __stdcall __declspec(dllexport) InstallHook(void);
bool __stdcall __declspec(dllexport) RemoveHook(void);
}
//--------------------------------------------------------------------------
-
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
InstallHook();
}
//--------------------------------------------------------------------------
-
void __fastcall TForm1::WMCopyData(TMessage &Message)
{
COPYDATASTRUCT *cds = (COPYDATASTRUCT*)Message.LParam;
if(cds->dwData == 10000) // message we sent ourselves
{
char *buffer = new char[cds->cbData];
memcpy(buffer, cds->lpData, cds->cbData);
Memo1->Lines->Add(buffer);
}
else
// we're not interested in this message, pass to default handling
TForm::Dispatch(&Message);
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
RemoveHook();
}
//--------------------------------------------------------------------------
-

***** end *****

"roger" <rogersmail (AT) ntlworld (DOT) com> wrote

Quote:
Thanks

"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote in message
news:421d81d6 (AT) newsgroups (DOT) borland.com...

"roger" <rogersmail (AT) ntlworld (DOT) com> wrote in message
news:421d76a8 (AT) newsgroups (DOT) borland.com...

Can someone please tell me the best way(if poss) to hook via
a DLL when windows opens or closes a new window of any
kind

Look at the WH_CBT hook. It has HCBT_CREATEWND and HCBT_DESTROYWND
notifications.


Gambit







Back to top
roger
Guest





PostPosted: Thu Feb 24, 2005 12:01 pm    Post subject: Re: Global window hook Reply with quote

this is the DLL contents;;

-------------------------------
#include <vcl.h>
#include <windows.h>
#pragma pack(1)
typedef struct tagMSGGLOBAL
{
HWND hHandle;
} TMSGGLOBAL;
typedef TMSGGLOBAL* PMSGGLOBAL;
#pragma pack()

HINSTANCE hInst;
HANDLE hObjHandle;
PMSGGLOBAL lpMsgGlobal;
HHOOK hHook = NULL;
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam);

extern "C" {
__declspec(dllexport) PMSGGLOBAL __stdcall GetGlobalPointer(void);
bool __stdcall __declspec(dllexport) InstallHook(void);
bool __stdcall __declspec(dllexport) RemoveHook(void);
}

void __fastcall MapFileMemory(DWORD dwAllocSize)
{
// Create a process wide memory mapped variable
if( hObjHandle == NULL )
{
hObjHandle = CreateFileMapping((HANDLE)0xFFFFFFFF, NULL,
PAGE_READWRITE, 0, dwAllocSize,
"HookGlobalMemBlock" );

if( hObjHandle == NULL )
{
MessageBox( 0, "Could not create file map object",
"Hook DLL", MB_OK );
return;
}
}

// 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 )
{
lpMsgGlobal->hHandle = NULL;
}
else
{
CloseHandle( hObjHandle );
MessageBox( 0, "Could not map file", "Hook DLL", MB_OK );
return;
}
}
}

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

if( hObjHandle > 0 )
{
CloseHandle( hObjHandle );
hObjHandle = 0;
}
}

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

LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if( ( nCode >= 0 ) && ( nCode == HCBT_CREATEWND ) &&
lpMsgGlobal->hHandle != NULL )
{
HWND hWnd = (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,(LPARAM)&cds );
}
}
else
if( ( nCode >= 0 ) && ( nCode == HCBT_DESTROYWND ) &&
lpMsgGlobal->hHandle != NULL )
{
HWND hWnd = (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,(LPARAM)&cds );
}
}


return CallNextHookEx( hHook, nCode, wParam, lParam );
}

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

return ( hHook != NULL );
}

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

return ( hHook == NULL );
}

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


-------------------------------

"roger" <rogersmail (AT) ntlworld (DOT) com> wrote

Quote:
Hi REMY...

I have found a snippet that you posted some while ago which i have created
and added the lib to the below project, but i am not getting any response
from the dll when a window opens or closes.

=============================
****** Header File contents *******
=============================

#ifndef mainUnitH
#define mainUnitH

//--------------------------------------------------------------------------
-
#include <Classes.hpp
#include #include #include

//--------------------------------------------------------------------------
-
class TForm1 : public TForm
{
__published: // IDE-managed Components
TMemo *Memo1;
void __fastcall WMCopyData(TMessage &Message);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
public:
BEGIN_MESSAGE_MAP
VCL_MESSAGE_HANDLER(WM_COPYDATA, TMessage, WMCopyData)
END_MESSAGE_MAP(TForm)
__fastcall TForm1(TComponent* Owner);
};

//--------------------------------------------------------------------------
-
extern PACKAGE TForm1 *Form1;

//--------------------------------------------------------------------------
-
#endif

==========================
******* cpp file contents *******
==========================

//--------------------------------------------------------------------------
-

#include #pragma hdrstop

#include "mainUnit.h"

//--------------------------------------------------------------------------
-
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
extern "C" {
bool __stdcall __declspec(dllexport) InstallHook(void);
bool __stdcall __declspec(dllexport) RemoveHook(void);
}

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

//--------------------------------------------------------------------------
-
void __fastcall TForm1::WMCopyData(TMessage &Message)
{
COPYDATASTRUCT *cds = (COPYDATASTRUCT*)Message.LParam;
if(cds->dwData == 10000) // message we sent ourselves
{
char *buffer = new char[cds->cbData];
memcpy(buffer, cds->lpData, cds->cbData);
Memo1->Lines->Add(buffer);
}
else
// we're not interested in this message, pass to default handling
TForm::Dispatch(&Message);
}
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
RemoveHook();
}

//--------------------------------------------------------------------------
-

***** end *****

"roger" <rogersmail (AT) ntlworld (DOT) com> wrote in message
news:421d891c (AT) newsgroups (DOT) borland.com...
Thanks

"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote in message
news:421d81d6 (AT) newsgroups (DOT) borland.com...

"roger" <rogersmail (AT) ntlworld (DOT) com> wrote in message
news:421d76a8 (AT) newsgroups (DOT) borland.com...

Can someone please tell me the best way(if poss) to hook via
a DLL when windows opens or closes a new window of any
kind

Look at the WH_CBT hook. It has HCBT_CREATEWND and HCBT_DESTROYWND
notifications.


Gambit









Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Feb 24, 2005 6:23 pm    Post subject: Re: Global window hook Reply with quote


"roger" <rogersmail (AT) ntlworld (DOT) com> wrote


Quote:
extern "C" {
bool __stdcall __declspec(dllexport) InstallHook(void);
bool __stdcall __declspec(dllexport) RemoveHook(void);
}

The form should be importing the functions, not exporting them.

Quote:
char *buffer = new char[cds->cbData];
memcpy(buffer, cds->lpData, cds->cbData);
Memo1->Lines->Add(buffer);

You are leaking the memory you allocated as you are never freeing it. You
don't need to allocate a new buffer anyway, just use the existing buffer in
the message:

Memo1->Lines->Add(AnsiString(cds->lpData, cds->cbData));

Quote:
void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
RemoveHook();
}

I would suggest moving the call to RemoveHook() into the form's destructor
instead. You used the constructor to install the hook, so the destructor is
logical to remove it. Also, OnClose is not guaranteed to always be called
in all situations, but the destructor is.


Gambit



Back to top
Remy Lebeau (TeamB)
Guest





PostPosted: Thu Feb 24, 2005 6:53 pm    Post subject: Re: Global window hook Reply with quote


"roger" <rogersmail (AT) ntlworld (DOT) com> wrote


Quote:
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().

Quote:
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



Back to top
roger
Guest





PostPosted: Thu Feb 24, 2005 9:59 pm    Post subject: Re: Global window hook Reply with quote

Thanks again... no problem now...

"Remy Lebeau (TeamB)" <no.spam (AT) no (DOT) spam.com> wrote

Quote:

"roger" <rogersmail (AT) ntlworld (DOT) com> wrote in message
news:421dc13d$1 (AT) newsgroups (DOT) borland.com...

extern "C" {
bool __stdcall __declspec(dllexport) InstallHook(void);
bool __stdcall __declspec(dllexport) RemoveHook(void);
}

The form should be importing the functions, not exporting them.

char *buffer = new char[cds->cbData];
memcpy(buffer, cds->lpData, cds->cbData);
Memo1->Lines->Add(buffer);

You are leaking the memory you allocated as you are never freeing it. You
don't need to allocate a new buffer anyway, just use the existing buffer
in
the message:

Memo1->Lines->Add(AnsiString(cds->lpData, cds->cbData));

void __fastcall TForm1::FormClose(TObject *Sender, TCloseAction &Action)
{
RemoveHook();
}

I would suggest moving the call to RemoveHook() into the form's destructor
instead. You used the constructor to install the hook, so the destructor
is
logical to remove it. Also, OnClose is not guaranteed to always be called
in all situations, but the destructor is.


Gambit





Back to top
Display posts from previous:   
Post new topic   Reply to topic    BorlandTalk.com Forum Index -> C++ Builder (Native API) All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.