C#实现QQ截图功能及相关问题

对于QQ截图,肯定是早就有认识了,只是一直没有去认真观察这个操作的具体实现步骤。所以这里将自己的记忆中的步骤简单的写一下:

习惯性用QQ或者TIM的人,一般是使用Ctrl+Alt+A  快捷键(热键)快速实现截图。

  • Ctrl+Alt+A  进入截图模式
  • 鼠标左键点击
  • 鼠标拖动对截图去进行选取
  • 鼠标左键弹起
  • 双击截图区域  保存图片到剪贴板
  • 鼠标右键点击
  • 退出截图模式

因为考虑到截图模式的时候  一般只能显示一个窗体  所以就考虑使用单例模式  在ScreenBody窗体中实现以下代码

1:创建单例

private static ScreenBody screenBody=null;

2:私有化构造函数

private ScreenBody()
{
InitializeComponent();
}

3:创建静态方法

private static ScreenBody GetSingle()
{
if(screenBody==null)
{
screenBody=new ScreenBody();
}
return screenBody;
}

进一步讨论一下在Main窗体中的调用  Main中添加了一个button 命名为btnCutter

private void btnCutter_Click(object sender,EventArgs e)
{
 //新建一个和屏幕大小相同的图片img 也可以用BitMap
image img=new Bitmap(Screen.AllScreens[0].Bounds.Width,Screen.AllScreens[0].Bounds.Height);
//创建一个画板 让我们可以在画板上画图 大小和屏幕大小一样大
Graphics g=Graphics.FromImage(img);
 //将屏幕图片拷贝到空白图片img
g.CopyFromScreen(new Point(0,0),new Point(0,0),Screen.AllScreens[0].Bounds.Size);
//创建截图窗体
ScreenBody body=ScreenBody.GetSingle();
//指示窗体的背景图片为屏幕图片
body.BackGroundImage=img;
body.ShowDialog();

}

对于窗体ScreenBody

声明全局变量

private bool CatchStart;//判断鼠标是否按下
private bool CatchFinished;//判断矩形是否绘制完成
private Point DownPoint;//鼠标按下的点
private Image baseMap;//最基本的图片
private Rectangle CatchRectangle;

必须要实现的那几个事件

鼠标按下MouseDown

 private void ScreenBody_MouseDown(object sender, MouseEventArgs e)
  {
   //鼠标左键按下就是开始画图,也就是截图
   if (e.Button == MouseButtons.Left)
   {
    if (CatchStart == false)
    {
     CatchStart = true;
     //保存此时的坐标
     DownPoint = new Point(e.X, e.Y);
    }
   }
  }

