在Windows操作系统中.docx

上传人:b****3 文档编号:3900417 上传时间:2022-11-26 格式:DOCX 页数:18 大小:22.94KB
下载 相关 举报
在Windows操作系统中.docx_第1页
第1页 / 共18页
在Windows操作系统中.docx_第2页
第2页 / 共18页
在Windows操作系统中.docx_第3页
第3页 / 共18页
在Windows操作系统中.docx_第4页
第4页 / 共18页
在Windows操作系统中.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

在Windows操作系统中.docx

《在Windows操作系统中.docx》由会员分享,可在线阅读,更多相关《在Windows操作系统中.docx(18页珍藏版)》请在冰豆网上搜索。

在Windows操作系统中.docx

在Windows操作系统中

在Windows操作系统中,当用户按下"PrintScreen"按钮后,Windows自动将当前屏幕的图像拷贝到系统剪贴板中,这时可以通过"画笔"这个小程序将剪贴板中的内容保存成图像文件,可以看出,如果需要将当前屏幕保存下来还是比较麻烦的,能否可以自己编写一个应用程序,自动将当前屏幕的内容保存到一个图像文件中去呢?

这个答案是肯定的,本实例应用程序就是利用通用的热键管理DLL库实现的热键功能,在收到热键通知后截取屏幕的内容并保存到bmp文件中。

例如我们设置图片保存路径为c:

\,热键为F9+Control,然后按Change按钮设置好热键,那么当我们按下CTRL+F9后,当前界面将以BMP图像文件的格式被保存在C:

\目录下。

  一、实现方法

  热键管理DLL实际上是一个键盘钩子,由它来监视系统的键盘事件。

如果有和程序登记符合的按键组合就通知该程序的窗口。

为了应用方便,本实例把它做成了一个标准的管理库来为其它的程序通过热键服务,它有两个输出函数:

AddHotkey()和DeleteHotkey(),程序只需要调用这两个函数就可以了,如果编译之后不用改变热键,则只需要AddHotkey就可以了。

DLL中的所有的全局变量都放在一个共享段中,定义如下:

#pragmadata_seg("shareddata")

HHOOKhHook=NULL;//钩子句柄

UINTnHookCount=0;//挂接的程序数目

staticUCHARHotKey[MAX_KEY]={0};//热键虚拟键码

staticUCHARHotKeyMask[MAX_KEY]={0};//组合掩码,control=4,alt=2,shift=1

staticHWNDhCallWnd[MAX_KEY]={0};//windowhandleassociatedwithhotkey

staticintKeyCount=0;

staticUCHARMaskBits=0;//00000Ctrl=4&Alt=2&Shift=1

#pragmadata_seg()

  关于共享段,有几点重要的说明:

一是必须在链接选项里指定该段为共享:

一种方法是在project->settings->link->object/library中加上/section:

shareddata,rws;第二种方法是在def文件的sections里加上一句shareddatareadwriteshared;第三种指定共享段的方法在程序里加上一句#pragmacomment(linker,"section:

shareddata,rws")。

二是所有的变量必须初始化,否则链接程序会把它放到普通数据段。

三是如果不初始化变量,需要在段外用"__declspec(allocate("shareddata"))变量类型变量名"的方式定义。

  DLL中的两个输出函数分别用来添加/删除热键,函数代码如下:

BOOL__declspec(dllexport)__stdcallAddHotkey(HWNDhWnd,UCHAR

cKey,UCHARcMask)

{

 BOOLbAdded=FALSE;

 for(intindex=0;index

  if(hCallWnd[index]==0){

   hCallWnd[index]=hWnd;

   HotKey[index]=cKey;

   HotKeyMask[index]=cMask;

   bAdded=TRUE;

   KeyCount++;

   break;

  }

 }

 returnbAdded;

}

//删除热键

BOOL__declspec(dllexport)__stdcallDeleteHotkey(HWNDhWnd,

UCHARcKey,UCHARcMask)

