Hi,

I know the code for this post is quite long, but I thought it would be best to be comprehensive about what i'm trying to do as i'm not exactly an expert in this area of programming. I'm stuck trying to work out how to get windows hook procedures to work and am trying to get simple ostream messages to print in the console window to show a hook procedure is working.

I have created the following code to load windows hooks via the SetWindowsHookEx function in a c++ (VS 2010, windows 7) console application:

int _tmain(int argc, _TCHAR* argv[]) 
{ 

/////////////////////////////////////////////////////////////////////////////////////////////////
// HOOK PROCEDURES /////////////////////////////////////////////////////////////////////////////////////////////////
static HINSTANCE hinstDLL; 
hinstDLL = LoadLibrary(TEXT("C:\\HOOK_DLL\\Debug\\HOOK_DLL.dll")); 

//-----------------------------------------------------------------------------------------------
HOOKPROC hkprcCALLWNDPROC;
static HHOOK hhookCALLWNDPROC; 

hkprcCALLWNDPROC = (HOOKPROC)GetProcAddress(hinstDLL, "CALLWNDPROC"); 
hhookCALLWNDPROC = SetWindowsHookEx(	WH_CALLWNDPROC,
					hkprcCALLWNDPROC,
					hinstDLL,
					0); 
cout<<"WH_CALLWNDPROC set"<<endl;
//-----------------------------------------------------------------------------------------------
HOOKPROC hkprcCALLWNDPROCRET;
static HHOOK hhookCALLWNDPROCRET; 

hkprcCALLWNDPROCRET = (HOOKPROC)GetProcAddress(hinstDLL, "CALLWNDPROCRET"); 
hhookCALLWNDPROCRET = SetWindowsHookEx(	WH_CALLWNDPROCRET,
					hkprcCALLWNDPROCRET,
					hinstDLL,
					0); 

cout<<"WH_CALLWNDPROCRET set"<<endl;
//----------------------------------------------------------------------------------------------
HOOKPROC hkprcCBT;
static HHOOK hhookCBT; 

hkprcCBT = (HOOKPROC)GetProcAddress(hinstDLL, "CBT"); 
hhookCBT = SetWindowsHookEx(	WH_CBT,
				hkprcCBT,
				hinstDLL,
				0); 
cout<<"WH_CBT set"<<endl;
//----------------------------------------------------------------------------------------------
HOOKPROC hkprcGETMSG;
static HHOOK hhookGETMSG; 

hkprcGETMSG = (HOOKPROC)GetProcAddress(hinstDLL, "GETMESSAGE"); 
hhookGETMSG = SetWindowsHookEx(	WH_GETMESSAGE,
				hkprcGETMSG,
				hinstDLL,
				0); 
cout<<"WH_GETMSG set"<<endl;
//-----------------------------------------------------------------------------------------------
HOOKPROC hkprcJOURNALRECORD;
static HHOOK hhookJOURNALRECORD; 

hkprcJOURNALRECORD = (HOOKPROC)GetProcAddress(hinstDLL, "JOURNALRECORD"); 
hhookJOURNALRECORD = SetWindowsHookEx(	WH_JOURNALRECORD,
					hkprcJOURNALRECORD,
					hinstDLL,
					0); 
cout<<"WH_JOURNALRECORD set"<<endl;
//-----------------------------------------------------------------------------------------------
HOOKPROC hkprcSYSMSGFILTER;
static HHOOK hhookSYSMSGFILTER; 

hkprcSYSMSGFILTER = (HOOKPROC)GetProcAddress(hinstDLL, "SYSMSGFILTER"); 
hhookSYSMSGFILTER = SetWindowsHookEx(	WH_SYSMSGFILTER,
					hkprcSYSMSGFILTER,
					hinstDLL,
					0); 
cout<<"WH_SYSMSGFILTER set"<<endl;
/////////////////////////////////////////////////////////////////////////////////////////////////
// HOOK PROCEDURES END///////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

//----------------------------------------------------------------------------------------------
// I USE THIS FOLLOWING BIT TO TEST THE DLL CONNECTION
//----------------------------------------------------------------------------------------------
MYPROC ProcAdd; 
BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 

// Get a handle to the DLL module.
	if (hinstDLL != NULL)											// If the handle is valid...
	{ 

// ...try to get the function address.
	ProcAdd = (MYPROC) GetProcAddress(hinstDLL, "TESTDLL");	

// If the function address is valid, call the function.
		if (NULL != ProcAdd)										
		{
		fRunTimeLinkSuccess = TRUE;
// print msg to the console if the dll is loaded properly via the procadd dll function
		(ProcAdd) (L"Message sent to the DLL function\n"); 
		}

	fFreeResult = FreeLibrary(hinstDLL);							// Free the DLL module.
	} 

	if (! fRunTimeLinkSuccess)										// If unable to call the DLL function, use an alternative msg
	printf("Message printed from executable\n"); 
	system("PAUSE");

/////////////////////////////////////////////////////////////////////////////////////////////////
// these following lines load a GUI which is used to interface with other program functions
/////////////////////////////////////////////////////////////////////////////////////////////////
	Application::EnableVisualStyles(); 
        Application::SetCompatibleTextRenderingDefault(false); 
        Application::Run(gcnew GUI()); 
        return 0; 
/////////////////////////////////////////////////////////////////////////////////////////////////

}

