VC++深入详解·chapter20·笔记

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方法释放引用计数时必须使用点操作符(.)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值