MSDN中SetWindowsHookEx的例子代码

目标:
运行SetWindowsHookEx在MSDN(2008)中的例子程序。
ms-help://MS.MSDNQTR.v90.en/winui/winui/windowsuserinterface/windowing/hooks/hookreference/hookfunctions/setwindowshookex.htm
ms-help://MS.MSDNQTR.v90.en/winui/winui/windowsuserinterface/windowing/hooks/usinghooks.htm

操作如下:
(1)使用VS2008默认设置建立一个C++DE“Win32 Project”的窗口程序,名为“hookTest4”。
(2)需要把相应的按钮事件关联到界面的菜单中,如hookTest4.rc中所述。
(3)需要在“Source Files”中添加新文件“hookExample.cpp”。其中,SetWindowsHookEx的示例代码为顺利运行有一些改动。
(4)运行程序,触发菜单“HOOK”下的选项,可以在窗口中看到调试输出。

// hookExample.cpp
#include "stdafx.h"
#include <strsafe.h>// for using StringCchCopy,StringCchLength functions etc.
#include "Resource.h"

#define CALLWNDPROC					IDM_CALLWNDPROC 
#define CBT   						IDM_CBT   
#define DEBUG						IDM_DEBUG  
#define GETMESSAGE 					IDM_GETMESSAGE 
#define KEYBOARD 					IDM_KEYBOARD 
#define MOUSE  						IDM_MOUSE  
#define MSGFILTER 					IDM_MSGFILTER 


LRESULT WINAPI MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam, LPARAM lParam);
LRESULT WINAPI CallWndProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DebugProc(int nCode, WPARAM wParam, LPARAM lParam) ;
LRESULT CALLBACK CBTProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK MessageProc(int nCode, WPARAM wParam, LPARAM lParam);

INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

HWND hwndMain;
extern HINSTANCE hInst;	

//void LookUpTheMessage(PMSG pmsg, TCHAR* szMsg);
//application-defined function, I have written a simple one,you can
//write yours instead
void LookUpTheMessage(PMSG pmsg, TCHAR* szMsg)
{
	DWORD message = pmsg->message;
	StringCchPrintf(szMsg, sizeof(DWORD), L"%x", message);
}

//==============================================================================================================================================
// 下面是MSDN上SetWindowsHookEx的Example原文,为顺利运行有一些改动。
//==============================================================================================================================================
#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)) 
		{ 
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hwndMain, About);
			break;

		case IDM_EXIT:
			DestroyWindow(hwndMain);
			break;

			// 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) 
{ 
	TCHAR szCWPBuf[256]; 
	TCHAR szMsg[16]; 
	HDC hdc; 
	static int c = 0; 
	size_t cch;
	size_t * pcch = &cch;
	HRESULT hResult; 

	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:
		hResult = StringCchPrintf(szCWPBuf, 256/sizeof(TCHAR),  
			L"CALLWNDPROC - tsk: %ld, msg: %s, %d times   ", 
			wParam, szMsg, c++);
		if (FAILED(hResult))
		{
			// TODO: writer error handler
		}
		hResult = StringCchLength(szCWPBuf, 256/sizeof(TCHAR), pcch);
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		TextOut(hdc, 2, 15, szCWPBuf, *pcch); 
		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) 
{ 
	TCHAR szMSGBuf[256]; 
	TCHAR szRem[16]; 
	TCHAR szMsg[16]; 
	HDC hdc; 
	static int c = 0; 
	size_t cch;
	size_t * pcch = &cch;
	HRESULT hResult;

	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:
			hResult = StringCchCopy(szRem, 16/sizeof(TCHAR), L"PM_REMOVE");
			if (FAILED(hResult))
			{
				// TODO: write error handler
			} 
			break; 

		case PM_NOREMOVE:
			hResult = StringCchCopy(szRem, 16/sizeof(TCHAR), L"PM_NOREMOVE");
			if (FAILED(hResult))
			{
				// TODO: write error handler
			} 
			break; 

		default:
			hResult = StringCchCopy(szRem, 16/sizeof(TCHAR), L"Unknown");
			if (FAILED(hResult))
			{
				// TODO: write error handler
			} 
			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);
		hResult = StringCchPrintf(szMSGBuf, 256/sizeof(TCHAR), 
			L"GETMESSAGE - wParam: %s, msg: %s, %d times   ", 
			szRem, szMsg, c++);
		if (FAILED(hResult))
		{
			// TODO: write error handler
		}
		hResult = StringCchLength(szMSGBuf, 256/sizeof(TCHAR), pcch);
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		TextOut(hdc, 2, 35, szMSGBuf, *pcch); 
		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) 
{ 
	TCHAR szBuf[128]; 
	HDC hdc; 
	static int c = 0; 
	size_t cch;
	size_t * pcch = &cch;
	HRESULT hResult;

	if (nCode < 0)  // do not process message 
		return CallNextHookEx(myhookdata[DEBUG].hhook, nCode, 
		wParam, lParam); 

	hdc = GetDC(hwndMain); 

	switch (nCode) 
	{ 
	case HC_ACTION:
		hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR),   
			L"DEBUG - nCode: %d, tsk: %ld, %d times   ", 
			nCode,wParam, c++);
		if (FAILED(hResult))
		{
			// TODO: write error handler
		}
		hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), pcch);
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		TextOut(hdc, 2, 55, szBuf, *pcch); 
		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) 
{ 
	TCHAR szBuf[128]; 
	TCHAR szCode[128]; 
	HDC hdc; 
	static int c = 0; 
	size_t cch;
	size_t * pcch = &cch;
	HRESULT hResult;

	if (nCode < 0)  // do not process message 
		return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam, 
		lParam); 

	hdc = GetDC(hwndMain); 

	switch (nCode) 
	{ 
	case HCBT_ACTIVATE:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_ACTIVATE");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_CLICKSKIPPED:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_CLICKSKIPPED");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_CREATEWND:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_CREATEWND");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_DESTROYWND:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_DESTROYWND");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_KEYSKIPPED:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_KEYSKIPPED");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_MINMAX:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_MINMAX");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_MOVESIZE:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_MOVESIZE");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_QS:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_QS");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_SETFOCUS:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_SETFOCUS");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case HCBT_SYSCOMMAND:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"HCBT_SYSCOMMAND");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	default:
		hResult = StringCchCopy(szCode, 128/sizeof(TCHAR), L"Unknown");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 
	} 
	hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR), L"CBT -  nCode: %s, tsk: %ld, %d times   ",
		szCode, wParam, c++);
	if (FAILED(hResult))
	{
		// TODO: write error handler
	}
	hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), pcch);
	if (FAILED(hResult))
	{
		// TODO: write error handler
	} 
	TextOut(hdc, 2, 75, szBuf, *pcch); 
	ReleaseDC(hwndMain, hdc); 
	return CallNextHookEx(myhookdata[CBT].hhook, nCode, wParam, 
		lParam); 
} 

/**************************************************************** 
WH_MOUSE hook procedure 
****************************************************************/ 

LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
	TCHAR szBuf[128]; 
	TCHAR szMsg[16]; 
	HDC hdc; 
	static int c = 0; 
	size_t cch;
	size_t * pcch = &cch;
	HRESULT hResult;

	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);
	hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR), 
		L"MOUSE - nCode: %d, msg: %s, x: %d, y: %d, %d times   ", 
		nCode, szMsg, LOWORD(lParam), HIWORD(lParam), c++); 
	if (FAILED(hResult))
	{
		// TODO: write error handler
	}
	hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), pcch);
	if (FAILED(hResult))
	{
		// TODO: write error handler
	}
	TextOut(hdc, 2, 95, szBuf, *pcch); 
	ReleaseDC(hwndMain, hdc); 
	return CallNextHookEx(myhookdata[MOUSE].hhook, nCode, wParam, 
		lParam); 
} 

/**************************************************************** 
WH_KEYBOARD hook procedure 
****************************************************************/ 

LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
	TCHAR szBuf[128]; 
	HDC hdc; 
	static int c = 0; 
	size_t cch;
	size_t * pcch = &cch;
	HRESULT hResult;

	if (nCode < 0)  // do not process message 
		return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode, 
		wParam, lParam); 

	hdc = GetDC(hwndMain);
	hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR), L"KEYBOARD - nCode: %d, vk: %d, %d times ", nCode, wParam, c++);
	if (FAILED(hResult))
	{
		// TODO: write error handler
	} 
	hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), pcch);
	if (FAILED(hResult))
	{
		// TODO: write error handler
	} 
	TextOut(hdc, 2, 115, szBuf, *pcch); 
	ReleaseDC(hwndMain, hdc); 
	return CallNextHookEx(myhookdata[KEYBOARD].hhook, nCode, wParam, 
		lParam); 
} 

/**************************************************************** 
WH_MSGFILTER hook procedure 
****************************************************************/ 

LRESULT CALLBACK MessageProc(int nCode, WPARAM wParam, LPARAM lParam) 
{ 
	TCHAR szBuf[128]; 
	TCHAR szMsg[16]; 
	TCHAR szCode[32]; 
	HDC hdc; 
	static int c = 0; 
	size_t cch;
	size_t * pcch = &cch;
	HRESULT hResult;

	if (nCode < 0)  // do not process message 
		return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode, 
		wParam, lParam); 

	switch (nCode) 
	{ 
	case MSGF_DIALOGBOX:
		hResult = StringCchCopy(szCode, 32/sizeof(TCHAR), L"MSGF_DIALOGBOX");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case MSGF_MENU:
		hResult = StringCchCopy(szCode, 32/sizeof(TCHAR), L"MSGF_MENU");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	case MSGF_SCROLLBAR:
		hResult = StringCchCopy(szCode, 32/sizeof(TCHAR), L"MSGF_SCROLLBAR");
		if (FAILED(hResult))
		{
			// TODO: write error handler
		} 
		break; 

	default:
		hResult = StringCchPrintf(szCode, 128/sizeof(TCHAR), L"Unknown: %d", nCode);
		if (FAILED(hResult))
		{
			// TODO: write error handler
		}
		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);
	hResult = StringCchPrintf(szBuf, 128/sizeof(TCHAR),  
		L"MSGFILTER  nCode: %s, msg: %s, %d times    ", 
		szCode, szMsg, c++);
	if (FAILED(hResult))
	{
		// TODO: write error handler
	} 
	hResult = StringCchLength(szBuf, 128/sizeof(TCHAR), pcch);
	if (FAILED(hResult))
	{
		// TODO: write error handler
	} 
	TextOut(hdc, 2, 135, szBuf, *pcch); 
	ReleaseDC(hwndMain, hdc); 
	return CallNextHookEx(myhookdata[MSGFILTER].hhook, nCode, 
		wParam, lParam); 
} 
// hookTest4.cpp : Defines the entry point for the application.
//

#include "stdafx.h"
#include "hookTest4.h"

extern HWND hwndMain;

LRESULT WINAPI MainWndProc(HWND hwndMain, UINT uMsg, WPARAM wParam, LPARAM lParam);

#define MAX_LOADSTRING 100

// Global Variables:
HINSTANCE hInst;								// current instance
TCHAR szTitle[MAX_LOADSTRING];					// The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];			// the main window class name

// Forward declarations of functions included in this code module:
ATOM				MyRegisterClass(HINSTANCE hInstance);
BOOL				InitInstance(HINSTANCE, int);
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
INT_PTR CALLBACK	About(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPTSTR    lpCmdLine,
                     int       nCmdShow)
{
	UNREFERENCED_PARAMETER(hPrevInstance);
	UNREFERENCED_PARAMETER(lpCmdLine);

 	// TODO: Place code here.
	MSG msg;
	HACCEL hAccelTable;

	// Initialize global strings
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
	LoadString(hInstance, IDC_HOOKTEST4, szWindowClass, MAX_LOADSTRING);
	MyRegisterClass(hInstance);

	// Perform application initialization:
	if (!InitInstance (hInstance, nCmdShow))
	{
		return FALSE;
	}

	hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_HOOKTEST4));

	// Main message loop:
	while (GetMessage(&msg, NULL, 0, 0))
	{
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	return (int) msg.wParam;
}



//
//  FUNCTION: MyRegisterClass()
//
//  PURPOSE: Registers the window class.
//
//  COMMENTS:
//
//    This function and its usage are only necessary if you want this code
//    to be compatible with Win32 systems prior to the 'RegisterClassEx'
//    function that was added to Windows 95. It is important to call this function
//    so that the application will get 'well formed' small icons associated
//    with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style			= CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc	= MainWndProc; //WndProc;
	wcex.cbClsExtra		= 0;
	wcex.cbWndExtra		= 0;
	wcex.hInstance		= hInstance;
	wcex.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_HOOKTEST4));
	wcex.hCursor		= LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
	wcex.lpszMenuName	= MAKEINTRESOURCE(IDC_HOOKTEST4);
	wcex.lpszClassName	= szWindowClass;
	wcex.hIconSm		= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