I know the dll is called successfully because the 'Message sent to the DLL function' message appears in the console output but I expected that setting the combination of WH_CALLWNDPROC, WH_CALLWNDPROCRET, WH_CBT, WH_CALLWNDPROCRET, WH_JOURNALRECORD, WH_SYSMSGFILTER etc. hooks I would see my related dll procedures (cout<<prints to the console window) run as the computer's other programs called the hooks (when the computer opened new windows in other applications etc.)

The code for my dll is below, it should just give simple console messages if the hooks are called, via the associated dll functions:

#include "stdafx.h"
#include "HOOK_DLL.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

BEGIN_MESSAGE_MAP(CHOOK_DLLApp, CWinApp)
END_MESSAGE_MAP()

CHOOK_DLLApp::CHOOK_DLLApp()
{
}

CHOOK_DLLApp theApp;

BOOL CHOOK_DLLApp::InitInstance()
{
	CWinApp::InitInstance();

	return TRUE;
}

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

#include <windows.h>
#include <iostream>
using namespace std;

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

LRESULT CALLBACK CALLWNDPROC(	int nCode, 
				WPARAM wParam, 
				LPARAM lParam) 
{
	if (nCode < 0)
	return CallNextHookEx(NULL, nCode, wParam, lParam);

	switch (nCode)
	{
		case HC_ACTION:	
		cout<<"CALLWNDPROC called HC_ACTION"<<endl;
		break;
		default:
		cout<<"CALLWNDPROC called"<<endl;
	}

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

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

LRESULT CALLBACK CALLWNDPROCRET(int nCode, 
				WPARAM wParam, 
				LPARAM lParam) 
{
	if (nCode < 0)
	return CallNextHookEx(NULL, nCode, wParam, lParam);

	switch (nCode)
	{
		case HC_ACTION:	
		cout<<"CALLWNDPROCRET called HC_ACTION"<<endl;
		break;
		default:
		cout<<"CALLWNDPROCRET called"<<endl;
	}

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

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

LRESULT CALLBACK CBT(	int nCode,
			WPARAM wParam,
			LPARAM lParam)
{
	if (nCode < 0)
	return CallNextHookEx(NULL, nCode, wParam, lParam);

	switch (nCode)
	{
		case HCBT_ACTIVATE:	
		cout<<"CBT called HCBT_ACTIVATE"<<endl;
		break;

		case HCBT_CLICKSKIPPED:	
		cout<<"CBT called HCBT_CLICKSKIPPED"<<endl;
		break;

		case HCBT_CREATEWND:	
		cout<<"CBT called HCBT_CREATEWND"<<endl;
		break;

		case HCBT_DESTROYWND:	
		cout<<"CBT called HCBT_DESTROYWND"<<endl;
		break;

		case HCBT_KEYSKIPPED:	
		cout<<"CBT called HCBT_KEYSKIPPED"<<endl;
		break;

		case HCBT_MINMAX:	
		cout<<"CBT called HCBT_MINMAX"<<endl;
		break;

		case HCBT_MOVESIZE:	
		cout<<"CBT called HCBT_MOVESIZE"<<endl;
		break;

		case HCBT_QS:	
		cout<<"CBT called HCBT_QS"<<endl;
		break;

		case HCBT_SETFOCUS:	
		cout<<"CBT called HCBT_SETFOCUS"<<endl;
		break;

		case HCBT_SYSCOMMAND:	
		cout<<"CBT called HCBT_SYSCOMMAND"<<endl;
		break;

		default:
		cout<<"CBT called"<<endl;
	}

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

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

LRESULT CALLBACK GETMESSAGE(    int nCode, 
				WPARAM wParam, 
				LPARAM lParam) 
{
	if (nCode < 0)
	return CallNextHookEx(NULL, nCode, wParam, lParam);

	switch (nCode)
	{
		case HC_ACTION:	
		cout<<"GETMSG called HC_ACTION"<<endl;
		break;
		default:
		cout<<"GETMSG called"<<endl;
	}

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

//-----------------------------------------------------------------------------------------------
LRESULT CALLBACK JOURNALRECORD( int code, 
				WPARAM wParam, 
				LPARAM lParam) 
 
{
	if (code < 0)
	return CallNextHookEx(NULL, code, wParam, lParam);

	switch (code)
	{
		case HC_ACTION:
		cout<<"JOURNALRECORD called HC_ACTION"<<endl;
		break;
		case HC_SYSMODALOFF:	
		cout<<"JOURNALRECORD called HC_SYSMODALOFF"<<endl;
		break;
		case HC_SYSMODALON:	
		cout<<"JOURNALRECORD called HC_SYSMODALON"<<endl;
		break;
		default:
		cout<<"JOURNALRECORD called"<<endl;
	}

	return CallNextHookEx(NULL, code, wParam, lParam);
}

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

LRESULT CALLBACK SYSMSGFILTER(  int nCode, 
				WPARAM wParam, 
				LPARAM lParam) 
{
	if (nCode < 0)
	return CallNextHookEx(NULL, nCode, wParam, lParam);

	switch (nCode)
	{
		case MSGF_DIALOGBOX:	
		cout<<"SYSMSGFILTER called MSGF_DIALOGBOX"<<endl;
		break;
		case MSGF_MENU:	
		cout<<"SYSMSGFILTER called MSGF_MENU"<<endl;
		break;
		case MSGF_SCROLLBAR:	
		cout<<"SYSMSGFILTER called MSGF_SCROLLBAR"<<endl;
		break;
		default:
		cout<<"SYSMSGFILTER called"<<endl;
	}

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

///////////////////////////////////////////////////////////////////////////////////////////////
// NEXT BIT IS THE TEST USED BY THE MAIN PROGRAM TO TEST THE DLL LOADS PROPERLY
///////////////////////////////////////////////////////////////////////////////////////////////

#define EOF (-1)

#ifdef __cplusplus    			     
extern "C" 
{			         			    
#endif
 
	__declspec(dllexport) int __cdecl TESTDLL(LPWSTR lpszMsg)
	{
	DWORD cchWritten;
	HANDLE hConout;
	BOOL fRet;

cout<<"DLL printing via cout"<<endl;

	hConout = CreateFileW(
	L"CONOUT$",		
	GENERIC_WRITE,		
	FILE_SHARE_WRITE,	
	NULL,			
	OPEN_EXISTING,			
	FILE_ATTRIBUTE_NORMAL,
	NULL);				

	if (INVALID_HANDLE_VALUE == hConout)
	return EOF;
		while (*lpszMsg != L'\0')
		{
		fRet = WriteConsole(	
		hConout,		
		lpszMsg,		
		1,						
		&cchWritten,			
		NULL);				
			if( (FALSE == fRet) || (1 != cchWritten) )
			return EOF;
		lpszMsg++;
		}
	return 1;
	}
 
	#ifdef __cplusplus
}
#endif

Can anyone tell me if i'm making some sort of basic error? Am i misinterpreting the use of the WH_CALLWNDPROC, WH_CALLWNDPROCRET, WH_CBT, WH_CALLWNDPROCRET, WH_JOURNALRECORD, WH_SYSMSGFILTER hooks? Any help / examples would be greatly appreciated. As I say, i have very little experience doing this kind of programming.

Carrythe1

Does anyone have any comment on this? its my second post on the subject and i don't seem to be getting any feedback...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.