Posts Tagged ‘CBT

13
May
09

[C++] CBT Hook Example

Got bored of doing revision and started on a HookLib, this is an example program where I was testing using a CBT Hook.

header.h

#include "windows.h"

bool SetCBTHook(DWORD, HWND);
void RemoveCBTHook(); 

Main.cpp

#include "header.h"

#define IDC_LIST 4000

HINSTANCE	mhInstance;
HWND		mhWnd;
HWND		lvhWnd;

LRESULT CALLBACK WindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	switch (message)
    {
		case WM_COMMAND:
               break;
		case WM_DESTROY:
			RemoveCBTHook();
			PostQuitMessage (0); 
			break;
		default: 
			return DefWindowProc (hwnd, message, wParam, lParam);
    }
    return 0;
}

BOOL RegisterClass(wchar_t szClassName[])
{
    WNDCLASSEX wc;
    wc.hInstance =  mhInstance;
    wc.lpszClassName = (LPCWSTR)szClassName;
    wc.lpfnWndProc = WindowProc; 
    wc.style = CS_DBLCLKS;
    wc.cbSize = sizeof (WNDCLASSEX);
    wc.hIcon = LoadIcon (NULL, IDI_APPLICATION);
    wc.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
    wc.hCursor = LoadCursor (NULL, IDC_ARROW);
    wc.lpszMenuName = NULL;
    wc.cbClsExtra = 0; 
    wc.cbWndExtra = 0;
    wc.hbrBackground = (HBRUSH) COLOR_BACKGROUND;
    if (!RegisterClassEx (&wc))
		return 0;
	else
		return 1;
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreviousInstance,LPSTR lpcmdline,int nCmdShow)
{
	MSG messages;
	mhInstance = hInstance;
	wchar_t ClassName[ ] = L"CBTHookClass";
	wchar_t WindowName[ ] = L"CBTHookWindow";
	RegisterClass(ClassName);
	mhWnd = CreateWindowEx(WS_EX_CONTROLPARENT, ClassName, WindowName, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX | WS_VISIBLE | WS_MAXIMIZEBOX, 0, 0, 500, 500, NULL, NULL, hInstance, NULL);
	lvhWnd = CreateWindow(L"LISTBOX",L"CBTHookListBox",WS_CHILD|WS_VISIBLE|WS_VSCROLL, 2,2,490,479,mhWnd, (HMENU)IDC_LIST,hInstance, NULL );
	SetCBTHook(GetCurrentThreadId(), mhWnd);
	while (GetMessage (&messages, NULL, 0, 0))
    {
		TranslateMessage(&messages);
        DispatchMessage(&messages);
    }
    return 0;
} 

CBTHook.cpp

#include "header.h"
#include <stdlib.h>
#include <sstream>
#include <string>


HHOOK	CBT_HOOK_ID;
HWND	hWnd;

using namespace std;

std::wstring StringToWString(const std::string& s)
{
	std::wstring temp(s.length(),L' ');
	std::copy(s.begin(), s.end(), temp.begin());
	return temp; 
}

void AddItem(LPCWSTR text) {
	SendDlgItemMessage(hWnd, 4000, LB_ADDSTRING, 0, (LPARAM)text);
}

void AddHWND(WPARAM hwnd) {
	ostringstream oss;
	oss << hex << (int)hwnd;
	wstring Message = L" ---Window Handle: 0x" + StringToWString(oss.str());
	AddItem(Message.c_str());
}

//void AddRECT(RECT rect) {
//	string out;
//	ostringstream oss;
//	oss << rect.top;
//	out = oss.str();
//	oss << rect.bottom;
//	out = out + ", " + oss.str();
//	oss << rect.left;
//	out = out + ", " + oss.str();
//	oss << rect.right;
//	out = out + ", " + oss.str();
//	wstring Message = L"Window Moved/Resized: " + StringToWString(out);
//}

static LRESULT CALLBACK CBTHookProc(int nCode, WPARAM wParam, LPARAM lParam)   
{  
	if(nCode > 0) {
		CBT_CREATEWND	*CBTHOOKCREATE;
		RECT			*CBTRECTPTR;
		RECT			CBTRECT;
		wstring			Message;
		
		switch (nCode)
		{
			case HCBT_ACTIVATE:
				AddItem(L"Window Activated");
			case HCBT_CREATEWND:
				CBTHOOKCREATE = (CBT_CREATEWND*) lParam;
				AddItem(L"Window Created");
				Message = L" ---Window Name: ";
				if(!IsBadReadPtr(CBTHOOKCREATE->lpcs, 1)) {
					if(!IsBadReadPtr(CBTHOOKCREATE->lpcs->lpszName, 1))
						Message = Message + CBTHOOKCREATE->lpcs->lpszName;
				}
				AddItem(Message.c_str());

				Message = L" ---Window Class: ";
				if(!IsBadReadPtr(CBTHOOKCREATE->lpcs, 1)) {
					if(!IsBadReadPtr(CBTHOOKCREATE->lpcs->lpszClass, 1))
						Message = Message + CBTHOOKCREATE->lpcs->lpszClass;
				}
				AddItem(Message.c_str());
				AddHWND(wParam);
			case HCBT_DESTROYWND:
				AddItem(L"Window Destroyed");
			case HCBT_MINMAX:
				switch(lParam)
				{
				case SW_HIDE:
					AddItem(L"Window Hidden");
					break;
				case SW_MAXIMIZE:
					AddItem(L"Window Maximized");
					break;
				case SW_MINIMIZE:
					AddItem(L"Window Minimized");
					break;
				case SW_RESTORE:
					AddItem(L"Window Restored");
					break;
				case SW_SHOW:
					AddItem(L"Window Shown");
					break;
				case SW_SHOWDEFAULT:
					AddItem(L"Window Shown Default");
					break;
				case SW_SHOWMINIMIZED:
					AddItem(L"Window Shown Minimized");
					break;
				case SW_SHOWMINNOACTIVE:
					AddItem(L"Window Shown Minimized (Not Active)");
					break;
				case SW_SHOWNA:
					AddItem(L"Window Shown (Not Active)");
					break;
				case SW_SHOWNOACTIVATE:
					AddItem(L"Window Shown (Not Active)");
					break;
				case SW_SHOWNORMAL:
					AddItem(L"Window Shown");
					break;
				}
				AddHWND(wParam);
			case HCBT_MOVESIZE:
				//CBTRECTPTR = (RECT*) lParam;
				//memcpy(&CBTRECT, CBTRECTPTR, sizeof(RECT));
				//AddRECT(CBTRECT);
				break;
		}
	}
	return CallNextHookEx(CBT_HOOK_ID, nCode, wParam, lParam);  
}

bool SetCBTHook(DWORD ThreadID, HWND ThisMainWindow) {
	hWnd = ThisMainWindow;
	HHOOK CBT_HOOK_ID = ::SetWindowsHookEx(WH_CBT, CBTHookProc, 0, ThreadID);
	MessageBox(NULL, L"Hey", L"There", 1);
	if(CBT_HOOK_ID)
		return true;
	else
		return false;
}

void RemoveCBTHook() {
	UnhookWindowsHookEx(CBT_HOOK_ID);
} 

Its just a quick throw-together of setting a cbt hook on your window, the HookLib exports the hook function, allowing you to hook any process/the entire system.
Also note that the IsBadReadPtr is just there to ensure that the structure returned by the hook is valid, as sometimes it isnt causing the function to die.

Advertisements