计算机接口技术--实验三

数学与计算机学院

《计算机接口技术 》

专 业:班 级:学 号:姓 名:指导老师:实验报告

网络工程 1201 1205110108 王振京 郭峰林

实验3 基于DLL 与HOOK 技术的键盘消息拦截与读音

一 实验目的

1.了解MFC DLL动态连接库的编程方法; 2.了解HOOK 技术和回调函数的运行机制; 3.学习MFC 中加载动态连接库的方法。 二 实验指导

1.HOOK 的基本概念

在Windows 下,当硬件或软件产生中断时,系统会发送一个消息给用户程序。因此,用户程序一般不使用中断,而是采用拦截系统消息的方法。为了拦截不属于本应用程序的消息,拦截程序必须得到系统的认可,由系统安装成全局运行。

HOOK 即通常所说的钩子。实际上,HOOK 就是上面所说的消息拦截程序段。通过系统调用,把它挂入系统。每当HOOK 所希望的消息发出,在没有到达目的窗口前,HOOK 程序就先捕获该消息,得到控制权。HOOK 程序先处理该消息,再向系统传递该消息。也可以丢弃该消息。系统维护着一个HOOK 链,最近安装的HOOK 总放在链的开始,从而得到优先执行。

2.HOOK 函数的形式及其安装方法

HOOK 函数在程序中应为全局函数,即:HOOK 函数不应写在一个类中。

HOOK 函数是一个消息响应函数,由系统调用,应以回调函数的形式出现,其格式为: LRESULT _declspec(dllexport)_stdcall CALLBACK KeyboardProc( int nCode, // 若为HC_ACTION,说明后两参数含有击键的消息 WPARAM wParam, //虚键码

LPARAM lParam //击键的有关信息,如重复次数等 )

写好HOOK 函数后,应进行安装,才能得到系统的回调。安装HOOK 的函数为: HHOOK SetWindowsHookEx(

int idHook, //钩子的类型,按键为 WH_KEYBOARD HOOKPROC lpfn, //钩子函数的地址 HINSTANCE hMod, //包含钩子函数的模块句柄

DWORD dwThreadId //指定监视的线程。若为NULL ,则为全局钩子 );

3.程序要求

(1)编写含有按键HOOK 的DLL ,要求当按键时,能读出按键名称 (2)编写安装DLL 的应用程序。 三 实验步骤

1.建立DLL

(1)启动VC++,选 File\New

(2)进入MFC AppWizard _ step 1 of 1 (3)在KeyHook.cpp 文件中添加代码:

#include "stdafx.h" #include "KeyHook.h" #include "mmsystem.h" #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

#pragma data_seg(".SHARDAT")

static HHOOK hkb=NULL; //定义HOOK 句柄

#pragma data_seg()

HINSTANCE hInst; //定义本实例的句柄

BOOL __declspec(dllexport)__stdcall installhook() {

hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hInst,0); return TRUE; }

BOOL __declspec(dllexport) UnHook() { BOOL

unhooked

=

UnhookWindowsHookEx(hkb); return unhooked; } LRESULT

__declspec(dllexport)__stdcall CALLBACK KeyboardProc(int

nCode,

WPARAM wParam, LPARAM lParam) {

if(((DWORD)lParam&0x40000000) &&

(HC_ACTION==nCode)) { if(wParam>='A' && wParam

KeyName[20],temp[10];

strcpy(KeyName,"sound\\");

在keypress.cpp 添加如下文件:

#include "stdafx.h" #include "KeyPress.h" #include "KeyPressDlg.h" #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

class CAboutDlg : public CDialog { public: CAboutDlg();

enum { IDD = IDD_ABOUTBOX }; protected: virtual

void

DoDataExchange(CDataExchange* pDX);

temp[0]=wParam; temp[1]=0; strcat(KeyName,temp); strcat(KeyName,".wav");

sndPlaySound(KeyName,SND_ASYNC);

}

}

LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam ); return(RetVal);}

BEGIN_MESSAGE_MAP(CKeyHookApp, CWinApp)

END_MESSAGE_MAP()

CKeyHookApp::CKeyHookApp(){} CKeyHookApp theApp;

CKeyHookApp::InitInstance() {

AFX_MANAGE_STATE(AfxGetStaticModuleState());

hInst=AfxGetInstanceHandle();

return CWinApp::InitInstance(); }

int CKeyHookApp::ExitInstance() {

UnHook();

return CWinApp::ExitInstance(); }

protected:

DECLARE_MESSAGE_MAP() };

