1、HOOK过程,即钩子过程
1> 操作系统将我们感兴趣的消息都先交给钩子过程,后者实际上就是一个函数,在此函数中进行判断,如果是我们希望屏蔽掉的消息,那么就直接处理掉,不让它在继续向下传递。
2> SetWindowsHookEx函数:安装一个钩子过程,并将其放进钩子链中。
多个钩子过程就形成了钩子链,要注意的是,最后安装的钩子过程总是排列在该链的前面。
3> UnhookWindowsHookEx函数:从钩子链中移走一个已安装的钩子
2、安装鼠标钩子:
HHOOK g_hMouse=NULL;
//在MSDN中得到鼠标钩子过程函数
LRESULT CALLBACK MouseProc(int nCode, WPARAM wParam, LPARAM lParam)
{
return 1; //返回非零表示Mouse消息已经处理了,相当于屏蔽掉了
}
//OnInitDialog()函数中安装鼠标钩子
g_hMouse=SetWindowsHookEx( WH_MOUSE, MouseProc,NULL, GetCurrentThreadId()); //返回所安装钩子过程的句柄
//GetCurrentThreadId函数得到当前线程的ID
注:如果钩子函数返回非0值,表示已经对当前消息进行了处理。
3、安装键盘钩子:
HHOOK g_hKeyBoard=NULL;
//在MSDN中得到键盘钩子过程函数
LRESULT CALLBACK KeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
//屏蔽所有按键消息
//return 1;
/*//屏蔽空格和回车键按键消息
if(VK_SPACE==wParam || VK_RETURN==wParam)
{
return 1;
}*/
/*//屏蔽Alt+F4组合键消息
if(VK_F4==wParam && 1==(lParam>>29 & 1))
return 1;*/
//实现F2推出程序的功能
if(VK_F2==wParam)
{
::SendMessage(hWnd, WM_CLOSE, wParam, lParam); //给应用程序的主窗口发送WM_CLOSE消息,让应用程序从主窗口退出,
从而程序也就退出了
UnhookWindowsHookEx(g_hMouse); //将钩子过程移除,从hook链中
UnhookWindowsHookEx(g_hKeyBoard);
}
else
return CallNextHookEx(g_hKeyBoard, code, wParam, lParam);
}
//OnInitDialog()函数中安装键盘钩子
hWnd=m_hWnd;
g_hKeyBoard=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc, NULL, GetCurrentThreadId());
注:键盘虚拟键的宏都是以"VK_"开头的
4、全局钩子:如果要想屏蔽当前正在运行的所有进程的鼠标消息和键盘消息,那么安装钩子过程的代码,必须放到动态链接库中去实现。
1> 获得指定的DLL模块句柄:
(1)为DLL程序提供一个DllMain函数,当第一次加载DLL时,系统会调用这个函数,并传递当前DLL模块的句柄。
(2)GetModuleHandle函数
2> DLL调试方法
3> 实现功能:在程序切换时不能看到其他程序的窗口,即让用户始终看到的都是一个指定程序的窗口(把程序的窗口设置为最顶层窗
口,并将窗口的大小设置为屏幕的大小。)SetWindowPos
4> 当DLL被多个进程使用时,这些进程可以共享DLL的同一份代码和数据。
写入时复制机制
节的使用(新建,设共享)
查看节信息列表:dumpbin -Headers 【dll的完整路径】
注:Hook API是指Windows开放给程序员的编程接口,使得在用户级别下可以对操作系统进行控制,也就是一般的应用程序都需要调用API来完成某些功能, Hook API的意思就是在这些应用程序调用真正的系统API前可以先被截获,从而进行一些处理再调用真正的API来完成功能。
5、在使用COM组件时,一定要调用CoInitialized函数初始化COM库,在访问完COM库后,还需要调用CoUninitialze函数卸载 COM库。
6、数据库访问技术:对数据库的访问总是按行进行的
ODBC(Open Database Connectivity, 开放数据库互联):它为编写关系数据库的客户软件提供了一种统一的接口
DAO(Data Access Object, 数据访问对象)(过时)
RDO(Remote Data Object, 远程数据对象)(过时)
OLE DB(对象链接与嵌入数据库):
1> 提供了一个数据库编程的COM接口,底层采用COM技术实现
2> 提供了一个可用于访问关系数据库和非关系型数据源的接口
3> OLE DB的两个基本结构是OLE DB提供程序(Provider)和OLE DB用户程序(Consumer)
ADO(ActiveX Data Object, ActiveX数据对象):
1> 本身是一个OLE DB用户程序, 即一个Consumer
2> 简化了OLE DB,提供了自动化支持
1> 三个核心对象:Connection对象,Command对象,Recordset对象
4> Recordset和Command对象都有一个ActiveConnection属性,该属性用来引用Connection对象
7、在VC++中:使用OLE DB,编写OLE DB用户程序;速度快,不支持自动化
VBScript、VB中:使用ADO,支持自动化,速度较慢
8、在VC中利用ADO访问数据库(访问Access数据源)
1> 导入ADO库:
//在stdafx.h中
#import "C:/Program Files/Common Files/System/ado/msado15.dll" no_namespace rename("EOF", "rsEOF")
注:编译后,Debug目录下产生了两个文件:msado15.tlh和msado15.tli,自动生成的
2> 在服务资源管理器中“添加连接”,新建目标Access数据源。
新建链接成功后,vs05会自动产生相应的“连接字符串”(所建连接的属性面板中)
3> 利用Connection智能指针对象执行SQL查询
void CADODlg::OnBnClickedBtnQuery()
{
// TODO: 在此添加控件通知处理程序代码
CoInitialize(NULL); //初始化COM库
_ConnectionPtr pConn(__uuidof(Connection)); //定义了一个Connection智能指针对象
_RecordsetPtr pRst(__uuidof(Recordset)); //定义了一个Recordset智能指针对象
//链接字符串,来源于vs自动生成
pConn->ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F://F-disk//C++//CPP//VC//ADO//debug//test.mdb";
pConn->Open("", "", "", adConnectUnspecified); //打开到数据库的链接,adConnectUnspecified表示同步链接
pRst=pConn->Execute("select * from tab_test", NULL, adCmdText);
while(!pRst->rsEOF) //记录集末尾
{
((CListBox* )GetDlgItem(IDC_LIST1))->AddString((_bstr_t)pRst->GetCollect("first"));
pRst->MoveNext();
}
pRst->Close(); //调用记录集对象的Close方法关闭记录集
pConn->Close(); //调用连接对象的Close方法关闭连接
pRst.Release(); //释放智能指针在COM接口上的引用计数
pConn.Release();
CoUninitialize(); //卸载COM库
}
4> 利用Recordset智能指针对象执行SQL查询语句
void CADODlg::OnBnClickedBtnQuery()
{
// TODO: 在此添加控件通知处理程序代码
CoInitialize(NULL); //初始化COM库
_ConnectionPtr pConn(__uuidof(Connection)); //定义了一个Connection智能指针对象
_RecordsetPtr pRst(__uuidof(Recordset)); //定义了一个Recordset智能指针对象
//链接字符串,来源于vs自动生成
pConn->ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F://F-disk//C++//CPP//VC//ADO//debug//test.mdb";
pConn->Open("", "", "", adConnectUnspecified); //打开到数据库的链接,adConnectUnspecified表示同步链接
pRst->Open("select * from tab_test", _variant_t((IDispatch*)pConn), adOpenDynamic,adLockOptimistic, adCmdText);
while(!pRst->rsEOF)
{
((CListBox* )GetDlgItem(IDC_LIST1))->AddString((_bstr_t)pRst->GetCollect("first"));
pRst->MoveNext();
}
pRst->Close(); //调用记录集对象的Close方法关闭记录集
pConn->Close(); //调用连接对象的Close方法关闭连接
pRst.Release();
pConn.Release();
CoUninitialize(); //卸载COM库
}
5> 利用Command智能指针对象来访问数据库(重复执行一条SQL语句时,最好使用Command对象来实现)
void CADODlg::OnBnClickedBtnQuery()
{
// TODO: 在此添加控件通知处理程序代码
CoInitialize(NULL); //初始化COM库
_ConnectionPtr pConn(__uuidof(Connection)); //定义了一个Connection智能指针对象
_RecordsetPtr pRst(__uuidof(Recordset)); //定义了一个Recordset智能指针对象
_CommandPtr pCmd(__uuidof(Command)); //定义了一个Command智能指针对象
//链接字符串,来源于vs自动生成
pConn->ConnectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=F://F-disk//C++//CPP//VC//ADO//debug//test.mdb";
pConn->Open("", "", "", adConnectUnspecified); //打开到数据库的链接,adConnectUnspecified表示同步链接
pCmd->put_ActiveConnection(_variant_t((IDispatch* )pConn)); //用来设置活动连接
pCmd->CommandText="select * from tab_test"; //设置Command对象的命令文本属性(CommandText),此处直接将其设置为一条SQL语句
pRst=pCmd->Execute(NULL, NULL, adCmdText);
while(!pRst->rsEOF)
{
((CListBox* )GetDlgItem(IDC_LIST1))->AddString((_bstr_t)pRst->GetCollect("first"));
pRst->MoveNext();
}
pRst->Close(); //调用记录集对象的Close方法关闭记录集
pConn->Close(); //调用连接对象的Close方法关闭连接
pRst.Release();
pConn.Release();
CoUninitialize(); //卸载COM库
}
注:此处介绍了三种利用ADO技术访问数据库的程序实现方法,无论采用哪种方法访问数据,最终数据都是放在记录集对象中。在VC中
利用ADO访问数据库比较麻烦。
代码中把自动产生的链接字符串中表示目录的"/"皆改成"//"(转义)
9、智能指针的一个特点:在访问其他方法和属性时都是用箭头指向操作符(->),但在调用Release方法释放引用计数时必须使用点操作符(.)
VC++深入详解·chapter20·笔记
最新推荐文章于 2020-09-03 19:42:04 发布