C++开发截屏小程序功能

C++开发截屏小程序,Win32程序,可以显示截屏区域并保存。

上次的流星雨屏幕程序就简单涉及到GDI绘图了,这次简单介绍几个API函数,涉及到GDI的。

GetDC,获取当前创建的窗口的设备环境。
CreateDC,获取当前屏幕的设备环境。
CreateCompatibleDC,创建一个兼容性的设备环境(相当于一个虚拟的设备环境)
BitBlt,这个函数,相当于拷贝,将一个环境的设备内容拷贝到另一个设备中。
CreateCompatibleBitmap,创建一块画布,将其放在兼容性的DC里面,这样就可以在里面画图了,当然还要放入画笔和画刷这些。

介绍完这些函数之后,那么设计思路就来了:

1.首先当然还是定义并创建窗口,还有消息循环。

ATOM MyRegisterClass(HINSTANCE hInstance)
{
 WNDCLASSEX wcex;

 wcex.cbSize = sizeof(WNDCLASSEX);
 wcex.style = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
 wcex.lpfnWndProc = WndProc;
 wcex.cbClsExtra = 0;
 wcex.cbWndExtra = 0;
 wcex.hInstance = hInstance;
 wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDC_CAPTURESCREEN));
 wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
 wcex.hbrBackground = (HBRUSH)(BLACK_BRUSH);
 wcex.lpszMenuName = NULL;
 wcex.lpszClassName = szWindowClass;
 wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

 return RegisterClassEx(&wcex);
}

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{

 hInst = hInstance; // 将实例句柄存储在全局变量中
 //创建自己的窗口
 hWnd = CreateWindow(szWindowClass, szTitle, WS_POPUP,
 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

 if (!hWnd)
 {
 return FALSE;
 }
 //显示和更新窗口
 ShowWindow(hWnd, SW_MAXIMIZE);
 UpdateWindow(hWnd);

 return TRUE;
}

int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
 _In_opt_ HINSTANCE hPrevInstance,
 _In_ LPTSTR lpCmdLine,
 _In_ int  nCmdShow)
{
 //playsound只能播放wav格式,而mcisendstring可以播放任意格式的。

 //PlaySound("yixi.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);
 mciSendString("open ./abc.mp3 alias bk",
 0, 0, 0);
 mciSendString("play bk repeat", 0, 0, 0);

 UNREFERENCED_PARAMETER(hPrevInstance);
 UNREFERENCED_PARAMETER(lpCmdLine);

 // TODO: 在此放置代码。
 MSG msg;
 HACCEL hAccelTable;

 // 初始化全局字符串
 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
 LoadString(hInstance, IDC_CAPTURESCREEN, szWindowClass, MAX_LOADSTRING);

 MyRegisterClass(hInstance); //注册类

 // 执行应用程序初始化:
 if (!InitInstance(hInstance, nCmdShow)) //初始化窗口
 {

 return FALSE;
 }

 hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_CAPTURESCREEN));

 // 主消息循环:
 while (GetMessage(&msg, NULL, 0, 0))
 {
 if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
 {
 TranslateMessage(&msg);
 DispatchMessage(&msg);
 }
 }
 return (int)msg.wParam;
}

2.之后获取当前屏幕的设备环境,

3.然后将它保存到兼容性的DC中,这就相当于将当前屏幕图片放到一个缓冲区中。在WM_CREATE消息里面做这个动作。

void ScreenDisplay()
{
 HDC disDc = ::CreateDC("DISPLAY", NULL, NULL, NULL);
 g_memDC = ::CreateCompatibleDC(disDc);
 g_ScreenW = GetDeviceCaps(disDc, HORZRES);
 g_ScreenH = GetDeviceCaps(disDc, VERTRES);
 HBITMAP hbitmap = CreateCompatibleBitmap(disDc, g_ScreenW, g_ScreenH);
 SelectObject(g_memDC, hbitmap);
 BitBlt(g_memDC, 0, 0, g_ScreenW, g_ScreenH, disDc, 0, 0, SRCCOPY);
}

4.接着再将它放到我们创建的窗口中,这时就会看到整个桌面就不动了,就呈现的是一张图片,

5.之后我们就可以在这张图片上绘制我们想截取的区域。

6.呈现的是静止的图片,如果绘制之后,需要更新,这就用到一个函数InvalidateRgn,会无效选定的区域,这样会触发消息WM_PAINT,所以在这个消息里面将重新绘制图形,然后显示即可。

case WM_PAINT:
 hdc = BeginPaint(hWnd, &ps);
 // TODO: 在此添加任意绘图代码...
 SelectObject(hdc, hpen);
 SelectObject(hdc, hBrush);
 BitBlt(hdc, 0, 0, g_ScreenW, g_ScreenH, g_memDC, 0, 0, SRCCOPY);
 Rectangle(hdc, rect.left, rect.top, rect.right, rect.bottom);
 EndPaint(hWnd, &ps);
break;

接下来就是绘制想要区域的操作,需要用到的几个鼠标的消息函数,鼠标按下,鼠标弹起,鼠标移动,鼠标双击。
那么思路来了:

鼠标按下,确定左上角的点,然后鼠标移动绘制矩形区域,然后鼠标弹起,确定右下角的点,这样矩形区域绘制完成。

case WM_LBUTTONDOWN:
{
  if (!Iselect)
  {
   POINT pt;
   GetCursorPos(&pt);
   rect.left = pt.x;
   rect.top = pt.y;
   rect.right = pt.x;
   rect.bottom = pt.x;
   InvalidateRgn(hWnd, 0, FALSE);
   Isdowmn = TRUE;
  }

}
 break;
case WM_LBUTTONUP:
{
  if (Isdowmn == TRUE&&!Iselect)
  {
  POINT pt;
  GetCursorPos(&pt);
  rect.right = pt.x;
  rect.bottom = pt.y;
  InvalidateRgn(hWnd, 0, FALSE);
  Isdowmn = FALSE;
  Iselect = TRUE;
  }
}
 break;
case WM_MOUSEMOVE:
{
  if (Isdowmn == TRUE&&!Iselect)
  {
  POINT pt;
  GetCursorPos(&pt);
  rect.right = pt.x;
  rect.bottom = pt.y;
  InvalidateRgn(hWnd, 0, FALSE);
  }
}
 break;

最后鼠标双击将截取到的图片保存剪切板,这样就完成了屏幕截取。

case WM_LBUTTONDBLCLK:
 if (Iselect == TRUE)
 {
 int iNum = MessageBox(hWnd, "截图成功!", "张一西", MB_OKCANCEL | MB_ICONINFORMATION);
 if (iNum == 1)
 {
  CopyToCliboard();
  Iselect = FALSE;
  PostQuitMessage(0);
 }
 else
 {
  Iselect = FALSE;
 }
 }
 break;
void CopyToCliboard()
{
 HDC hScreenDC = ::CreateDC("DISPLAY", 0, 0, 0);
 HDC memDC = ::CreateCompatibleDC(hScreenDC);
 int Width = rect.right - rect.left-2;
 int Height = rect.bottom - rect.top-2;
 HBITMAP hBmap = CreateCompatibleBitmap(hScreenDC, Width, Height);
 HBITMAP hOldBmap = (HBITMAP)SelectObject(memDC, hBmap);
 BitBlt(memDC, 0, 0, Width, Height, hScreenDC, rect.left+1, rect.top+1, SRCCOPY);
 HBITMAP hNewBmap = (HBITMAP)SelectObject(memDC, hOldBmap);
 if (OpenClipboard(0))      //打开粘贴板
 {
 EmptyClipboard();      //清空粘贴板
 SetClipboardData(CF_BITMAP, hNewBmap); //把图片放入粘贴板
 CloseClipboard();      //关闭粘贴板
 }
}

代码地址:http://xiazai.jb51.net/202004/yuanma/CaptureScreen_jb51.rar

总结

