 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
roger Guest
|
Posted: Thu Feb 24, 2005 6:39 am Post subject: Global window hook |
|
|
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
|
Posted: Thu Feb 24, 2005 7:20 am Post subject: Re: Global window hook |
|
|
"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
|
Posted: Thu Feb 24, 2005 7:58 am Post subject: Re: Global window hook |
|
|
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
|
Posted: Thu Feb 24, 2005 11:58 am Post subject: Re: Global window hook |
|
|
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
|
Posted: Thu Feb 24, 2005 12:01 pm Post subject: Re: Global window hook |
|
|
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
|
Posted: Thu Feb 24, 2005 6:23 pm Post subject: Re: Global window hook |
|
|
"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
|
Posted: Thu Feb 24, 2005 6:53 pm Post subject: Re: Global window hook |
|
|
"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
|
Posted: Thu Feb 24, 2005 9:59 pm Post subject: Re: Global window hook |
|
|
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 |
|
 |
|
|
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
|
|