{

 BOOLbRemoved=FALSE;

 for(intindex=0;index

  if(hCallWnd[index]==hWnd){

   if(HotKey[index]==cKey&&HotKeyMask[index]==cMask){

    hCallWnd[index]=NULL;

    HotKey[index]=0;

    HotKeyMask[index]=0;

    bRemoved=TRUE;

    KeyCount--;

    break;

   }

  }

 }

 returnbRemoved;

}

  DLL中的钩子函数如下:

LRESULTCALLBACKKeyboardProc(intnCode,WPARAMwParam,LPARAMlParam)

{

 BOOLbProcessed=FALSE;

 if(HC_ACTION==nCode)

 {

  if((lParam&0xc0000000)==0xc0000000){//有键松开

   switch(wParam)

   {

    caseVK_MENU:

     MaskBits&=~ALTBIT;

     break;

    caseVK_CONTROL:

     MaskBits&=~CTRLBIT;

     break;

    caseVK_SHIFT:

     MaskBits&=~SHIFTBIT;

     break;

    default:

//judgethekeyandsendmessage

     break;

   }

   for(intindex=0;index

    if(hCallWnd[index]==NULL)

     continue;

    if(IsWindow(hCallWnd[index])&&(HotKey[index]==wParam)&&(HotKeyMask[index]==MaskBits))

    {

     SendMessage(hCallWnd[index],WM_HOTKEY,wParam,WM_KEYUP);

     bProcessed=TRUE;

    }

   }

  }

  elseif((lParam&0xc000ffff)==1){//有键按下

   switch(wParam)

   {

    caseVK_MENU:

     MaskBits|=ALTBIT;

     break;

    caseVK_CONTROL:

     MaskBits|=CTRLBIT;

     break;

    caseVK_SHIFT:

     MaskBits|=SHIFTBIT;

     break;

    default:

//judgethekeyandsendmessage

     break;

   }

   for(intindex=0;index

    if(hCallWnd[index]==NULL)

     continue;

    if(IsWindow(hCallWnd[index])&&(HotKey[index]==wParam)&&(HotKeyMask[index]==MaskBits))

    {

     SendMessage(hCallWnd[index],WM_HOTKEY,wParam,WM_KEYDOWN);

     bProcessed=TRUE;

    }

   }

  }

  if(!

bProcessed){//一般按键事件,为监视键盘的程序留出余地

   for(intindex=0;index

    if(hCallWnd[index]==NULL)

     continue;

    if(IsWindow(hCallWnd[index])&&(HotKey[index]==0)&&(HotKeyMask[index]==0))

     SendMessage(hCallWnd[index],WM_HOTKEY,WM_HOTKEY,lParam);

     //lParam的意义可看MSDN中WM_KEYDOWN部分

   }

  }

 }

 returnCallNextHookEx(hHook,nCode,wParam,lParam);

}

  抓图程序是一个基于对话框的程序,它在建立对话框的时候调用前面的DLL,登记热键,因此需要将hook.lib添加到工程里,在程序里给出两个DLL函数的定义,也可以写个头文件,再包含进来以下代码:

BOOL__declspec(dllexport)__stdcallAddHotkey(HWND,UCHARkey,UCHARmask);

BOOL__declspec(dllexport)__stdcallDeleteHotkey(HWND,UCHARkey,UCHARmask);

  为了添加应用程序对热键通知事件的响应,程序中用的办法是重载WindowProc()函数,该函数代码如下:

LRESULTCCaptureDlg:

:

WindowProc(UINTmessage,WPARAMwParam,LPARAMlParam)

{

 if(message==WM_HOTKEY&&lParam==WM_KEYDOWN)

 {//lParam表示是按下还是松开,如果有多个热键,由wParam来区分

  SaveBmp();

  returnFALSE;

 }

 ……//其它处理及默认处理

}

  将屏幕图像保存到BMP文件中的任务是由函数SaveBmp()来完成的,具体实现参见代码部分。