//   FUNCTION: InitInstance(HINSTANCE, int)
//
//   PURPOSE: Saves instance handle and creates main window
//
//   COMMENTS:
//
//        In this function, we save the instance handle in a global variable and
//        create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
   //HWND hWnd;

   hInst = hInstance; // Store instance handle in our global variable

   hwndMain = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
      CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

   if (!hwndMain)
   {
      return FALSE;
   }

   ShowWindow(hwndMain, nCmdShow);
   UpdateWindow(hwndMain);

   return TRUE;
}


  FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)

  PURPOSE:  Processes messages for the main window.

  WM_COMMAND	- process the application menu
  WM_PAINT	- Paint the main window
  WM_DESTROY	- post a quit message and return


//LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
//{
//	int wmId, wmEvent;
//	PAINTSTRUCT ps;
//	HDC hdc;
//
//	switch (message)
//	{
//	case WM_COMMAND:
//		wmId    = LOWORD(wParam);
//		wmEvent = HIWORD(wParam);
//		// Parse the menu selections:
//		switch (wmId)
//		{
//		case IDM_ABOUT:
//			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
//			break;
//		case IDM_EXIT:
//			DestroyWindow(hWnd);
//			break;
//		default:
//			return DefWindowProc(hWnd, message, wParam, lParam);
//		}
//		break;
//	case WM_PAINT:
//		hdc = BeginPaint(hWnd, &ps);
//		// TODO: Add any drawing code here...
//		EndPaint(hWnd, &ps);
//		break;
//	case WM_DESTROY:
//		PostQuitMessage(0);
//		break;
//	default:
//		return DefWindowProc(hWnd, message, wParam, lParam);
//	}
//	return 0;
//}

// Message handler for about box.
INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
	UNREFERENCED_PARAMETER(lParam);
	switch (message)
	{
	case WM_INITDIALOG:
		return (INT_PTR)TRUE;

	case WM_COMMAND:
		if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)
		{
			EndDialog(hDlg, LOWORD(wParam));
			return (INT_PTR)TRUE;
		}
		break;
	}
	return (INT_PTR)FALSE;
}
// Resource.h
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by hookTest4.rc
//

#define IDS_APP_TITLE			103

#define IDR_MAINFRAME			128
#define IDD_HOOKTEST4_DIALOG	102
#define IDD_ABOUTBOX			103
#define IDM_ABOUT				104
#define IDM_EXIT				105
#define IDI_HOOKTEST4			107
#define IDI_SMALL				108
#define IDC_HOOKTEST4			109
#define IDC_MYICON				2
#ifndef IDC_STATIC
#define IDC_STATIC				-1
#endif
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS

#define _APS_NO_MFC					130
#define _APS_NEXT_RESOURCE_VALUE	129
#define _APS_NEXT_COMMAND_VALUE		32771
#define _APS_NEXT_CONTROL_VALUE		1000
#define _APS_NEXT_SYMED_VALUE		110
#endif
#endif

// HOOK, 下面是添加的代码
#define IDM_CALLWNDPROC 0
#define IDM_CBT   1
#define IDM_DEBUG  2
#define IDM_GETMESSAGE 3
#define IDM_KEYBOARD 4
#define IDM_MOUSE  5
#define IDM_MSGFILTER 6
// hookTest4.rc
//Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/
//
// Generated from the TEXTINCLUDE 2 resource.
//
#ifndef APSTUDIO_INVOKED
#include "targetver.h"
#endif
#define APSTUDIO_HIDDEN_SYMBOLS
#include "windows.h"
#undef APSTUDIO_HIDDEN_SYMBOLS
/
#undef APSTUDIO_READONLY_SYMBOLS

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE 9, 1
#pragma code_page(936)

/
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.

IDI_HOOKTEST4       ICON         "hookTest4.ico"
IDI_SMALL               ICON         "small.ico"

/
//
// Menu
//

