• 注册
  • 关于作者
    企业认证:趣记站长
    关注 6 粉丝 4 喜欢 9 内容 992
    江西省·南昌市
    聊天 送礼
    • 查看作者
    • 用Visual C++设计屏幕抓图程序

        在Windows操作系统中,当用户按下"PrintScreen"按钮后,Windows自动将当前屏幕的图像拷贝到系统剪贴板中,这时可以通过"画笔"这个小程序将剪贴板中的内容保存成图像文件,可以看出,如果需要将当前屏幕保存下来还是比较麻烦的,能否可以自己编写一个应用程序,自动将当前屏幕的内容保存到一个图像文件中去呢?这个答案是肯定的,本实例应用程序就是利用通用的热键管理DLL库实现的热键功能,在收到热键通知后截取屏幕的内容并保存到bmp文件中。例如我们设置图片保存路径为c:\,热键为F9 + Control,然后按Change按钮设置好热键,那么当我们按下CTRL+F9后,当前界面将以BMP图像文件的格式被保存在C:\目录下。

        一、实现方法

        热键管理DLL实际上是一个键盘钩子,由它来监视系统的键盘事件。如果有和程序登记符合的按键组合就通知该程序的窗口。为了应用方便,本实例把它做成了一个标准的管理库来为其它的程序通过热键服务,它有两个输出函数:AddHotkey()和DeleteHotkey(),程序只需要调用这两个函数就可以了,如果编译之后不用改变热键,则只需要AddHotkey就可以了。DLL中的所有的全局变量都放在一个共享段中,定义如下:

      #pragma data_seg("shareddata")

      HHOOK hHook =NULL; //钩子句柄

      UINT nHookCount =0; //挂接的程序数目

      static UCHAR HotKey[MAX_KEY] = {0}; //热键虚拟键码

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

      static HWND hCallWnd[MAX_KEY] = {0}; //window handle associated with hotkey

      static int KeyCount =0;

      static UCHAR MaskBits =0; //00000 Ctrl=4 & Alt=2 & Shift=1

      #pragma data_seg()

        关于共享段,有几点重要的说明:一是必须在链接选项里指定该段为共享:一种方法是在project->settings->link->object/library中加上/section:shareddata,rws;第二种方法是在def文件的sections里加上一句shareddata read write shared;第三种指定共享段的方法在程序里加上一句#pragma comment(linker,"section:shareddata,rws")。二是所有的变量必须初始化,否则链接程序会把它放到普通数据段。三是如果不初始化变量,需要在段外用"__declspec(allocate("shareddata")) 变量类型 变量名"的方式定义。

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

      BOOL __declspec(dllexport) __stdcall AddHotkey(HWND hWnd,UCHAR

      cKey,UCHAR cMask)

      {

       BOOL bAdded=FALSE;

       for(int index=0;index<MAX_KEY;index++){

        if(hCallWnd[index]==0){

         hCallWnd[index]=hWnd;

         HotKey[index]=cKey;

         HotKeyMask[index]=cMask;

         bAdded=TRUE;

         KeyCount++;

         break;

        }

       }

       return bAdded;

      }

      //删除热键

      BOOL __declspec(dllexport) __stdcall DeleteHotkey(HWND hWnd,

      UCHAR cKey,UCHAR cMask)

      {

       BOOL bRemoved=FALSE;

       for(int index=0;index<MAX_KEY;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;

         }

        }

       }

       return bRemoved;

      }

        DLL中的钩子函数如下:

      LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)

      {

       BOOL bProcessed=FALSE;

       if(HC_ACTION==nCode)

       {

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

         switch(wParam)

         {

          case VK_MENU:

           MaskBits&=~ALTBIT;

           break;

          case VK_CONTROL:

           MaskBits&=~CTRLBIT;

           break;

          case VK_SHIFT:

           MaskBits&=~SHIFTBIT;

           break;

          default: //judge the key and send message

           break;

         }

         for(int index=0;index<MAX_KEY;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;

          }

         }

        }

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

         switch(wParam)

         {

          case VK_MENU:

           MaskBits|=ALTBIT;

           break;

          case VK_CONTROL:

           MaskBits|=CTRLBIT;

           break;

          case VK_SHIFT:

           MaskBits|=SHIFTBIT;

           break;

          default: //judge the key and send message

           break;

         }

         for(int index=0;index<MAX_KEY;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(int index=0;index<MAX_KEY;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部分

         }

        }

       }

       return CallNextHookEx( hHook, nCode, wParam, lParam );

      }

        抓图程序是一个基于对话框的程序,它在建立对话框的时候调用前面的DLL,

      VB6如何让程序开机就自动启动
      用VB创建FTP组件(get),Visual Basic构建线程安全的Singleton,如何实现VB与EXCEL的无缝连接,vb中利用xmlhttp来下载远程文件,vb中使用正则表达式,ASP.NET中Cookie编程的基础知识,MASM-打字练习程序,用VB制作注册软件的方法,VB程序中数据库的图片处理的解决方法,用VB编写键盘拦截程序,用VB实现客户——服务器(TCP/IP)编程实例,利用Visual Basic 实现无线通讯,VB 中资源文件的多种使用技巧,VB中资源文件的具体使用方法,vb接收GPS数据源码全,VB6中使用Winsock穿越各种代理的实现(TCP协议),VB实现文字“闪入”显示的特殊效果,VB对注册表操作程序开机时运行,VB将OCX植入执行文件内,利用VB函数Dir()实现递归搜索目录
      Visual Basic

      登记热键,因此需要将hook.lib添加到工程里,在程序里给出两个DLL函数的定义,也可以写个头文件,再包含进来以下代码:

      BOOL __declspec(dllexport)__stdcall AddHotkey(HWND,UCHAR key,UCHAR mask);

      BOOL __declspec(dllexport)__stdcall DeleteHotkey(HWND,UCHAR key,UCHAR mask);

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

      LRESULT CCaptureDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

      {

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

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

        SaveBmp();

        return FALSE;

       }

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

      }

        将屏幕图像保存到BMP文件中的任务是由函数SaveBmp()来完成的,具体实现参见代码部分。另外为了顺利实现屏幕抓图,程序中还实现了"托盘"功能,由于这一部分本书在实例中已经专门介绍过了,所以不再赘述,读者朋友可以参考相关实例。

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

        二、编程步骤

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

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

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

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

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

        三、程序代码

      /////////////////////////////////////////////////////////// Hook.h : main header file for the HOOK DLL

      #if !defined(AFX_HOOK_H__AEBFF705_C93A_11D5_B7D6_0080C82BE86B__INCLUDED_)

      #define AFX_HOOK_H__AEBFF705_C93A_11D5_B7D6_0080C82BE86B__INCLUDED_

      #if _MSC_VER > 1000

      #pragma once

      #endif // _MSC_VER > 1000

      #ifndef __AFXWIN_H__

      #error include ''stdafx.h'' before including this file for PCH

      #endif

      #include "resource.h" // main symbols

      class CHookApp : public CWinApp

      {

       public:

        CHookApp();

        // Overrides

        // ClassWizard generated virtual function overrides

        //{{AFX_VIRTUAL(CHookApp)

       public:

        virtual BOOL InitInstance();

        virtual int ExitInstance();

        //}}AFX_VIRTUAL

        //{{AFX_MSG(CHookApp)

        // NOTE - the ClassWizard will add and remove member functions here.

        // DO NOT EDIT what you see in these blocks of generated code !

        //}}AFX_MSG

       DECLARE_MESSAGE_MAP()

      };

      LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam, LPARAM lParam);

       BOOL __declspec(dllexport)__stdcall AddHotkey(HWND,UCHAR key,UCHAR mask);

       BOOL __declspec(dllexport)__stdcall DeleteHotkey(HWND,UCHAR key,UCHAR mask);

       BOOL InitHotkey();

       BOOL UnInit();

      #endif

      ////////// Hook.cpp : Defines the initialization routines for the DLL.

      #include "stdafx.h"

      #include "hook.h"

      #include <windowsx.h>

      #ifdef _DEBUG

      #define new DEBUG_NEW

      #undef THIS_FILE

      static char THIS_FILE[] = __FILE__;

      #endif

      #define MAX_KEY 100

      #define CTRLBIT 0x04

      #define ALTBIT 0x02

      #define SHIFTBIT 0x01

      #pragma data_seg("shareddata")

      HHOOK hHook =NULL;

      UINT nHookCount =0;

      static UCHAR HotKey[MAX_KEY] = {0}; //hotkey

      static UCHAR HotKeyMask[MAX_KEY] = {0}; //flag for hotkey, value is VK_CONTRL or VK_NEMU or VK_SHIFT

      static HWND hCallWnd[MAX_KEY] = {0}; //window associated with hotkey

      static int KeyCount =0;

      static UCHAR MaskBits =0; //00000 Ctrl Alt Shift

      #pragma data_seg()

      HINSTANCE hins;

      void VerifyWindow();

      BEGIN_MESSAGE_MAP(CHookApp, CWinApp)

      //{{AFX_MSG_MAP(CHookApp)

       // NOTE - the ClassWizard will add and remove mapping macros here.

       // DO NOT EDIT what you see in these blocks of generated code!

      //}}AFX_MSG_MAP

      END_MESSAGE_MAP()

      CHookApp::CHookApp()

      {

       // TODO: add construction code here,

       // Place all significant initialization in InitInstance

      }

      CHookApp theApp;

      LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)

      {

       BOOL bProcessed=FALSE;

       if(HC_ACTION==nCode)

       {

        if((lParam&0xc0000000)==0xc0000000){// Key up

         switch(wParam)

         {

          case VK_MENU:

           MaskBits&=~ALTBIT;

           break;

          case VK_CONTROL:

           MaskBits&=~CTRLBIT;

           break;

          case VK_SHIFT:

           MaskBits&=~SHIFTBIT;

           break;

          default: //judge the key and send message

           break;

         }

         for(int index=0;index<MAX_KEY;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;

          }

         }

        }

        else if((lParam&0xc000ffff)==1){ //Key down

         switch(wParam)

         {

          case VK_MENU:

           MaskBits|=ALTBIT;

           break;

          case VK_CONTROL:

           MaskBits|=CTRLBIT;

           break;

          case VK_SHIFT:

           MaskBits|=SHIFTBIT;

           break;

          default: //judge the key and send message

           break;

         }

         for(int index=0;index<MAX_KEY;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(int index=0;index<MAX_KEY;index++){

          if(hCallWnd[index]==NULL)

           continue;

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

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

         }

        }

       }

       return CallNextHookEx( hHook, nCode, wParam, lParam );

      }

      BOOL InitHotkey()

      {

       if(hHook!=NULL){

        nHookCount++;

        return TRUE;

       }

       else

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

        if(hHook!=NULL)

         nHookCount++;

        return (hHook!=NULL);

      }

      BOOL UnInit()

      {

       if(nHookCount>1){

        nHookCount--;

        return TRUE;

      }

      BOOL unhooked = UnhookWindowsHookEx(hHook);

      if(unhooked==TRUE){

       nHookCount=0;

       hHook=NULL;

      }

      return unhooked;

      }

      BOOL __declspec(dllexport) __stdcall AddHotkey(HWND hWnd,UCHAR cKey,UCHAR cMask)

      {

       BOOL bAdded=FALSE;

       for(int index=0;index<MAX_KEY;index++){

        if(hCallWnd[index]==0){

         hCallWnd[index]=hWnd;

         HotKey[index]=cKey;

         HotKeyMask[index]=cMask;

         bAdded=TRUE;

         KeyCount++;

         break;

        }

       }

       return bAdded;

      }

      BOOL __declspec(dllexport) __stdcall DeleteHotkey(HWND hWnd,UCHAR cKey,UCHAR cMask)

      {

       BOOL bRemoved=FALSE;

       for(int index=0;index<MAX_KEY;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;

         }

        }

       }

       return bRemoved;

      }

      void VerifyWindow()

      {

       for(int i=0;i<MAX_KEY;i++){

        if(hCallWnd[i]!=NULL){

         if(!IsWindow(hCallWnd[i])){

          hCallWnd[i]=NULL;

          HotKey[i]=0;

          HotKeyMask[i]=0;

          KeyCount--;

         }

        }

       }

      }

      BOOL CHookApp::InitInstance()

      {

       AFX_MANAGE_STATE(AfxGetStaticModuleState());

       hins=AfxGetInstanceHandle();

       InitHotkey();

       return CWinApp::InitInstance();

      }

      int CHookApp::ExitInstance()

      {

       VerifyWindow();

       UnInit();

       return CWinApp::ExitInstance();

      }

      ////////////////////////////////////////////////////////////////////// CaptureDlg.h : header file

      #if !defined(AFX_CAPTUREDLG_H__97B51708_C928_11D5_B7D6_0080C82BE86B__INCLUDED_)

      #define AFX_CAPTUREDLG_H__97B51708_C928_11D5_B7D6_0080C82BE86B__INCLUDED_

      #if _MSC_VER > 1000

      #pragma once

      #endif // _MSC_VER > 1000

      class CCaptureDlg : public CDialog

      {

       // Construction

       public:

        BOOL bTray;

        BOOL bRegistered;

        BOOL RegisterHotkey();

        UCHAR cKey;

        UCHAR cMask;

        void DeleteIcon();

        void AddIcon();

        UINT nCount;

        void SaveBmp();

        CCaptureDlg(CWnd* pParent = NULL); // standard constructor

        // Dialog Data

        //{{AFX_DATA(CCaptureDlg)

        enum { IDD = IDD_CAPTURE_DIALOG };

        CComboBox m_Key;

        BOOL m_bControl;

        BOOL m_bAlt;

        BOOL m_bShift;

        CString m_Path;

        CString m_Number;

        //}}AFX_DATA

        // ClassWizard generated virtual function overrides

        //{{AFX_VIRTUAL(CCaptureDlg)

       public:

        virtual BOOL PreTranslateMessage(MSG* pMsg);

       protected:

        virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

        virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);

        //}}AFX_VIRTUAL

        // Implementation

       protected:

        HICON m_hIcon;

        // Generated message map functions

        //{{AFX_MSG(CCaptureDlg)

        virtual BOOL OnInitDialog();

        afx_msg void OnSysCommand(UINT nID, LPARAM lParam);

        afx_msg void OnPaint();

        afx_msg HCURSOR OnQueryDragIcon();

        virtual void OnCancel();

        afx_msg void OnAbout();

        afx_msg void OnBrowse();

        afx_msg void OnChange();

        //}}AFX_MSG

        DECLARE_MESSAGE_MAP()

      };

      #endif

      ////////////////////// CaptureDlg.cpp : implementation file

      #include "stdafx.h"

      #include "Capture.h"

      #include "CaptureDlg.h"

      #include <windowsx.h>

      #pragma comment(lib,"hook.lib")

      #ifdef _DEBUG

      #define new DEBUG_NEW

      #undef THIS_FILE

      static char THIS_FILE[] = __FILE__;

      #endif

      #define IDM_SHELL WM_USER+1

      BOOL __declspec(dllexport)__stdcall AddHotkey(HWND,UCHAR key,UCHAR mask);

      BOOL __declspec(dllexport)__stdcall DeleteHotkey(HWND,UCHAR key,UCHAR mask);

      UCHAR Key_Table[]={0x78,0x79,0x7a,0x7b,0x6a,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};

      class CAboutDlg : public CDialog

      {

       public:

        CAboutDlg();

        // Dialog Data

        //{{AFX_DATA(CAboutDlg)

        enum { IDD = IDD_ABOUTBOX };

        //}}AFX_DATA

        // ClassWizard generated virtual function overrides

        //{{AFX_VIRTUAL(CAboutDlg)

       protected:

        virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support

        //}}AFX_VIRTUAL

        // Implementation

       protected:

        //{{AFX_MSG(CAboutDlg)

        //}}AFX_MSG

       DECLARE_MESSAGE_MAP()

      };

      CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)

      {

       //{{AFX_DATA_INIT(CAboutDlg)

       //}}AFX_DATA_INIT

      }

      void CAboutDlg::DoDataExchange(CDataExchange* pDX)

      {

       CDialog::DoDataExchange(pDX);

       //{{AFX_DATA_MAP(CAboutDlg)

       //}}AFX_DATA_MAP

      }

      BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)

       //{{AFX_MSG_MAP(CAboutDlg)

       // No message handlers

       //}}AFX_MSG_MAP

      END_MESSAGE_MAP()

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

      : CDialog(CCaptureDlg::IDD, pParent)

      {

       //{{AFX_DATA_INIT(CCaptureDlg)

       m_bControl = FALSE;

       m_bAlt = FALSE;

       m_bShift = FALSE;

       m_Path = _T("c:");

       m_Number = _T("0 picture captured.");

       nCount=0;

       bRegistered=FALSE;

       bTray=FALSE;

       //}}AFX_DATA_INIT

       // Note that LoadIcon does not require a subsequent DestroyIcon in Win32

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

      }

      void CCaptureDlg::DoDataExchange(CDataExchange* pDX)

      {

       CDialog::DoDataExchange(pDX);

       //{{AFX_DATA_MAP(CCaptureDlg)

       DDX_Control(pDX, IDC_KEY, m_Key);

       DDX_Check(pDX, IDC_CONTROL, m_bControl);

       DDX_Check(pDX, IDC_ALT, m_bAlt);

       DDX_Check(pDX, IDC_SHIFT, m_bShift);

       DDX_Text(pDX, IDC_PATH, m_Path);

       DDX_Text(pDX, IDC_NUMBER, m_Number);

       //}}AFX_DATA_MAP

      }

      BEGIN_MESSAGE_MAP(CCaptureDlg, CDialog)

       //{{AFX_MSG_MAP(CCaptureDlg)

       ON_WM_SYSCOMMAND()

       ON_WM_PAINT()

       ON_WM_QUERYDRAGICON()

       ON_BN_CLICKED(ID_ABOUT, OnAbout)

       ON_BN_CLICKED(IDC_BROWSE, OnBrowse)

       ON_BN_CLICKED(ID_CHANGE, OnChange)

       //}}AFX_MSG_MAP

      END_MESSAGE_MAP()

      BOOL CCaptureDlg::OnInitDialog()

      {

       CDialog::OnInitDialog();

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

       ASSERT(IDM_ABOUTBOX < 0xF000);

       CMenu* pSysMenu = GetSystemMenu(FALSE);

       if (pSysMenu != NULL)

       {

        CString strAboutMenu;

        strAboutMenu.LoadString(IDS_ABOUTBOX);

        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

       m_Key.SetCurSel(0);

       RegisterHotkey();

       CMenu* pMenu=GetSystemMenu(FALSE);

       pMenu->DeleteMenu(SC_MAXIMIZE,MF_BYCOMMAND);

       pMenu->DeleteMenu(SC_SIZE,MF_BYCOMMAND);

       pMenu->DeleteMenu(SC_RESTORE,MF_BYCOMMAND);

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

      }

      void CCaptureDlg::OnSysCommand(UINT nID, LPARAM lParam)

      {

       if ((nID & 0xFFF0) == IDM_ABOUTBOX)

       {

        CAboutDlg dlgAbout;

        dlgAbout.DoModal();

       }

       else

       {

        CDialog::OnSysCommand(nID, lParam);

       }

      }

      void CCaptureDlg::OnPaint()

      {

       if (IsIconic())

       {

        CPaintDC dc(this); // device context for painting

        SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

        // Center icon in client rectangle

        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;

        // Draw the icon

        dc.DrawIcon(x, y, m_hIcon);

       }

       else

       {

        CDialog::OnPaint();

       }

      }

      HCURSOR CCaptureDlg::OnQueryDragIcon()

      {

       return (HCURSOR) m_hIcon;

      }

      void CCaptureDlg::OnCancel()

      {

       if(bTray)

        DeleteIcon();

        CDialog::OnCancel();

      }

      void CCaptureDlg::OnAbout()

      {

       CAboutDlg dlg;

       dlg.DoModal();

      }

      void CCaptureDlg::OnBrowse()

      {

       CString str;

       BROWSEINFO bi;

       char name[MAX_PATH];

       ZeroMemory(&bi,sizeof(BROWSEINFO));

       bi.hwndOwner=GetSafeHwnd();

       bi.pszDisplayName=name;

       bi.lpszTitle="Select folder";

       bi.ulFlags=BIF_RETURNONLYFSDIRS;

       LPITEMIDLIST idl=SHBrowseForFolder(&bi);

       if(idl==NULL)

        return;

       SHGetPathFromIDList(idl,str.GetBuffer(MAX_PATH));

       str.ReleaseBuffer();

       m_Path=str;

       if(str.GetAt(str.GetLength()-1)!='''')

        m_Path+="";

       UpdateData(FALSE);

      }

      void CCaptureDlg::SaveBmp()

      {

       CDC dc;

       dc.CreateDC("DISPLAY",NULL,NULL,NULL);

       CBitmap bm;

       int Width=GetSystemMetrics(SM_CXSCREEN);

       int Height=GetSystemMetrics(SM_CYSCREEN);

       bm.CreateCompatibleBitmap(&dc,Width,Height);

       CDC tdc;

       tdc.CreateCompatibleDC(&dc);

       CBitmap*pOld=tdc.SelectObject(&bm);

       tdc.BitBlt(0,0,Width,Height,&dc,0,0,SRCCOPY);

       tdc.SelectObject(pOld);

       BITMAP btm;

       bm.GetBitmap(&btm);

       DWORD size=btm.bmWidthBytes*btm.bmHeight;

       LPSTR lpData=(LPSTR)GlobalAllocPtr(GPTR,size);

       BITMAPINFOHEADER bih;

       bih.biBitCount=btm.bmBitsPixel;

       bih.biClrImportant=0;

       bih.biClrUsed=0;

       bih.biCompression=0;

       bih.biHeight=btm.bmHeight;

       bih.biPlanes=1;

       bih.biSize=sizeof(BITMAPINFOHEADER);

       bih.biSizeImage=size;

       bih.biWidth=btm.bmWidth;

       bih.biXPelsPerMeter=0;

       bih.biYPelsPerMeter=0;

       GetDIBits(dc,bm,0,bih.biHeight,lpData,(BITMAPINFO*)&bih,DIB_RGB_COLORS);

       static int filecount=0;

       CString name;

       name.Format("pict%04d.bmp",filecount++);

       name=m_Path+name;

       BITMAPFILEHEADER bfh;

       bfh.bfReserved1=bfh.bfReserved2=0;

       bfh.bfType=((WORD)(''M''<< 8)|''B'');

       bfh.bfSize=54+size;

       bfh.bfOffBits=54;

       CFile bf;

       if(bf.Open(name,CFile::modeCreate|CFile::modeWrite)){

        bf.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER));

        bf.WriteHuge(&bih,sizeof(BITMAPINFOHEADER));

        bf.WriteHuge(lpData,size);

        bf.Close();

        nCount++;

       }

       GlobalFreePtr(lpData);

       if(nCount==1)

        m_Number.Format("%d picture captured.",nCount);

       else

        m_Number.Format("%d pictures captured.",nCount);

       UpdateData(FALSE);

      }

      BOOL CCaptureDlg::PreTranslateMessage(MSG* pMsg)

      {

       if(pMsg -> message == WM_KEYDOWN)

       {

        if(pMsg -> wParam == VK_ESCAPE)

         return TRUE;

        if(pMsg -> wParam == VK_RETURN)

         return TRUE;

       }

       return CDialog::PreTranslateMessage(pMsg);

      }

      LRESULT CCaptureDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)

      {

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

        SaveBmp();

       return FALSE;

      }

      if(message==IDM_SHELL&&lParam==WM_RBUTTONUP){

       CMenu pop;

       pop.LoadMenu(MAKEINTRESOURCE(IDR_MENU1));

       CMenu*pMenu=pop.GetSubMenu(0);

       pMenu->SetDefaultItem(ID_EXITICON);

       CPoint pt;

       GetCursorPos(&pt);

       int id=pMenu->TrackPopupMenu(TPM_RIGHTALIGN|TPM_NONOTIFY|TPM_RETURNCMD|TPM_LEFTBUTTON,pt.x,pt.y,this);

       if(id==ID_EXITICON)

        DeleteIcon();

       else if(id==ID_EXIT)

        OnCancel();

       return FALSE;

      }

      LRESULT res= CDialog::WindowProc(message, wParam, lParam);

      if(message==WM_SYSCOMMAND&&wParam==SC_MINIMIZE)

      AddIcon();

      return res;

      }

      void CCaptureDlg::AddIcon()

      {

       NOTIFYICONDATA data;

       data.cbSize=sizeof(NOTIFYICONDATA);

       CString tip;

       tip.LoadString(IDS_ICONTIP);

       data.hIcon=GetIcon(0);

       data.hWnd=GetSafeHwnd();

       strcpy(data.szTip,tip);

       data.uCallbackMessage=IDM_SHELL;

       data.uFlags=NIF_ICON|NIF_MESSAGE |NIF_TIP ;

       data.uID=98;

       Shell_NotifyIcon(NIM_ADD,&data);

       ShowWindow(SW_HIDE);

       bTray=TRUE;

      }

      void CCaptureDlg::DeleteIcon()

      {

       NOTIFYICONDATA data;

       data.cbSize=sizeof(NOTIFYICONDATA);

       data.hWnd=GetSafeHwnd();

       data.uID=98;

       Shell_NotifyIcon(NIM_DELETE,&data);

       ShowWindow(SW_SHOW);

       SetForegroundWindow();

       ShowWindow(SW_SHOWNORMAL);

       bTray=FALSE;

      }

      void CCaptureDlg::OnChange()

      {

       RegisterHotkey();

      }

      BOOL CCaptureDlg::RegisterHotkey()

      {

       UpdateData();

       UCHAR mask=0;

       UCHAR key=0;

       if(m_bControl)

        mask|=4;

       if(m_bAlt)

        mask|=2;

       if(m_bShift)

        mask|=1;

       key=Key_Table[m_Key.GetCurSel()];

       if(bRegistered){

        DeleteHotkey(GetSafeHwnd(),cKey,cMask);

        bRegistered=FALSE;

       }

       cMask=mask;

       cKey=key;

       bRegistered=AddHotkey(GetSafeHwnd(),cKey,cMask);

       return bRegistered;

      }

      四、小结

        本实例通过一个钩子DLL实现了屏幕抓图的功能,它有一个缺陷,那就是只能保存整个屏幕图像,不过读者朋友可以在此基础上,实现屏幕任意区域的抓图功能,具体方法不再赘述,实现起来很容易的了,呵呵。

      IIS 常用操作编程实现(VB6)
      用VB创建FTP组件(get),Visual Basic构建线程安全的Singleton,如何实现VB与EXCEL的无缝连接,vb中利用xmlhttp来下载远程文件,vb中使用正则表达式,ASP.NET中Cookie编程的基础知识,MASM-打字练习程序,用VB制作注册软件的方法,VB程序中数据库的图片处理的解决方法,用VB编写键盘拦截程序,用VB实现客户——服务器(TCP/IP)编程实例,利用Visual Basic 实现无线通讯,VB 中资源文件的多种使用技巧,VB中资源文件的具体使用方法,vb接收GPS数据源码全,VB6中使用Winsock穿越各种代理的实现(TCP协议),VB实现文字“闪入”显示的特殊效果,VB对注册表操作程序开机时运行,VB将OCX植入执行文件内,利用VB函数Dir()实现递归搜索目录
      Visual Basic

    • 0
    • 0
    • 0
    • 58
    • 单栏布局 侧栏位置: