一篇好文:VC2010中的C++0x特性 Part 2:右值引用

http://www.cnblogs.com/oiramario/archive/2010/10/11/1847802.html
阅读更多
换一批

好文一篇(2)

03-04

钩子函数的应用 rn rnrn--------------------------------------------------------------------------------rn rn作者:吴燕 刘宏波 rn rn 摘 要:介绍了钩子的有关知识,并给出了在Delphi环境下编写的键盘鼠标钩子的程序示例。rn 关键词:钩子;键盘钩子;鼠标钩子;Delphirn rn 钩子是Windows中消息处理机制的一个要点,通过安装各种钩子,应用程序能够设置相应的子例程来监视系统里的消息传递以及在这些消息到达目的地之前截获它们并根据用户要求做出相应处理。钩子的种类很多其作用也不同,如键盘钩子可以截获键盘消息,鼠标钩子可以截获鼠标消息,外壳钩子可以截获启动和关闭应用程序的消息,日志钩子可以监视和记录输入事件。钩子分为线程专用钩子和全局钩子,线程专用钩子只监视指定的线程,要监视系统中的所有线程,必须用到全局钩子。对于全局钩子,钩子函数必须包含在独立的动态链接库(DLL)中,这样才能被各种相关联的应用程序调用。rn ~~一、钩子函数简介rn Windows提供API函数SetwindowsHookEx来建立一个Hook,通过这个函数可以将一个程序添加到Hook链中监视Windows消息,函数语法为:rn SetwindowsHookEx (idHook:Integer;lpfn:TFNHookProc;hmod: HINST;dwThreadId:DWORD)rn 其中参数idHook指定建立的监视函数类型。通过Windows MSDN帮助可以看到,SetwindowsHookEx函数提供15种不同的消息监视类型,而WH_JOURNALRECORD和WH_JOURNALPLAYBACK是用来监视键盘和鼠标操作的。参数lpfn指定消息函数,在相应的消息产生后,系统会调用该函数并将消息值传递给该函数供处理。函数的一般形式为:rn Hookproc (icode:Integer;wparam:WPARAM;lparam:LPARAM):LRESULT;stdcall; rn 其中icode为系统指示标记,wParam和lParam为附加参数,根据不同的消息监视类型而不同。只要在程序中建立这样一个函数再通过SetwindowsHookEx函数将它加入到消息监视链中就可以处理消息了。在不需要监视系统消息时可以调用UnHookWindowsHookEx来解除对消息的监视。WH_JOURNALRECORD和WH_JOURNALPLAYBACK类型是两种相反的Hook类型,前者获得鼠标、键盘动作消息,后者回放鼠标、键盘消息。rn rn ~~二、钩子程序的实例rn 在本程序中建立了两个消息函数,一个用于纪录鼠标、键盘的动作并保存,另一个用于将保存的动作返给系统回放。在Delphi中建立一个工程,在Form1上添加3个按钮用于程序操作。另外再添加一个Edit控件用于验证操作。以下程序在Delphi6.0、Windows98环境下调试通过。rn unit Unit1;rn interfacern uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms,rn Dialogs, StdCtrls;rn typern TForm1 = class(TForm)rn Button1: TButton;rn Button2: TButton;rn Button3: TButton;rn Edit1: TEdit;rn procedure FormCreate(Sender: TObject);rn procedure Button1Click(Sender: TObject);rn procedure Button2Click(Sender: TObject);rn procedure Button3Click(Sender: TObject);rn privatern private declarations rn publicrn public declarations rn end;rn varrn Form1: TForm1;rn EventArr:array[0..1000]of EVENTMSG;rn EventLog:Integer;rn PlayLog:Integer;rn hHook,hPlay:Integer;rn recOK:Integer;rn canPlay:Integer;rn bDelay:Bool;rn implementationrn $R *.DFMrn function PlayProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;rn beginrn canPlay:=1;rn Result:=0;rn if iCode < 0 then //必须将消息传递到钩子链的下一个处理程序rn Result := CallNextHookEx(hPlay,iCode,wParam,lParam)rn else if iCode = HC_SYSMODALON then canPlay:=0rn else if iCode = HC_SYSMODALOFF then canPlay:=1rn else if ((canPlay =1 )and(iCode=HC_GETNEXT)) then beginrn if bDelay then beginrn bDelay:=False;rn Result:=50;rn end;rn pEventMSG(lParam)^:=EventArr[PlayLog];rn endrn else if ((canPlay = 1)and(iCode = HC_SKIP))then beginrn bDelay := True;rn PlayLog:=PlayLog+1;rn end;rn if PlayLog>=EventLog then beginrn UNHookWindowsHookEx(hPlay);rn end;rn end;rn function HookProc(iCode:Integer;wParam:wParam;lParam:lParam):LRESULT;stdcall;rn beginrn recOK:=1;rn Result:=0; rn if iCode < 0 thenrn Result := CallNextHookEx(hHook,iCode,wParam,lParam)rn else if iCode = HC_SYSMODALON then recOK:=0rn else if iCode = HC_SYSMODALOFF then recOK:=1rn else if ((recOK>0) and (iCode = HC_ACTION)) then beginrn EventArr[EventLog]:=pEventMSG(lParam)^;rn EventLog:=EventLog+1;rn if EventLog>=1000 then beginrn UnHookWindowsHookEx(hHook);rn end;rn end;rn end;rn procedure TForm1.FormCreate(Sender: TObject);rn beginrn Button1.Caption:='纪录';rn Button2.Caption:='停止';rn Button3.Caption:='回放';rn Button2.Enabled:=False;rn Button3.Enabled:=False;rn end;rn procedure TForm1.Button1Click(Sender: TObject);rn beginrn EventLog:=0;rn //建立键盘、鼠标操作消息纪录链rn hHook:=SetwindowsHookEx(WH_JOURNALRECORD,HookProc,HInstance,0);rn Button2.Enabled:=True;rn Button1.Enabled:=False;rn end;rn procedure TForm1.Button2Click(Sender: TObject);rn beginrn UnHookWindowsHookEx(hHook);rn hHook:=0;rn Button1.Enabled:=True;rn Button2.Enabled:=False;rn Button3.Enabled:=True;rn end;rn procedure TForm1.Button3Click(Sender: TObject);rn beginrn PlayLog:=0;rn //建立键盘鼠标操作消息纪录回放链rn hPlay:=SetwindowsHookEx(WH_JOURNALPLAYBACK,PlayProc,rn HInstance,0); rn Button3.Enabled:=False;rn end; rn end. rn 运行程序,点击“纪录”按钮开始纪录操作,这时你可以在文本控件中输入一些文字,然后点击“停止”按钮停止纪录,再点击“回放”按钮就可以将先前所做的操作回放。在上面的程序中,HookProc是纪录操作的消息函数,每当有鼠标、键盘消息发生时,系统都会调用该函数,消息信息就保存在地址lParam中,PlayProc是消息回放函数,当系统执行消息回放时调用该函数,程序就将先前纪录的消息值返回到lParam指向的区域中,系统就会执行该消息,从而实现了消息回放。rn rn ~~三、小结rn Hook是应用程序在Microsoft Windows 消息处理过程中设置的用来监控消息流并且处理系统中尚未到达目的窗口的某一类型消息过程的机制。这可以帮助应用程序实现实现某些特殊目的,如控制键盘或鼠标的输入消息,监视窗口的打开关闭以及实现记录宏等等,应用灵活,功能强大。如果Hook过程在应用程序中实现,若应用程序不是当前窗口时,该Hook就不起作用;如果Hook在DLL中实现,程序在运行中动态调用它,它能实时对系统进行监控。rn rn 参考文献rn rn 1.Jeffrey Richter. Advanced Windows third edition. Microsoft Press, 1997rn 2.Feffrey Richter. Windows95 WindowsNT3.5 高级编程技术. 清华大学出版社,1996年rnrn rn