到此这篇关于C++开发截屏小程序的文章就介绍到这了,更多相关C++开发截屏小程序内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • C++有限状态机实现计算器小程序

    本文介绍利用有限状态机原理开发计算器小程序的过程. 实现的功能 支持整数.小数输入 支持+ - * / 四则运算 CE 清除当前操作数 C 清除所有.回到初始状态 回显操作数和结果 HSM状态图 计算器可以分为七种状态:Start.Operand_1.Negate_1.Operator.Operand_2.Negate_2.Error.其中Start.Operand_1.Operand_1状态又分了几种子状态. 下面简要的介绍下状态状态转换的过程: 启动软件,进入Start状态 当用户点击1-9

  • C++实现五子棋小程序

    这是一个用C++写的五子棋的小程序,关于A若是占据了已经下了的位置处理的不好.改动 hight,与width ,与q[][] 可以将棋盘扩大. #include<iostream> #include<vector> using namespace std; class qipan { public: qipan() {} ~qipan() {}; //向上下左右,斜的方向 char left(int x, int y) {//检查是否合适 if (x >= 1 &&a

  • C++开发截屏小程序功能

    C++开发截屏小程序,Win32程序,可以显示截屏区域并保存. 上次的流星雨屏幕程序就简单涉及到GDI绘图了,这次简单介绍几个API函数,涉及到GDI的. GetDC,获取当前创建的窗口的设备环境. CreateDC,获取当前屏幕的设备环境. CreateCompatibleDC,创建一个兼容性的设备环境(相当于一个虚拟的设备环境) BitBlt,这个函数,相当于拷贝,将一个环境的设备内容拷贝到另一个设备中. CreateCompatibleBitmap,创建一块画布,将其放在兼容性的DC里面,

  • Android实现的截屏小程序示例

    本文实例讲述了Android实现的截屏小程序.分享给大家供大家参考,具体如下: 先看截图,不过这个截屏还不够完整,头上的statusbar没有,呈黑色. 多按了几次,就成这样了,呵呵. package com.test; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Bitmap.Config; import

  • C#开发之微信小程序发送模板消息功能

    步骤一:获取模板ID 有两个方法可以获取模版ID 通过模版消息管理接口获取模版ID 在微信公众平台手动配置获取模版ID 步骤二:页面的 <form/> 组件,属性report-submit为true时,可以声明为需发模板消息,此时点击按钮提交表单可以获取formId,用于发送模板消息.或者当用户完成支付行为,可以获取prepay_id用于发送模板消息. 步骤三:调用接口下发模板消息 今天重要的说第三步怎么实现,前面的步骤比较简单就略过. ----------------------------

  • 微信小程序功能之全屏滚动效果的实现代码

    想做一个全屏滚动的效果,于是在网上找了一个差不多的例子,但是觉得有些地方不是很好,于是改进了一下: 先给大家展示下效果图,感觉不错,请参考实例代码. 代码: wxml: <!-- 第一页 -- > <view id='hook1' class="section section01 {{scrollindex==0?'active':''}}" style='background:red' bindtouchstart="scrollTouchStart&qu

  • Python开发桌面小程序功能

    当使用桌面应用程序的时候,有没有那么一瞬间,想学习一下桌面应用程序开发?建议此次课程大家稍作了解不要浪费太多时间,因为没有哪家公司会招聘以为Python程序员开发桌面程序吧? 开发环境: Python 3.6 Pycharm 代码 界面设置 导入模块 import tkinter as tk 实例化一个窗体对象 root = tk.Tk() 标题 root.title('计算器') 大小以及出现的位置 root.geometry("295x280+150+150") 透明度 root.

  • 使用DeviceOne实现微信小程序功能

    微信小程序即将推出,还没推出就火的不行了.基于微信这个巨大平台,小程序必然能有巨大成功.不过它并不能完全取代App,该开发App还得开发.如果我们自己想实现一个基于自己的APP包含类似微信的小程序功能,该如何实现了?我们先来看看小程序的技术特点. 小程序的特点 1. 跨平台,微信就像JRE,在不同操作系统上都有实现,所以微信上的小程序就像运行在JRE上的java程序,从而实现跨平台.另外解决了多平台多机型的适配问题. 2. 体验好,webview加载html是最容易的跨平台方式,但是在手机上的体

  • 微信小程序项目总结之记账小程序功能的实现(包括后端)

    一.小程序部分 这是理财系统的前端,江苏海洋大学微信小程序比赛,最后获得了一等奖 GitHub:https://github.com/GeorgeLeoo/finance 1. 项目描述 (1). 此项目为记账小程序 (2). 包括账单.图表.搜索.用户等多个子模块 (3). 使用微信小程序技术 (4). 采用模块化.组件化.工程化等模式开发 2. 项目功能界面 在 1.0.2版本中删除了扇形图 3. 项目目录 * pages:页面 * components:组件 * utils:工具类 |--

  • 用云开发Cloudbase实现小程序多图片内容安全监测的代码详解

    前言 相比于文本的安全检测,图片的安全检测要稍微略复杂一些,当您读完本篇,将get到 图片安全检测的应用场景 解决图片的安全校验的方式 使用云调用方式对图片进行检测 如何对上传图片大小进行限制 如何解决多图上传覆盖问题 示例效果 当用户上传敏感违规图片时,禁止用户上传发布,并且做出相对应的用户友好提示 应用场景 通常,在校验一张图片是否含有违法违规内容相比于文本安全的校验,同样重要,有如下应用 图片智能鉴黄:涉及拍照的工具类应用(如美拍,识图类应用)用户拍照上传检测:电商类商品上架图片检测:媒体

  • 如何使用python写截屏小工具

    前言 今天我看了一下自己的文件夹,发现了自己写了许多似乎很无聊的代码.于是乎,一个想法油然而生:"生活已经很无聊了,不如再无聊一点叭". 说干就干,那就开一个专题,我们称之为kimol君的无聊小发明. 妙-啊~~~ 今天要做的东西,就是用python写一个截屏工具.想必大家平时截屏的时候很多都是用的微信的ALT+A或者是WINDOWS自带的截屏软件.作为技术宅的我,怎么总是用别人的东西呢? 看我的,上图: 效果还阔以,好歹这个小猫咪截出来也是有模有样的~ 一.技术实现 1. 相关库 在

  • 微信小程序 功能函数小结(手机号验证*、密码验证*、获取验证码*)

    下面一小段代码给大家介绍微信小程序 功能函数 密码验证*,具体代码如下所示: //登录输入密码 userPasswordInput: function (e) { var that = this; this.setData({ userPassword: e.detail.value }) // console.log(e.detail.value.length) // console.log(e.detail.value); var value = e.detail.value var str

随机推荐