Home   Index   About
Ultimate Pack


Custom Search
Monitoring System Events

The following example uses a variety of thread-specific hook procedures to monitor the system for events affecting a thread. It demonstrates how to process events for the following types of hook procedures:

WH_CALLWNDPROC
WH_CBT
WH_DEBUG
WH_GETMESSAGE
WH_KEYBOARD
WH_MOUSE
WH_MSGFILTER

The user can install and remove a hook procedure by using the menu. When a hook procedure is installed and an event that is monitored by the procedure occurs, the procedure writes information about the event to the client area of the application's main window.

#define NUMHOOKS 7

// Global variables

typedef struct _MYHOOKDATA

{

int nType;

HOOKPROC hkprc;

HHOOK hhook;

} MYHOOKDATA;

MYHOOKDATA myhookdata[NUMHOOKS];

LRESULT WINAPI MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam,

LPARAM lParam)

{

static BOOL afHooks[NUMHOOKS];

int index;

static HMENU hmenu;

switch (uMsg)

{

case WM_CREATE:

// Save the menu handle.

hmenu = GetMenu(hwndMain);

// Initialize structures with hook data. The menu-item

// identifiers are defined as 0 through 6 in the

// header file. They can be used to identify array

// elements both here and during the WM_COMMAND

// message.

myhookdata[IDM_CALLWNDPROC].nType = WH_CALLWNDPROC;

myhookdata[IDM_CALLWNDPROC].hkprc = CallWndProc;

myhookdata[IDM_CBT].nType = WH_CBT;

myhookdata[IDM_CBT].hkprc = CBTProc;

myhookdata[IDM_DEBUG].nType = WH_DEBUG;

myhookdata[IDM_DEBUG].hkprc = DebugProc;

myhookdata[IDM_GETMESSAGE].nType = WH_GETMESSAGE;

myhookdata[IDM_GETMESSAGE].hkprc = GetMsgProc;

myhookdata[IDM_KEYBOARD].nType = WH_KEYBOARD;

myhookdata[IDM_KEYBOARD].hkprc = KeyboardProc;

myhookdata[IDM_MOUSE].nType = WH_MOUSE;

myhookdata[IDM_MOUSE].hkprc = MouseProc;

myhookdata[IDM_MSGFILTER].nType = WH_MSGFILTER;

myhookdata[IDM_MSGFILTER].hkprc = MessageProc;

// Initialize all flags in the array to FALSE.

memset(afHooks, FALSE, sizeof(afHooks));

return 0;

case WM_COMMAND:

switch (LOWORD(wParam))

{

// The user selected a hook command from the menu.

case IDM_CALLWNDPROC:

case IDM_CBT:

case IDM_DEBUG:

case IDM_GETMESSAGE:

case IDM_KEYBOARD:

case IDM_MOUSE:

case IDM_MSGFILTER:

// Use the menu-item identifier as an index

// into the array of structures with hook data.

index = LOWORD(wParam);

// If the selected type of hook procedure isn't

// installed yet, install it and check the

// associated menu item.

if (!afHooks[index])

{

myhookdata[index].hhook = SetWindowsHookEx(

myhookdata[index].nType,

myhookdata[index].hkprc,

(HINSTANCE) NULL, GetCurrentThreadId());

CheckMenuItem(hmenu, index,

MF_BYCOMMAND | MF_CHECKED);

afHooks[index] = TRUE;

}

// If the selected type of hook procedure is

// already installed, remove it and remove the

// check mark from the associated menu item.

else

{

UnhookWindowsHookEx(myhookdata[index].hhook);

CheckMenuItem(hmenu, index,

MF_BYCOMMAND | MF_UNCHECKED);

afHooks[index] = FALSE;

}

default:

return (DefWindowProc(hwndMain, uMsg, wParam,

lParam));

}

break;

//

// Process other messages.

//

default:

return DefWindowProc(hwndMain, uMsg, wParam, lParam);

}

return NULL;

}

/****************************************************************

WH_CALLWNDPROC hook procedure

****************************************************************/

LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam)

{

CHAR szCWPBuf[256];

CHAR szMsg[16];

HDC hdc;

static int c = 0;

int cch;

if (nCode < 0) // do not process message

return CallNextHookEx(myhookdata[CALLWNDPROC].hhook, nCode,

wParam, lParam);

// Call an application-defined function that converts a message

// constant to a string and copies it to a buffer.

LookUpTheMessage((PMSG) lParam, szMsg);

hdc = GetDC(hwndMain);

switch (nCode)

{

case HC_ACTION:

cch = wsprintf(szCWPBuf,

"CALLWNDPROC - tsk: %ld, msg: %s, %d times ",

wParam, szMsg, c++);

TextOut(hdc, 2, 15, szCWPBuf, cch);

break;

default:

break;

}

ReleaseDC(hwndMain, hdc);

return CallNextHookEx(myhookdata[CALLWNDPROC].hhook, nCode,

wParam, lParam);

}