鼠标移动 MouseMove

 private void ScreenBody_MouseMove(object sender, MouseEventArgs e)
  {
   //确保截图开始
   if (CatchStart)
   {
    //新建一个图片,让它与屏幕图片相同
    Bitmap copyBmp = (Bitmap)baseMap.Clone();
    //鼠标按下时的坐标
    Point newPoint = new Point(DownPoint.X, DownPoint.Y);

    //新建画板和画笔
    Graphics g = Graphics.FromImage(copyBmp);
    Pen p = new Pen(Color.Azure, 1);//画笔的颜色为azure 宽度为1

    //获取矩形的长度
    int width = Math.Abs(e.X - DownPoint.Y);
    int height = Math.Abs(e.Y - DownPoint.Y);

    if (e.X < DownPoint.X)
    {
     newPoint.X = e.X;

    }
    if (e.Y < DownPoint.Y)
    {
     newPoint.Y = e.Y;
    }

    CatchRectangle = new Rectangle(newPoint, new Size(width, height));
    g.DrawRectangle(p, CatchRectangle);

    //释放目前的画板
    g.Dispose();
    p.Dispose();

    //从当前窗体创建新的画板
    Graphics g1 = this.CreateGraphics();
    //将刚刚所画的图片画到截图窗体上去
    //为什么不直接在当前窗体画图呢???
    //如果直接解决将矩形画在窗体上,会造成图片抖动而且有多个矩形
    //这样实现也属于二次缓冲技术
    g1.DrawImage(copyBmp, new Point(0, 0));
    g1.Dispose();

    //释放拷贝图片 防止内存被大量的消耗
    copyBmp.Dispose();
   }

鼠标弹起 Mouseup

 /// <summary>
  /// 鼠标左键弹起事件
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void ScreenBody_MouseUp(object sender, MouseEventArgs e)
  {
   if (e.Button == MouseButtons.Left)
   {
    //如果截图已经开始,鼠标左键弹起设置截图完成
    if (CatchStart)
    {
     CatchStart = false;
     CatchFinished = true;
    }
   }
  }

鼠标双击

 private void ScreenBody_MouseDoubleClick(object sender, MouseEventArgs e)
  {
   if (e.Button==MouseButtons.Left&&CatchFinished)
   {
    //新建一个矩形大小相同的空白图片
    Bitmap CatcheBmp = new Bitmap(CatchRectangle.Width, CatchRectangle.Height);
    Graphics g = Graphics.FromImage(CatcheBmp); ;

    //把basemap中指定的部分按照指定大小画到空白图片上
    //CatchRectangle指定的baseMap中指定的部分
    //第二个参数指定绘制到空白图片的位置和大小
    //画完后CatchedBmp不再是空白图片,而是具有与截取的图片一样的内容
    g.DrawImage(baseMap, new Rectangle(0, 0, CatchRectangle.Width, CatchRectangle.Height));

    //将图片保存到剪切板中
    Clipboard.SetImage(CatcheBmp);
    g.Dispose();

    CatchFinished = false;
    this.BackgroundImage = baseMap;
    CatcheBmp.Dispose();
    this.DialogResult = DialogResult.OK;
    this.Close();
   }
  }

鼠标右键 退出截图

/// <summary>
  /// 鼠标右键点击结束截图
  /// </summary>
  /// <param name="sender"></param>
  /// <param name="e"></param>
  private void ScreenBody_MouseClick(object sender, MouseEventArgs e)
  {
   if (e.Button == MouseButtons.Right)
   {
    this.DialogResult = DialogResult.OK;
    this.Close();
   }
  }

最复杂的热键注册  自己也是去网上看的  Main窗体中

声明枚举

[FlagsAttribute]
 public enum KeyModifiers
 {
  None = 0,
  Alt = 1,
  Ctrl = 2,
  Shift = 4,
  WindowsKey = 8
 }

然后在类中编辑一下代码

 //在C#中引用命名空间System.Runtime.InteropServices;来加载非托管类user32.dll
  /*
  * RegisterHotKey函数原型及说明:
  * BOOL RegisterHotKey(
  * HWND hWnd,   // window to receive hot-key notification
  * int id,   // identifier of hot key
  * UINT fsModifiers, // key-modifier flags
  * UINT vk   // virtual-key code);
  * 参数 id为你自己定义的一个ID值
  * 对一个线程来讲其值必需在0x0000 - 0xBFFF范围之内,十进制为0~49151
  * 对DLL来讲其值必需在0xC000 - 0xFFFF 范围之内,十进制为49152~65535
  * 在同一进程内该值必须唯一参数 fsModifiers指明与热键联合使用按键
  * 可取值为:MOD_ALT MOD_CONTROL MOD_WIN MOD_SHIFT参数,或数字0为无,1为Alt,2为Control,4为Shift,8为Windows
  * vk指明热键的虚拟键码
  */
  [System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函数
  public static extern bool RegisterHotKey(
   IntPtr hWnd, // handle to window
   int id, // hot key identifier
   uint fsModifiers, // key-modifier options
   Keys vk // virtual-key code
  );

  [System.Runtime.InteropServices.DllImport("user32.dll")] //申明API函数
  public static extern bool UnregisterHotKey(
   IntPtr hWnd, // handle to window
   int id // hot key identifier
  );

再接着

 private void Form1_Load(object sender, EventArgs e)
  {
   uint ctrlHotKey = (uint)(KeyModifiers.Alt | KeyModifiers.Ctrl);
   // 注册热键为Alt+Ctrl+C, "100"为唯一标识热键
   RegisterHotKey(Handle, 100, ctrlHotKey, Keys.A);
  }
  //热键按下执行的方法
  private void GlobalKeyProcess()
  {
   this.WindowState = FormWindowState.Minimized;
   //窗口最小化需要一定的时间 使用线程
   Thread.Sleep(200);
   btnCutter.PerformClick();
  }

  protected override void WndProc(ref Message m)
  {
   //如果m.Msg的值为0x0312那么表示用户按下了热键
   const int WM_HOTKEY = 0x0312;
   switch (m.Msg)
   {
    case WM_HOTKEY:
     if (m.WParam.ToString()=="100")
     {
      GlobalKeyProcess();
     }
     break;
    default:
     break;
   }
   base.WndProc(ref m);
  }

  private void Form1_FormClosing(object sender, FormClosingEventArgs e)
  {
   // 卸载热键
   UnregisterHotKey(Handle, 100);
  }

热键的功能就能实现。但是我遇到了很多问题  首先是basemap  没有初始化值

这些问题  还有待解决!!!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2017-10-15

对指定的网页进行截图的效果 C#版

碰到一个项目,需要对指定的网页进行截图保存,晕死! 需求永远都是怪异的..... 解决是关键- 遂写了以下代码,快准狠!(因为赶时间!) 可以实现对指定的页面获取,按指定的大小生成缩略图,当然也可以1:1的产生图, 页面上的javascript 运行对截图貌似没任何影响,相当的正常,我个人都觉得很神奇. 首先对项目添加系统引用 System.Drawing; System.Drawing.Design; System.Windows.Forms; 获取指定网页并转换成图片的类: using Sy

C#实现类似qq的屏幕截图程序

因为近来想写个类似于远程桌面监控的程序,该程序中要用到屏幕捕捉.为实现该程序的一部分功能,做了个小DEMO.程序很简单,用到的技术也不多,只能实现类似qq的截图功能(方法虽然很笨)程序流程如下: 1.截取整个屏幕并保存2.新开一个全屏窗口,将保存的屏幕作为背景3.鼠标拖动改变截取范围,右键取消4.双击截取,保存在粘贴板,全屏窗口关闭 好了,下面的是代码部分 首先新建一个项目ScreenCutter(VS2005),将窗体名改为MainForm,再新建一个窗体ScreenBody.添加一个按钮bt

c# 控件截图的简单实例

首先选择保存图片的路径: 复制代码 代码如下: saveFileDialog1.Title = "保存";            saveFileDialog1.Filter = "*.png|*.png";            saveFileDialog1.RestoreDirectory = true;            if (saveFileDialog1.ShowDialog() == DialogResult.OK)            {  

C#实现网页截图功能

网页截图是很常见的实用功能,今天就为大家共享一个实现浏览器截图的代码,主要程序代码如下所示: private void Form_Load(object sender, EventArgs e) { //接收web url string colle = string.Empty; string url = string.Empty; //获取进程调用传入的命令 string[] args = Environment.GetCommandLineArgs(); string[] args = ne

解决C# 截取当前程序窗口指定位置截图的实现方法

要想完成这个功用,首先要了解一下在C#中如何调用API(利用程序交口)函数.固然在.Net框架中已经降求了很多类库,400电话,这些类库的功效也非常强盛,但关于一些Windows顶层编程来道,仍是要通过调用这些API函数才可以实现.一切API皆在"Kernel"."User "和"GDI"三个库中得以运转:其中"Kernel",他的库名为 "KERNEL32.DLL", 他重要用于发生取操做体系之间的联系关

C#实现通过ffmpeg从flv视频文件中截图的方法

本文实例讲述了C#实现通过ffmpeg从flv视频文件中截图的方法.分享给大家供大家参考.具体分析如下: 需要先下载ffmpeg,这是开源的,代码如下所示: 复制代码 代码如下: using System; using System.Configuration; public class PublicMethod:System.Web.UI.Page {     public PublicMethod()     {     }     //文件路径     public static stri

C#截图程序类似腾讯QQ截图实现代码

最近把以前制作的截图程序重新写了一下动了一个大手术 高质量仿照的TX的截图程序 先看几个效果图 拖动过程中显示当前鼠标下一小块的图像信息 尺寸.颜色信息的  注意 这里颜色是用的ARGB 本来截图的话RGB就够了 可是我把那个做成了控件 不仅截图可用 其他地方也可用作图像的选取 具体看代码就知道了 并且我还加了一个可以截图的同时把鼠标也捕获下来 现在看到的是我自己的截图程序 那个工具条啥的 是从TX的截图程序上面拔下来的 上面是几个工具条上的工具的三种粗细型号的展示 看到的蓝色的粗的刷笔 本来想

c#实现winform屏幕截图并保存的示例

复制代码 代码如下: using System.Runtime.InteropServices;using System.Drawing.Imaging;    [System.Runtime.InteropServices.DllImportAttribute("gdi32.dll")]    private static extern bool BitBlt( IntPtr hdcDest,   //   目标   DC的句柄                       int n

C#实现属于自己的QQ截图工具

下面就具体介绍下实现截图工具的实现思路. 为了让大家更清楚地知道如何去实现自己的截图工具,首先我来描述下截图的一个过程--我们使用QQ的截图工具和Windows 自带的截图工具都可以发现,当我们点击QQ窗体中的截图按钮时,此时我们将看到一个全屏图片,然后我们可以在其上截图,当鼠标左键按下时,即代表开始截图,并我们可以移动鼠标来改变截图的大小,鼠标弹起时即代表结束截图,此时我们可以双击矩形区域完全截图,并且可以通过粘贴操作把截取的图片粘贴到聊天窗口的发送区,鼠标右键点击则是退出截图.这样我们截图的

解决C#全屏幕截图的实现方法

今天一位同事想写一个全屏幕截图的代码.当然要实现的第一步是能够获取整个屏幕的位图,记得Win32 API的CreateDC, BitBlt等函数可以使用.于是上网查了下,果然屏幕截图用这些函数.但winform已经可以把API都忘记了,所以得寻找一个无Win32 API的实现方式.综合了网上的实现,以及自己的一些设计,实现思路如下:1. 开始截图时,创建一个与屏幕大小一样的位图,然后用Graphics.CopyFromScreen()把屏幕位图拷贝到该位图上.这是很关键的一步,这样所有的操作就都

php使用CutyCapt实现网页截图保存的方法

本文实例讲述了php使用CutyCapt实现网页截图保存的方法.分享给大家供大家参考,具体如下: 网页截图这个功能大家可能用到最多的就是QQ截图,或利用asp.net来实现截图,其实我们也可以直接使用php来网页截图,这里就来给大家介绍php利用CutyCapt实现网页截图的流程: CutyCapt下载地址:http://sourceforge.net/projects/cutycapt/files/cutycapt/ windows CutyCapt不需要安装,直接保存到你的电脑中即可,然后p

解决IOS开发空字符串的方法

解决IOS开发空字符串的方法 实例代码: -(Boolean) isEmptyOrNull:(NSString *) str { if (!str) { // null object return true; }else if(str == Null){ return true; }else if([str isKindOfClass:[NSNull class]]){ return true; }else { NSString *trimedString = [str stringByTrim

Java模拟QQ桌面截图功能实现方法

本文实例讲述了Java模拟QQ桌面截图功能实现方法.分享给大家供大家参考.具体如下: QQ的桌面截图功能非常方便,去年曾用Java模拟过一个,现整理出来. 本方法首先需要抓到屏幕的整个图象,将图象显示在一个JFrame中,再将JFrame全屏显示,这样就模拟出了一个桌面,Java也就可以获得鼠标的作用区域从而实现桌面中的小范围截屏. import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import

5种解决Java独占写文件的方法

本文实例讲解了5种解决Java独占写文件的方法,包含自己的一些理解,如若有不妥的地方欢迎大家提出. 方案1:利用RandomAccessFile的文件操作选项s,s即表示同步锁方式写 RandomAccessFile file = new RandomAccessFile(file, "rws"); 方案2:利用FileChannel的文件锁 File file = new File("test.txt"); FileInputStream fis = new Fi

javascript解决IE6下hover问题的方法

有时候我们想在非a标签上加hover元素 但是我们都知道IE6下不支持XX:hover,所以我们现在可以用js实现掉:代码如下 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999

Python实现对PPT文件进行截图操作的方法

本文实例讲述了Python实现对PPT文件进行截图操作的方法.分享给大家供大家参考.具体分析如下: 下面的代码可以为powerpoint文件ppt进行截图,可以指定要截取的幻灯片页面,需要本机安装了powerpoint,可以指定截图的大小分辨率 import os import comtypes.client def export_presentation(path_to_ppt, path_to_folder): if not (os.path.isfile(path_to_ppt) and

php使用ftp远程上传文件类(完美解决主从文件同步问题的方法)

php使用ftp实现文件上传代码片段: <?php /** * ftp上传文件类 */ class Ftp { /** * 测试服务器 * * @var array */ private $testServer = array( 'host' => 'ip', 'port' => 21, 'user' => 'userName', 'pwd' => 'password' ); /** * 打开并登录服务器 * * @param string $flag 服务器标识test *

Ajax解决多余刷新的两种方法(总结)

控制器Servlet则提供了简单的改变: 对于Ajax系统而言,服务器响应无须是整个页面内容,可以仅是 必需的数据,控制器不能将数据请求转发到jsp页面. 此时控制器有两个选择: 1.直接生成简单的响应数据. 在这种模式下,Servlet直接通过response获取页面输出流,通过 输出流生成字符响应. package pers.zkr.chat.web; import java.io.IOException; import java.io.PrintWriter; import javax.s

微信小程序 解决swiper不显示图片的方法

微信小程序 解决swiper不显示图片的方法 1.我说的swiper不显示图片是只有一个swiper的框,但不显示设置好的图片. 第一个要确定的是图片路径设置的正不正确,确定路径没有设置错,还有一个可能的原因就是,放swiper的这个页面(也就是这个wxml文件)没有在app.json里面的pages进行注册 确决的方法是: 找到项目下的app.json文件 在app.json的配置文件下的pages进行页面注册,像下面图片这样 小程序的文档也写了"小程序中新增/减少页面,都需要对 pages