CAboutDlg::CAboutDlg() :

CDialog(CAboutDlg::IDD){} void

CAboutDlg::DoDataExchange(CDataExchange* pDX) {

CDialog::DoDataExchange(pDX); }

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP()

CKeyPressDlg::CKeyPressDlg(CWnd* pParent /*=NULL*/) :

CDialog(CKeyPressDlg::IDD,

pParent) {

m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void

CKeyPressDlg::DoDataExchange(CDataExchange* pDX) {

CDialog::DoDataExchange(pDX); }

BEGIN_MESSAGE_MAP(CKeyPressDlg, CDialog)

ON_WM_SYSCOMMAND() ON_WM_PAINT()

ON_WM_QUERYDRAGICON() END_MESSAGE_MAP()

BOOL CKeyPressDlg::OnInitDialog() {

CDialog::OnInitDialog();

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX

pSysMenu

=

GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBO

X); if (!strAboutMenu.IsEmpty()) {

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); }

}

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set

small icon

static HINSTANCE hinstDLL; BOOL (CALLBACK *inshook)();

if(hinstDLL=LoadLibrary((LPCTSTR)"keyhook.dll")) {

inshook=GetProcAddress(hinstDLL, "installhook"); inshook(); }

return TRUE; // return TRUE unless you set the focus to a control }

void CKeyPressDlg::OnSysCommand(UINT nID, LPARAM lParam) {

if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal();

} else { CDialog::OnSysCommand(nID,

lParam);

} }