/****************************************************************

WH_GETMESSAGE hook procedure

****************************************************************/

LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)

{

CHAR szMSGBuf[256];

CHAR szRem[16];

CHAR szMsg[16];

HDC hdc;

static int c = 0;

int cch;

if (nCode < 0) // do not process message

return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode,

wParam, lParam);

switch (nCode)

{

case HC_ACTION:

switch (wParam)

{

case PM_REMOVE:

lstrcpy(szRem, "PM_REMOVE");

break;

case PM_NOREMOVE:

lstrcpy(szRem, "PM_NOREMOVE");

break;

default:

lstrcpy(szRem, "Unknown");

break;

}

// Call an application-defined function that converts a

// message constant to a string and copies it to a

// buffer.

LookUpTheMessage((PMSG) lParam, szMsg);

hdc = GetDC(hwndMain);

cch = wsprintf(szMSGBuf,

"GETMESSAGE - wParam: %s, msg: %s, %d times ",

szRem, szMsg, c++);

TextOut(hdc, 2, 35, szMSGBuf, cch);

break;

default:

break;

}

ReleaseDC(hwndMain, hdc);

return CallNextHookEx(myhookdata[GETMESSAGE].hhook, nCode,

wParam, lParam);

}

/****************************************************************

WH_DEBUG hook procedure

****************************************************************/

LRESULT CALLBACK DebugProc(int nCode, WPARAM wParam, LPARAM lParam)

{

CHAR szBuf[128];

HDC hdc;

static int c = 0;

int cch;

if (nCode < 0) // do not process message

return CallNextHookEx(myhookdata[DEBUG].hhook, nCode,

wParam, lParam);

hdc = GetDC(hwndMain);

switch (nCode)

{

case HC_ACTION:

cch = wsprintf(szBuf,

"DEBUG - nCode: %d, tsk: %ld, %d times ",

nCode,wParam, c++);

TextOut(hdc, 2, 55, szBuf, cch);

break;

default:

break;

}

ReleaseDC(hwndMain, hdc);

return CallNextHookEx(myhookdata[DEBUG].hhook, nCode, wParam,

lParam);

}

/****************************************************************

WH_CBT hook procedure

****************************************************************/

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

{

CHAR szBuf[128];

CHAR szCode[128];

HDC hdc;

static int c = 0;

int cch;

if (nCode < 0) // do not process message

return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam,

lParam);

hdc = GetDC(hwndMain);

switch (nCode)

{

case HCBT_ACTIVATE:

lstrcpy(szCode, "HCBT_ACTIVATE");

break;

case HCBT_CLICKSKIPPED:

lstrcpy(szCode, "HCBT_CLICKSKIPPED");

break;

case HCBT_CREATEWND:

lstrcpy(szCode, "HCBT_CREATEWND");

break;

case HCBT_DESTROYWND:

lstrcpy(szCode, "HCBT_DESTROYWND");

break;

case HCBT_KEYSKIPPED:

lstrcpy(szCode, "HCBT_KEYSKIPPED");

break;

case HCBT_MINMAX:

lstrcpy(szCode, "HCBT_MINMAX");

break;

case HCBT_MOVESIZE:

lstrcpy(szCode, "HCBT_MOVESIZE");

break;

case HCBT_QS:

lstrcpy(szCode, "HCBT_QS");

break;

case HCBT_SETFOCUS:

lstrcpy(szCode, "HCBT_SETFOCUS");

break;

case HCBT_SYSCOMMAND:

lstrcpy(szCode, "HCBT_SYSCOMMAND");

break;

default:

lstrcpy(szCode, "Unknown");

break;

}

cch = wsprintf(szBuf, "CBT - nCode: %s, tsk: %ld, %d times ",

szCode, wParam, c++);

TextOut(hdc, 2, 75, szBuf, cch);

ReleaseDC(hwndMain, hdc);

return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam,

lParam);

}

/****************************************************************

WH_MOUSE hook procedure

****************************************************************/

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)