另外为了顺利实现屏幕抓图,程序中还实现了"托盘"功能,由于这一部分本书在实例中已经专门介绍过了,所以不再赘述,读者朋友可以参考相关实例。

  最后需要提醒读者朋友们注意的是,源程序的编译与使用时要先编译hook.dll并将其放在系统目录(win2000/NT是system32,98/ME是system),然后编译对话框程序运行即可。

  二、编程步骤

  1、启动VisualC++,生成一个DLL项目和一个基于对话框的应用程序项目,并将两个项目分别命名为"Hook"和"Capture";

  2、在"Hook"项目中导出AddHotkey()、DeleteHotkey()函数;

  3、在"Capture"项目中按照图一所示设置对话框的界面,具体设置参见代码部分;

  4、使用ClassWizard在"Capture"项目中添加按钮的鼠标单击消息响应函数,并重载对话框的WindowProc()函数;

  5、添加代码,编译运行程序。

三、程序代码

///////////////////////////////////////////////////////////Hook.h:

mainheaderfilefortheHOOKDLL

#if!

defined(AFX_HOOK_H__AEBFF705_C93A_11D5_B7D6_0080C82BE86B__INCLUDED_)

#defineAFX_HOOK_H__AEBFF705_C93A_11D5_B7D6_0080C82BE86B__INCLUDED_

#if_MSC_VER>1000

#pragmaonce

#endif//_MSC_VER>1000

#ifndef__AFXWIN_H__

#errorinclude''stdafx.h''beforeincludingthisfileforPCH

#endif

#include"resource.h"//mainsymbols

classCHookApp:

publicCWinApp

{

 public:

  CHookApp();

  //Overrides

  //ClassWizardgeneratedvirtualfunctionoverrides

  //{{AFX_VIRTUAL(CHookApp)

 public:

  virtualBOOLInitInstance();

  virtualintExitInstance();

  //}}AFX_VIRTUAL

  //{{AFX_MSG(CHookApp)

  //NOTE-theClassWizardwilladdandremovememberfunctionshere.

  //DONOTEDITwhatyouseeintheseblocksofgeneratedcode!

  //}}AFX_MSG

 DECLARE_MESSAGE_MAP()

};

LRESULTCALLBACKKeyboardProc(intnCode,WPARAMwParam,LPARAMlParam);

 BOOL__declspec(dllexport)__stdcallAddHotkey(HWND,UCHARkey,UCHARmask);

 BOOL__declspec(dllexport)__stdcallDeleteHotkey(HWND,UCHARkey,UCHARmask);

 BOOLInitHotkey();

 BOOLUnInit();

#endif

//////////Hook.cpp:

DefinestheinitializationroutinesfortheDLL.

#include"stdafx.h"

#include"hook.h"

#include

#ifdef_DEBUG

#definenewDEBUG_NEW

#undefTHIS_FILE

staticcharTHIS_FILE[]=__FILE__;

#endif

#defineMAX_KEY100

#defineCTRLBIT0x04

#defineALTBIT0x02

#defineSHIFTBIT0x01

#pragmadata_seg("shareddata")

HHOOKhHook=NULL;

UINTnHookCount=0;

staticUCHARHotKey[MAX_KEY]={0};//hotkey

staticUCHARHotKeyMask[MAX_KEY]={0};//flagforhotkey,valueisVK_CONTRLorVK_NEMUorVK_SHIFT

staticHWNDhCallWnd[MAX_KEY]={0};//windowassociatedwithhotkey

staticintKeyCount=0;

staticUCHARMaskBits=0;//00000CtrlAltShift

#pragmadata_seg()

HINSTANCEhins;

voidVerifyWindow();

BEGIN_MESSAGE_MAP(CHookApp,CWinApp)

//{{AFX_MSG_MAP(CHookApp)

 //NOTE-theClassWizardwilladdandremovemappingmacroshere.

 //DONOTEDITwhatyouseeintheseblocksofgeneratedcode!

//}}AFX_MSG_MAP

END_MESSAGE_MAP()

CHookApp:

:

CHookApp()

