204上位机VC MFC使用热键抓取桌面图片
204上位机VC MFC使用热键抓取桌面图片 功能展示 桌面的图片的保存也是常用的功能,平常按下Prt Sc键就可在画板上粘贴抓取的桌面图片进行编辑,我们当前例程也实现桌面图片的抓取,点击保存桌面为图片或用快捷键CTRL+G可以将抓取桌面图片保存到指定的目录,效果如图; 要点提示 一.位图也是一种格式的图片,可以使用Cfile类的相关函数进行文件的打开写入与关闭操作;位图分为三个部分1.位图文件头 2.文件头,3位置数据,三个部分使用Cfile类的WriteHuge()函数进行数据写入; 二.热键的使用可以用函数RegisterHotKey()进行注册,然后响应消息WM_HOTKEY就可实现热键功能;在程序退出时得调用函数::UnregisterHotKey(this->m_hWnd,m_HotkeyID);将已注册的热键注销; RegisterHotKey函数原型:BOOL RegisterHotKey(HWNDhWnd,int id,UINTfsModifiers,UINT vk); 详细参数编辑 1.hWnd: 接收热键产生WM_HOTKEY消息的窗口句柄。若该参数NULL,传递给调用线程的WM_HOTKEY消息必须在消息循环中进行处理。 2.id: 定义热键的标识符。调用线程中的其他热键,不能使用同样的标识符。应用程序必须定义一个0X0000-0xBFFF范围的值。一个共享的动态链接库(DLL)必须定义一个范围为0xC000-0xFFFF的值(GlobalAddAtom函数返回该范围)。为了避免与其他动态链接库定义的热键冲突,一个DLL必须使用GlobalAddAtom函数获得热键的标识符。 3.fsModifoers: 定义为了产生WM_HOTKEY消息而必须与由nVirtKey参数定义的键一起按下的键。 该参数可以是如下值的组合: 键值含意 MOD_ALT 0x0001按下的可以是任一Alt键。 MOD_SHIFT 0x0004按下的可以是任一Shift键。 MOD_WIN 0x0008按下的可以是任一Windows徽标键。 MOD_NOREPEAT 0x4000更改热键行为,以便键盘自动重复不会产生多个热键通知。 MOD_CONTROL 0x0002按下的可以是任一Ctrl键。 4.vk: 定义热键的虚拟键码。 若函数调用成功,返回一个非0值。若函数调用失败,则返回值为0。若要获得更多的错误信息,可以调用GetLastError函数获取具体的错误代码。 实现功能 1.新建基于对话框的应用程序 2.包含截图用头文件#include <math.h> #include<windowsx.h>;添加热键ID变量ATOM m_HotkeyID; 热键响应函数voidHotKey(WPARAM wParam,LPARAM lParam); 桌面图片抓取函数void GrabScreen(CStringsBitmapName,BOOL bScrabCursor=TRUE);并在程序初始化时注册热键m_HotkeyID = GlobalAddAtom("MyHotKey")-0XC000;if(!RegisterHotKey(this->m_hWnd,m_HotkeyID,MOD_CONTROL,'G') )MessageBox("注册热键失败"); 3.将热键响应函数HotKey()与消息WM_HOTKEY进行手工映射;ON_MESSAGE(WM_HOTKEY,HotKey) 4.拖拽按钮<保存桌面为图片>关联函数,拖拽选择框ID为IDC_CHECK1用于选择是否抓取鼠标; 5.在程序退出时注销已注册的热键 ::UnregisterHotKey(this->m_hWnd,m_HotkeyID);//注销热键; HotKey() OnGrab() GrabScreen()代码为: - void CGkbc8Dlg::HotKey(WPARAM wParam,LPARAM lParam)
- {
- if(m_HotkeyID == (int)wParam)
- {
- OnGrab();
- }
- }
复制代码- void CGkbc8Dlg::OnGrab()
- {
- CString ReturnPach; //字符串变量
- TCHAR szPath[_MAX_PATH]; //保存路径变量
- BROWSEINFO bi; // BROWSEINFO结构变量
- ZeroMemory(&bi,sizeof(BROWSEINFO));
- bi.lpszTitle = _T("选择图片保存位置"); //对话框标题
- bi.pszDisplayName = szPath; //选择文件夹路径
- bi.ulFlags = BIF_RETURNONLYFSDIRS; //标记
- LPITEMIDLIST pItemIDList = SHBrowseForFolder(&bi);//显示文件浏览对话框
- if(pItemIDList)//用户选择了文件夹
- {
- if(SHGetPathFromIDList(pItemIDList,szPath)) //判断是否获得文件夹路径
- {
- CButton* pBtn=(CButton*)GetDlgItem(IDC_CHECK1);
- CString sFileName(szPath),tmp;
- CTime time = CTime::GetCurrentTime(); //抓图时间
- tmp.Format("\\工控编程吧-%s.bmp",time.Format("_%Y_%m_%d_%H_%M_%S"));
- sFileName+=tmp;//图片名称
- GrabScreen(sFileName,pBtn->GetCheck());
- }
- }
- }
- void CGkbc8Dlg::OnDestroy()
- {
- CDialog::OnDestroy();
- ::UnregisterHotKey(this->m_hWnd,m_HotkeyID);//注销热键
- }
- void CGkbc8Dlg::GrabScreen(CString sBitmapName,BOOL bScrabCursor)
- {
- if(sBitmapName.Right(3)!="bmp")//函数仅保存位图
- return;
- //<>
- CDC* pDeskDC = GetDesktopWindow()->GetDC(); //获取桌面画布对象
- CRect rc;
- GetDesktopWindow()->GetClientRect(rc); //获取屏幕的客户区域
- CDC memDC; //定义一个内存画布
- memDC.CreateCompatibleDC(pDeskDC); //创建一个兼容的画布
- CBitmap bmp;
复制代码- bmp.CreateCompatibleBitmap(pDeskDC,rc.Width(),rc.Height()); //创建兼容位图
- memDC.SelectObject(&bmp); //选中位图对象
- BITMAP bitmap;
- bmp.GetBitmap(&bitmap); //获得图片信息
- memDC.BitBlt(0,0,bitmap.bmWidth,bitmap.bmHeight,pDeskDC,0,0,SRCCOPY);//绘制图片
- if(bScrabCursor) //选择抓取鼠标
- {
- CPoint point;
- GetCursorPos(&point); //鼠标位置
- HICON hicon = (HICON)GetCursor(); //获得鼠标图标句柄
- memDC.DrawIcon(point.x-10,point.y-10,hicon); //绘制鼠标图标
- }
- //<>位图数据
- DWORD size=bitmap.bmWidthBytes*bitmap.bmHeight; //图片数据大小
- LPSTR lpData=(LPSTR)GlobalAllocPtr(GPTR,size);
- int panelsize = 0; //记录调色板大小
- if(bitmap.bmBitsPixel<16) //判断是否为真彩色位图
- panelsize = (int)pow(2,bitmap.bmBitsPixel*sizeof(RGBQUAD));
- BITMAPINFOHEADER *pBInfo = (BITMAPINFOHEADER*)LocalAlloc(LPTR,
- sizeof(BITMAPINFO)+panelsize); //位图头指针
- pBInfo->biBitCount = bitmap.bmBitsPixel; //位图像素
- pBInfo->biClrImportant = 0;
- pBInfo->biCompression = 0;
- pBInfo->biHeight = bitmap.bmHeight; //位图高
- pBInfo->biPlanes = bitmap.bmPlanes;
- pBInfo->biSize = sizeof(BITMAPINFO);
- pBInfo->biSizeImage = bitmap.bmWidthBytes*bitmap.bmHeight; //数据
- pBInfo->biWidth = bitmap.bmWidth; //位图宽
- pBInfo->biXPelsPerMeter = 0;
- pBInfo->biYPelsPerMeter = 0;
- GetDIBits(memDC.m_hDC,bmp,0,pBInfo->biHeight,lpData,
- (BITMAPINFO*)pBInfo,DIB_RGB_COLORS);
- //<>//位图文件头
- BITMAPFILEHEADER bfh;
- bfh.bfReserved1 = bfh.bfReserved2 = 0;
- bfh.bfType = ((WORD)('M'<< 8)|'B');
- bfh.bfSize = 54+size;
- bfh.bfOffBits = 54;
复制代码- //<>保存位图
- CFile file;
- if(file.Open(sBitmapName,CFile::modeCreate|CFile::modeWrite))//创建位图文件
- {
- file.WriteHuge(&bfh,sizeof(BITMAPFILEHEADER)); //写入位图文件头
- file.WriteHuge(pBInfo,sizeof(BITMAPINFOHEADER));//写入文件头
- file.WriteHuge(lpData,size); //写入数据
- file.Close(); //关闭文件
- }
- }
复制代码我们来实现整个功能实现 过程
|