VC2010C++0x初体验

05-21

VS2010 beta1发布了,我只关心其编译器对C++0x的支持如何。于是下载,安装,写最简单的控制台程序,命令行编译之,成功!没有了tr1命名空间了,这点感觉很好,不过thread看起来还不支持!rn下面是测试程序:rn[code=C/C++]#include rn#include rn#include rnrnint main()rnrn for (auto i = 0; i < 10; ++i)rn rn std::cout << i << std::endl;rn rnrn std::shared_ptr sp(new int(1));rn std::cout << *sp << std::endl;rnrn std::vector v;rn v.push_back(1.0);rn v.push_back(1.0/2);rn v.push_back(1.0/3);rn for (auto it = v.begin(); it != v.end(); ++it)rn rn std::cout << *it << std::endl;rn rnrn return 0;rn[/code]rnrn测试结果:rnD:\>cl main.cpprnMicrosoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.20506.01 for 80x86rnCopyright (C) Microsoft Corporation. All rights reserved.rnrnmain.cpprnE:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xlocale(355) : warningrnC4530: C++ exception handler used, but unwind semantics are not enabled. Specifyrn/EHscrnmain.cpp(4) : fatal error C1083: Cannot open include file: 'thread': No such filrne or directoryrnrnD:\>cl main.cpprnMicrosoft (R) 32-bit C/C++ Optimizing Compiler Version 16.00.20506.01 for 80x86rnCopyright (C) Microsoft Corporation. All rights reserved.rnrnmain.cpprnE:\Program Files\Microsoft Visual Studio 10.0\VC\INCLUDE\xlocale(355) : warningrnC4530: C++ exception handler used, but unwind semantics are not enabled. Specifyrn/EHscrnMicrosoft (R) Incremental Linker Version 10.00.20506.01rnCopyright (C) Microsoft Corporation. All rights reserved.rnrn/out:main.exernmain.objrnrnD:\>mainrn0rn1rn2rn3rn4rn5rn6rn7rn8rn9rn1rn1rn0.5rn0.333333

没有更多推荐了,返回首页