{

 //TODO:

addconstructioncodehere,

 //PlaceallsignificantinitializationinInitInstance

}

CHookApptheApp;

LRESULTCALLBACKKeyboardProc(intnCode,WPARAMwParam,LPARAMlParam)

{

 BOOLbProcessed=FALSE;

 if(HC_ACTION==nCode)

 {

  if((lParam&0xc0000000)==0xc0000000){//Keyup

   switch(wParam)

   {

    caseVK_MENU:

     MaskBits&=~ALTBIT;

     break;

    caseVK_CONTROL:

     MaskBits&=~CTRLBIT;

     break;

    caseVK_SHIFT:

     MaskBits&=~SHIFTBIT;

     break;

    default:

//judgethekeyandsendmessage

     break;

   }

   for(intindex=0;index

    if(hCallWnd[index]==NULL)

     continue;

    if(IsWindow(hCallWnd[index])&&(HotKey[index]==wParam)&&(HotKeyMask[index]==MaskBits))

    {

     SendMessage(hCallWnd[index],WM_HOTKEY,wParam,WM_KEYUP);

     bProcessed=TRUE;

    }

   }

  }

  elseif((lParam&0xc000ffff)==1){//Keydown

   switch(wParam)

   {

    caseVK_MENU:

     MaskBits|=ALTBIT;

     break;

    caseVK_CONTROL:

     MaskBits|=CTRLBIT;

     break;

    caseVK_SHIFT:

     MaskBits|=SHIFTBIT;

     break;

    default:

//judgethekeyandsendmessage

     break;

   }

   for(intindex=0;index

   {

    if(hCallWnd[index]==NULL)

     continue;

    if(IsWindow(hCallWnd[index])&&(HotKey[index]==wParam)&&(HotKeyMask[index]==MaskBits))

    {

     SendMessage(hCallWnd[index],WM_HOTKEY,wParam,WM_KEYDOWN);

     bProcessed=TRUE;

    }

   }

  }

  if(!

bProcessed){

   for(intindex=0;index

    if(hCallWnd[index]==NULL)

     continue;

    if(IsWindow(hCallWnd[index])&&(HotKey[index]==0)&&(HotKeyMask[index]==0))

     SendMessage(hCallWnd[index],WM_HOTKEY,WM_HOTKEY,lParam);

   }

  }

 }

 returnCallNextHookEx(hHook,nCode,wParam,lParam);

}

BOOLInitHotkey()

{

 if(hHook!

=NULL){

  nHookCount++;

  returnTRUE;

 }

 else

  hHook=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,hins,0);

  if(hHook!

=NULL)

   nHookCount++;

  return(hHook!

=NULL);

}

BOOLUnInit()

{

 if(nHookCount>1){

  nHookCount--;

  returnTRUE;

}

BOOLunhooked=UnhookWindowsHookEx(hHook);

if(unhooked==TRUE){

 nHookCount=0;

 hHook=NULL;

}

returnunhooked;

}

BOOL__declspec(dllexport)__stdcallAddHotkey(HWNDhWnd,UCHARcKey,UCHARcMask)

{

 BOOLbAdded=FALSE;

 for(intindex=0;index

  if(hCallWnd[index]==0){

   hCallWnd[index]=hWnd;

   HotKey[index]=cKey;

   HotKeyMask[index]=cMask;

   bAdded=TRUE;

   KeyCount++;

   break;

  }

 }

 returnbAdded;

}

BOOL__declspec(dllexport)__stdcallDeleteHotkey(HWNDhWnd,UCHARcKey,UCHARcMask)

{

 BOOLbRemoved=FALSE;

 for(intindex=0;index

  if(hCallWnd[index]==hWnd){

   if(HotKey[index]==cKey&&HotKeyMask[index]==cMask){

    hCallWnd[index]=NULL;

    HotKey[index]=0;

    HotKeyMask[index]=0;

    bRemoved=TRUE;

    KeyCount--;

    break;

   }

  }

 }

 returnbRemoved;

}

void

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > PPT模板 > 动物植物

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1