1. 程式人生 > >使用鉤子函式獲取全部的滑鼠訊息和鍵盤訊息

使用鉤子函式獲取全部的滑鼠訊息和鍵盤訊息

// HookTest1Dlg.cpp : 實現檔案
//

#include "stdafx.h"
#include "HookTest1.h"
#include "HookTest1Dlg.h"
#include "afxdialogex.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// 用於應用程式“關於”選單項的 CAboutDlg 對話方塊
CString str,str1;
int num=0;
HWND hwnd;
CDC *cdc;
HHOOK hmouse,hkeyboard;
LRESULT CALLBACK MouseProc(int ncode, WPARAM wParam,LPARAM lParam)
{
	str=_T("滑鼠操作次數: ");
	num++;
	str1.Format(_T("%d"),num);
	str=str+str1;
	int s=str.GetLength();
	cdc->TextOut(50,50,str,s);
	return CallNextHookEx(hmouse, ncode, wParam, lParam);

}
LRESULT CALLBACK KeyProc(int ncode,WPARAM wParam,LPARAM lParam)
{
	 int s=0;
	 if(wParam==VK_F10)
	 {
	              ::SendMessage(hwnd,WM_CLOSE,0,0);
				  ::UnhookWindowsHookEx(hmouse);
				  ::UnhookWindowsHookEx(hkeyboard);
	 }
	 else
	 {
		switch(wParam)
		{
			case VK_F2:
				 str=_T("按鍵F2");
				 s=str.GetLength();
				 cdc->TextOut(50,150,str,s);
				 break;
	
			   case VK_F3:
				  str=_T("按鍵F3");
				 s=str.GetLength();
				 cdc->TextOut(50,150,str,s);
				 break;
	
				 break;
			  case 0x41:
				 str=_T("按鍵A");
				 s=str.GetLength();
				 cdc->TextOut(50,150,str,s);
				 break; 
			  case 0x42:
				 str=_T("按鍵B");
				 s=str.GetLength();
				 cdc->TextOut(50,150,str,s);
				 break;
		}
		return CallNextHookEx(hkeyboard, ncode, wParam, lParam);
	 }
}
class CAboutDlg : public CDialogEx
{
public:
	CAboutDlg();

// 對話方塊資料
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 支援

// 實現
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
END_MESSAGE_MAP()


// CHookTest1Dlg 對話方塊




CHookTest1Dlg::CHookTest1Dlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CHookTest1Dlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CHookTest1Dlg::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CHookTest1Dlg, CDialogEx)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDOK, &CHookTest1Dlg::OnBnClickedOk)
END_MESSAGE_MAP()


// CHookTest1Dlg 訊息處理程式

BOOL CHookTest1Dlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// 將“關於...”選單項新增到系統選單中。

	// IDM_ABOUTBOX 必須在系統命令範圍內。
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		BOOL bNameValid;
		CString strAboutMenu;
		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
		ASSERT(bNameValid);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 設定此對話方塊的圖示。當應用程式主視窗不是對話方塊時,框架將自動
	//  執行此操作
	SetIcon(m_hIcon, TRUE);			// 設定大圖示
	SetIcon(m_hIcon, FALSE);		// 設定小圖示

	// TODO: 在此新增額外的初始化程式碼
	cdc=GetDC();
	hwnd=this->m_hWnd;
    hmouse=SetWindowsHookEx(WH_MOUSE,MouseProc,NULL,GetCurrentThreadId());
	hkeyboard=SetWindowsHookEx(WH_KEYBOARD,KeyProc,NULL,GetCurrentThreadId());
	return TRUE;  // 除非將焦點設定到控制元件,否則返回 TRUE
}

void CHookTest1Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialogEx::OnSysCommand(nID, lParam);
	}
}

// 如果向對話方塊新增最小化按鈕,則需要下面的程式碼
//  來繪製該圖示。對於使用文件/檢視模型的 MFC 應用程式,
//  這將由框架自動完成。

void CHookTest1Dlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // 用於繪製的裝置上下文

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// 使圖示在工作區矩形中居中
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// 繪製圖標
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialogEx::OnPaint();
	}
}

//當用戶拖動最小化視窗時系統呼叫此函式取得游標
//顯示。
HCURSOR CHookTest1Dlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}



void CHookTest1Dlg::OnBnClickedOk()
{
	// TODO: 在此新增控制元件通知處理程式程式碼

CDialogEx::OnOK();

}

以上方法即可獲得當前執行程式內的所有滑鼠和鍵盤的訊息,程式中只顯示了部分按鍵訊息,並未全部處理,然後介紹如何獲取全部執行緒的滑鼠和鍵盤訊息。