void CKeyPressDlg::OnPaint() {

if (IsIconic()) { CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (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

{ } } HCURSOR

CKeyPressDlg::OnQueryDragIcon() {

return (HCURSOR) m_hIcon; }

CDialog::OnPaint();

四,实验结果:

五,实验总结:

本次实验室关于MFC.DLL 动态链接库的编程方法, 需要了解键盘钩子和相应回调函数的运行机制, 了解DLL 的可重要特性等. 受益颇深.

数学与计算机学院

《计算机接口技术 》

专 业:班 级:学 号:姓 名:指导老师:实验报告

网络工程 1201 1205110108 王振京 郭峰林

实验3 基于DLL 与HOOK 技术的键盘消息拦截与读音

一 实验目的

1.了解MFC DLL动态连接库的编程方法; 2.了解HOOK 技术和回调函数的运行机制; 3.学习MFC 中加载动态连接库的方法。 二 实验指导

1.HOOK 的基本概念

在Windows 下,当硬件或软件产生中断时,系统会发送一个消息给用户程序。因此,用户程序一般不使用中断,而是采用拦截系统消息的方法。为了拦截不属于本应用程序的消息,拦截程序必须得到系统的认可,由系统安装成全局运行。

HOOK 即通常所说的钩子。实际上,HOOK 就是上面所说的消息拦截程序段。通过系统调用,把它挂入系统。每当HOOK 所希望的消息发出,在没有到达目的窗口前,HOOK 程序就先捕获该消息,得到控制权。HOOK 程序先处理该消息,再向系统传递该消息。也可以丢弃该消息。系统维护着一个HOOK 链,最近安装的HOOK 总放在链的开始,从而得到优先执行。

2.HOOK 函数的形式及其安装方法

HOOK 函数在程序中应为全局函数,即:HOOK 函数不应写在一个类中。

HOOK 函数是一个消息响应函数,由系统调用,应以回调函数的形式出现,其格式为: LRESULT _declspec(dllexport)_stdcall CALLBACK KeyboardProc( int nCode, // 若为HC_ACTION,说明后两参数含有击键的消息 WPARAM wParam, //虚键码

LPARAM lParam //击键的有关信息,如重复次数等 )

写好HOOK 函数后,应进行安装,才能得到系统的回调。安装HOOK 的函数为: HHOOK SetWindowsHookEx(

int idHook, //钩子的类型,按键为 WH_KEYBOARD HOOKPROC lpfn, //钩子函数的地址 HINSTANCE hMod, //包含钩子函数的模块句柄

DWORD dwThreadId //指定监视的线程。若为NULL ,则为全局钩子 );

3.程序要求

(1)编写含有按键HOOK 的DLL ,要求当按键时,能读出按键名称 (2)编写安装DLL 的应用程序。 三 实验步骤

1.建立DLL

(1)启动VC++,选 File\New

(2)进入MFC AppWizard _ step 1 of 1 (3)在KeyHook.cpp 文件中添加代码:

#include "stdafx.h" #include "KeyHook.h" #include "mmsystem.h" #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

#pragma data_seg(".SHARDAT")

static HHOOK hkb=NULL; //定义HOOK 句柄

#pragma data_seg()

HINSTANCE hInst; //定义本实例的句柄

BOOL __declspec(dllexport)__stdcall installhook() {

hkb=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hInst,0); return TRUE; }

BOOL __declspec(dllexport) UnHook() { BOOL

unhooked

=

UnhookWindowsHookEx(hkb); return unhooked; } LRESULT

__declspec(dllexport)__stdcall CALLBACK KeyboardProc(int

nCode,

WPARAM wParam, LPARAM lParam) {

if(((DWORD)lParam&0x40000000) &&

(HC_ACTION==nCode)) { if(wParam>='A' && wParam

KeyName[20],temp[10];

strcpy(KeyName,"sound\\");

在keypress.cpp 添加如下文件:

#include "stdafx.h" #include "KeyPress.h" #include "KeyPressDlg.h" #ifdef _DEBUG

#define new DEBUG_NEW #undef THIS_FILE

static char THIS_FILE[] = __FILE__; #endif

class CAboutDlg : public CDialog { public: CAboutDlg();

enum { IDD = IDD_ABOUTBOX }; protected: virtual

void

DoDataExchange(CDataExchange* pDX);

temp[0]=wParam; temp[1]=0; strcat(KeyName,temp); strcat(KeyName,".wav");

sndPlaySound(KeyName,SND_ASYNC);

}

}

LRESULT RetVal = CallNextHookEx( hkb, nCode, wParam, lParam ); return(RetVal);}

BEGIN_MESSAGE_MAP(CKeyHookApp, CWinApp)

END_MESSAGE_MAP()

CKeyHookApp::CKeyHookApp(){} CKeyHookApp theApp;

CKeyHookApp::InitInstance() {

AFX_MANAGE_STATE(AfxGetStaticModuleState());

hInst=AfxGetInstanceHandle();

return CWinApp::InitInstance(); }

int CKeyHookApp::ExitInstance() {

UnHook();

return CWinApp::ExitInstance(); }

protected:

DECLARE_MESSAGE_MAP() };

CAboutDlg::CAboutDlg() :

CDialog(CAboutDlg::IDD){} void

CAboutDlg::DoDataExchange(CDataExchange* pDX) {

CDialog::DoDataExchange(pDX); }

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) END_MESSAGE_MAP()

CKeyPressDlg::CKeyPressDlg(CWnd* pParent /*=NULL*/) :

CDialog(CKeyPressDlg::IDD,

pParent) {

m_hIcon=AfxGetApp()->LoadIcon(IDR_MAINFRAME); } void

CKeyPressDlg::DoDataExchange(CDataExchange* pDX) {

CDialog::DoDataExchange(pDX); }

BEGIN_MESSAGE_MAP(CKeyPressDlg, CDialog)

ON_WM_SYSCOMMAND() ON_WM_PAINT()

ON_WM_QUERYDRAGICON() END_MESSAGE_MAP()

BOOL CKeyPressDlg::OnInitDialog() {

CDialog::OnInitDialog();

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);

ASSERT(IDM_ABOUTBOX

pSysMenu

=

GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu;

strAboutMenu.LoadString(IDS_ABOUTBO

X); if (!strAboutMenu.IsEmpty()) {

pSysMenu->AppendMenu(MF_SEPARATOR);

pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); }

}

SetIcon(m_hIcon, TRUE); // Set big icon

SetIcon(m_hIcon, FALSE); // Set

small icon

static HINSTANCE hinstDLL; BOOL (CALLBACK *inshook)();

if(hinstDLL=LoadLibrary((LPCTSTR)"keyhook.dll")) {

inshook=GetProcAddress(hinstDLL, "installhook"); inshook(); }

return TRUE; // return TRUE unless you set the focus to a control }

void CKeyPressDlg::OnSysCommand(UINT nID, LPARAM lParam) {

if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal();

} else { CDialog::OnSysCommand(nID,

lParam);

} }