{

CHAR szBuf[128];

CHAR szMsg[16];

HDC hdc;

static int c = 0;

int cch;

if (nCode < 0) // do not process the message

return CallNextHookEx(myhookdata[MOUSE].hhook, nCode,

wParam, lParam);

// Call an application-defined function that converts a message

// constant to a string and copies it to a buffer.

LookUpTheMessage((PMSG) lParam, szMsg);

hdc = GetDC(hwndMain);

cch = wsprintf(szBuf,

"MOUSE - nCode: %d, msg: %s, x: %d, y: %d, %d times ",

nCode, szMsg, LOWORD(lParam), HIWORD(lParam), c++);

TextOut(hdc, 2, 95, szBuf, cch);

ReleaseDC(hwndMain, hdc);

return CallNextHookEx(myhookdata[MOUSE].hhook, nCode, wParam,

lParam);

}

/****************************************************************

WH_KEYBOARD hook procedure

****************************************************************/

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)

{

CHAR szBuf[128];

HDC hdc;

static int c = 0;

int cch;

if (nCode < 0) // do not process message

return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode,

wParam, lParam);

hdc = GetDC(hwndMain);

cch = wsprintf(szBuf, "KEYBOARD - nCode: %d, vk: %d, %d times ",

nCode, wParam, c++);

TextOut(hdc, 2, 115, szBuf, cch);

ReleaseDC(hwndMain, hdc);

return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode, wParam,

lParam);

}

/****************************************************************

WH_MSGFILTER hook procedure

****************************************************************/

LRESULT CALLBACK MessageProc(int nCode, WPARAM wParam, LPARAM lParam)

{

CHAR szBuf[128];

CHAR szMsg[16];

CHAR szCode[32];

HDC hdc;

static int c = 0;

int cch;

if (nCode < 0) // do not process message

return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,

wParam, lParam);

switch (nCode)

{

case MSGF_DIALOGBOX:

lstrcpy(szCode, "MSGF_DIALOGBOX");

break;

case MSGF_MENU:

lstrcpy(szCode, "MSGF_MENU");

break;

case MSGF_SCROLLBAR:

lstrcpy(szCode, "MSGF_SCROLLBAR");

break;

case MSGF_NEXTWINDOW:

lstrcpy(szCode, "MSGF_NEXTWINDOW");

break;

default:

wsprintf(szCode, "Unknown: %d", nCode);

break;

}

// Call an application-defined function that converts a message

// constant to a string and copies it to a buffer.

LookUpTheMessage((PMSG) lParam, szMsg);

hdc = GetDC(hwndMain);

cch = wsprintf(szBuf,

"MSGFILTER nCode: %s, msg: %s, %d times ",

szCode, szMsg, c++);

TextOut(hdc, 2, 135, szBuf, cch);

ReleaseDC(hwndMain, hdc);

return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode,

wParam, lParam);

}


Last news from Greatis Software

Nostalgia .Net     Nostalgia .Net     .Net is powerful, but not all-powerful, so sometimes we need to use Win32 API for our .Net applications. It's simple enough with Platform Invoke if you have Win32 skill, but we do not always have time to dig the ancient documentation, declare the special types that are compatible with Win32, find the values of the Win32's constants and so on. Nostalgia .Net offers several simple-to-use classes, and components that will allow you to forget about the headache of Win32 and just use the power of Win32 in your application the same way as you use the native. Net classes.  More »

Recommended software for developers

Ultimate Pack for Delphi and C++ Builder     Ultimate Pack     Component pack for Delphi and C++ Builder that contains runtime form designer, runtime object inspector, print suite and much more for the very special price.  More »

Form Designer .Net     Form Designer .Net     Unique runtime form design solution that allows to edit any form in .Net WinForms application at runtime with full source codes for only 300 euro!  More »

Print Suite .Net     Print Suite .Net     Print Suite .Net is a set of components for easy printing texts, images and grids from your WinForms applications. Full C# source codes are available  More »

Gradient Controls .Net     Gradient Controls .Net     Gradient Controls .Net offers controls with gradient background feature. Labels, panels and so on... Full C# source codes are available  More »

iGrid     Greatis iGrid     iGrid plots drawing grid right over your desktop, so you can use it everywhere, with any drawing application without any special plugins for different graphic editors.  More »


All the contacts and projects

Dmitry Vasiliev (just.dmitry)

Related Links

Software for Visual Studio .NET developers
Software for Delphi and C++ Builder developers
Software for Visual Basic 6 developers
Delphi Tips&Tricks
MegaDetailed.NET

More Online Helps

Win32 Programmer's Reference
Win32 Multimedia Programmer's Reference
OLE Programmer's Reference
Microsoft Windows Pen API Programmer's Reference
Microsoft Windows Sockets 2 Reference
Microsoft Windows Telephony API (TAPI) Programmer's Reference
Unix Manual Pages

Free Tech Secrets ;) Copyright © 2008-2012 Free Tech Secrets ;) greatis just4fun network just4fun