IDC_HOOKTEST4 MENU
BEGIN
    POPUP "&File"
    BEGIN
        MENUITEM "E&xit",                IDM_EXIT
    END
    POPUP "&Help"
    BEGIN
        MENUITEM "&About ...",           IDM_ABOUT
    END
	POPUP "&HOOK"
	BEGIN
		MENUITEM "&IDM_CALLWNDPROC",		IDM_CALLWNDPROC 
		MENUITEM "&IDM_CBT",				IDM_CBT   
		MENUITEM "&IDM_DEBUG",				IDM_DEBUG  
		MENUITEM "&IDM_GETMESSAGE",			IDM_GETMESSAGE 
		MENUITEM "&IDM_KEYBOARD",			IDM_KEYBOARD 
		MENUITEM "&IDM_MOUSE",				IDM_MOUSE  
		MENUITEM "&IDM_MSGFILTER",			IDM_MSGFILTER 
    END
END


/
//
// Accelerator
//

IDC_HOOKTEST4 ACCELERATORS
BEGIN"?",            IDM_ABOUT,              ASCII,  ALT
    "/",            IDM_ABOUT,              ASCII,  ALT
END


/
//
// Dialog
//

IDD_ABOUTBOX DIALOGEX 0, 0, 170, 62
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "About hookTest4"
FONT 8, "MS Shell Dlg"
BEGIN
    ICON            IDR_MAINFRAME,IDC_STATIC,14,14,21,20
    LTEXT           "hookTest4, Version 1.0",IDC_STATIC,42,14,114,8,SS_NOPREFIX
    LTEXT           "Copyright (C) 2012",IDC_STATIC,42,26,114,8
    DEFPUSHBUTTON   "OK",IDOK,113,41,50,14,WS_GROUP
END

/
//
// DESIGNINFO
//

#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO
BEGIN
    IDD_ABOUTBOX, DIALOG
    BEGIN
        LEFTMARGIN, 7
        RIGHTMARGIN, 163
        TOPMARGIN, 7
        BOTTOMMARGIN, 55
    END
END
#endif    // APSTUDIO_INVOKED

#ifdef APSTUDIO_INVOKED
/
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE
BEGIN
	"#ifndef APSTUDIO_INVOKED\r\n"
    "#include ""targetver.h""\r\n"
    "#endif\r\n"
    "#define APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "#include ""windows.h""\r\n"
    "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n"
    "\0"
END

3 TEXTINCLUDE
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED

/
//
// String Table
//

STRINGTABLE
BEGIN
   IDC_HOOKTEST4   "HOOKTEST4"
   IDS_APP_TITLE       "hookTest4"
END

#endif
/



#ifndef APSTUDIO_INVOKED
/
//
// Generated from the TEXTINCLUDE 3 resource.
//

/
#endif    // not APSTUDIO_INVOKED