void CKeyPressDlg::OnPaint() {

if (IsIconic()) { CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (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

{ } } HCURSOR

CKeyPressDlg::OnQueryDragIcon() {

return (HCURSOR) m_hIcon; }

CDialog::OnPaint();

四,实验结果:

五,实验总结:

本次实验室关于MFC.DLL 动态链接库的编程方法, 需要了解键盘钩子和相应回调函数的运行机制, 了解DLL 的可重要特性等. 受益颇深.


相关文章

  • 光纤通信实验室建设方案
  • 光纤通信实验室建设方案 一.建设的必要性 <光纤通信>是为通信工程专业本科高年级学生开设的专业课,课程全面地讲解了光纤通信技术方面的基本概念.原理及实用系统.实验是配合<光纤通信>课程设置的实验内容,它包含光源及光调 ...查看


  • 单片机原理与接口技术实验室方案
  • 单片机原理与接口技术实验室方案 一.前言 单片机是当今电子信息产业发展最迅速的领域,大学单晶片教学和实验应该适应这样的变化,本方 案是针对单片机原理课程为主的单片机原理与接口技术 单片机原理与接口技术实验室的设备配置,从基础课程建设开始,对 ...查看


  • 实验室信息管理系统(LIMS)
  • 1. 实验室信息管理系统(LIMS )主要功能 1)样品的管理(Sample Management) 是指样品进入实验室到分配检测项目直至完成并认可检测结果出具证书的过程.样品被登录到 LIMS 后,系统将严格按照预先定义好的有关规范对其实 ...查看


  • 计算机接口技术实验教程
  • <计算机接口技术> 实 验 教 程 专业班级: 姓 名: 学 号: 甘肃农业大学信息科学技术学院 计算机接口技术 1 目 录 实验一 汇编程序MASM 的使用 .................................. ...查看


  • [微机原理及应用]课程教学方法探讨
  • 摘要:对<微机原理及应用>课程的课堂教学和实验实践教学方法进行了探讨.针对课堂教学,从教学内容和课堂教育方法两方面进行了总结探讨.探索创新:针对实验实践,对实验内容和实验教学模式进行了大胆尝试. 关键词:微型原理及应用:教学方法 ...查看


  • 单片机的电路原理
  • 单片机的电路原理 单片机技术自发展以来已走过了近20年的发展路程 .单片机技术的发展以微处理器(MPU)技术及超大规模集成电路技术的发展为先导,以广泛的应用领域拉动,表现出较微处理器更具个性的发展趋势.小到遥控电子玩具,大到航空航天技术等电 ...查看


  • 嵌入式软件人才的培养
  • [摘 要]随着信息产业和微电子技术的发展,嵌入式技术已经成为了最热门的技术之一,应用范围遍及我们日常生活的各个角落.于是全社会展开了学习嵌入式技术的热潮,嵌入式技术以不可阻挡的趋势走进了大学校园. [关键词]嵌入式:嵌入式人才:培养 [中图 ...查看


  • 未来计算机接口的设想
  • 摘要:近些年来,脑-机接口BCI(brain-computer interaction)技术的研究在国际上引起了广泛的兴趣并获得了快速的发展.人类大脑能够产生多种信号, 包括电的.磁的.化学的以及大脑活动的机械反应等各种形式.这些信号可以通 ...查看


  • 基于825x的几个相关实验包括课程设计
  • 实验 一 可编程并行接口 一. 实验目的 1. 掌握8255方式0的工作原理及使用方法 二. 实验内容 1. 实验电路如下图,8255C口接逻辑电平开关K0-K7,A口接LED显示电路L0- L7. 2. 编程从8255C口输入数据,再从A ...查看


热门内容