相关推荐
三:程序的设计: I:设置钩子 设置钩子是通过SetWindowsHookEx ()的API函数. 原形: HHOOK SetWindowsHookEx(int idHook,HOOKPROC lpfn,HINSTANCE hMod,DWORD dwThreadId) idhook:装入钩子的类型. lpfn: 钩子进程的入口地址 hMod: 应用程序的事件句柄 dwThreadId: 装入钩子的线程标示 参数: idHook: 这个参数可以是以下值: WH_CALLWNDPROC、WH_CALLWNDPROCRET、WH_CBT、WH_DEBUG、WH_FOREGROUNDIDLE、WH_GETMESSAGE、WH_JOURNALPLAYBACK、WH_JOURNALRECORD、WH_KEYBOARD、 WH_KEYBOARD_LL、WH_MOUSE、WH_MOUSE_LL、WH_MSGFILTER、WH_SHELL、WH_SYSMSGFILTER。 对于这些参数,我不想一一加以解释,因为MSDN有关于他们的详细注解。我只挑选其的几个加以文说明。 WH_KEYBOARD:一旦有键盘敲打消息(键盘的按下、键盘的弹起),在这个消息被放在应用程序的消息队列前,WINDOWS将会调用你的钩子函数。钩子函数可以 改变和丢弃键盘敲打消息。 WH_MOUSE:每个鼠标消息在被放在应用程序的消息队列前,WINDOWS将会调用你的钩子函数。钩子函数可以改变和丢弃鼠标消息。 WH_GETMESSAGE:每次当你的应用程序调用一个GetMessage()或者一个PeekMessage()为了去从应用程序的消息队列要求一个消息时,WINDOWS都会调用你的钩子函数。 而钩子函数可以改变和丢弃这个消息。 II:释放钩子 钩子的释放使用的是UnhookWindowsHookEx()函数 原形:BOOL UnhookWindowsHookEx( HHOOK hhk ) UnhookWindowsHookEx()函数将释放的是钩子链函数SetWindowsHookEx所装入的钩子进程。 hhk: 将要释放的钩子进程的句柄。 III:钩子进程 钩子进程使用函数HookProc;其实HookProc仅仅只是应用程序定义的符号。比如你可以写成KeyBoardHook.但是参数是不变的。Win32 API提供了诸如:CallWndProc、 GetMsgProc、DebugProc、CBTProc、MouseProc、KeyboardProc、MessageProc等函数,对于他们的详细讲解,可以看MSDN我在此只讲解一下KeyBoardHook的含义。 原形:LRESULT CALLBACK KeyBoardHook (int nCode, WPARAM wParam, LPARAM lParam) 说明:钩子进程是一些依附在一个钩子上的一些函数,因此钩子进程只被WINDOWS调用而不被应用程序调用,他们有时就需要作为一个回调函数(CALLBACK)。 参数说明: nCode:钩子代码,钩子进程使用钩子代码去决定是否执行。而钩子代码的值是依靠钩子的种类来定的。每种钩子种类都有他们自己一系列特性的代码。比如对于WH_KEYBOARD, 钩子代码的参数有:HC_ACTION,HC_NOREMOVE。HC_ACTION的意义:参数wParam 和lParam 包含了键盘敲打消息的信息,HC_NOREMOVE的意义:参数wParam 和lParam包含了 键盘敲打消息的信息,并且,键盘敲打消息一直没有从消息队列删除。(应用程序调用PeekMessage函数,并且设置PM_NOREMOVE标志)。也就是说当nCode等于HC_ACTION时, 钩子进程必须处理消息。而为HC_NOREMOVE时,钩子进程必须传递消息给CallNextHookEx函数,而不能做进一步的处理,而且必须有CallNextHookEx函数的返回值。 wParam:键盘敲打所产生的键盘消息,键盘按键的虚拟代码。 lParam:包含了消息细节。 注意:如果钩子进程nCode小于零,钩子进程必须返回(return) CallNextHookEx(nCode,wParam,lParam);而钩子进程的nCode大于零,但是钩子进程并不处理消息, 作者推荐你调用CallNextHookEx并且返回该函数的返回值。否则,如果另一个应用程序也装入WH_KEYBOARD 钩子,那么该钩子将不接受钩子通知并且返回一个不正确的值。 如果钩子进程处理了消息,它可能返回一个非零值去阻止系统传递该信息到其它剩下的钩子或者windows进程。所以最好在钩子进程的最后都返回CallNextHookEx的返回值。 IV:调用下一个钩子函数 调用下一个钩子函数时使用CallNexHookEx函数。 原形:LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam ) CallNexHookEx()函数用于对当前钩子链的下一个钩子进程传递钩子信息,一个钩子进程既可以在钩子信息处理前,也可以在钩子信息处理后调用该函数。 为什么使用该函数已在iii钩子进程的“注意”,加以了详细的说明。 hhk: 当前钩子的句柄 nCode: 传送到钩子进程的钩子代码。 wParam:传送到钩子进程的值。 lParam:传送到钩子进程的值。 参数: hhk: 当前钩子的句柄. 应用程序接受这个句柄,作为先前调用SetWindowsHookE函数的结果 nCode: 传送到钩子进程的钩子代码,下一个钩子进程使用这个代码以此决定如何处理钩子信息 wParam:传送给钩子进程的wParam 参数值 ,参数值的具体含义与当前钩子链的挂接的钩子类型有关 lParam : 传送给钩子进程的wParam 参数值 ,参数值的具体含义与当前钩子链的挂接的钩子类型有关 返回值:返回值是链下一个钩子进程返回的值,当前钩子进程必须返回这个值,返回值的具体含义与挂接的钩子类型有关,详细信息请参看具体的钩子进程描述。 V 建立一个动态连接库(DLL) 当我们熟悉了以上的各个函数后,现在我们开始编写一个动态连接库(DLL)。在这儿我采用的是WIN32 DLL,而不是MFC DLL。而且以下所有的程序也都是采用C语言去编写。 这主要是因为使用WIN32 API能够更详细、更全面的控制程序的如何执行,而使用MFC,一些低级的控制是不可能实现的(当然,仅对该程序来说,也是可以使用MFC的)。 1:建立一个动态连接库的.cpp文件。比如我们现在建立一个名为hookdll.cpp的文件。在hookdll.cpp的文件加上如下内容:附加
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页