当前位置: 首页 > 编程笔记 >

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

西门正平
2023-03-14
本文向大家介绍C#实现QQ截图功能及相关问题,包括了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  没有初始化值

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

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

 类似资料:
  • 本文向大家介绍C# 实现QQ式截图功能实例代码,包括了C# 实现QQ式截图功能实例代码的使用技巧和注意事项,需要的朋友参考一下 这个功能一共有两部分组成,第一部分是窗体代码,另外的一部分是一个辅助方法。直接贴出代码,以供大家参考: 第二部分是辅助方法类  实现的效果如下:  以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

  • 本文向大家介绍Java模拟QQ桌面截图功能实现方法,包括了Java模拟QQ桌面截图功能实现方法的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了Java模拟QQ桌面截图功能实现方法。分享给大家供大家参考。具体如下: QQ的桌面截图功能非常方便,去年曾用Java模拟过一个,现整理出来。 本方法首先需要抓到屏幕的整个图象,将图象显示在一个JFrame中,再将JFrame全屏显示,这样就模拟出了一

  • 本文向大家介绍VBS实现截图功能,包括了VBS实现截图功能的使用技巧和注意事项,需要的朋友参考一下 百度说,VBS很难截图,倒是有个利用第三方软件的方法,调用该软件,然后该软件会自动截图。 但这样,违背了用VBS的初衷。 用VBS就是因为它方便快捷。要是用第三方软件的话,干脆我们直接用VB写一个好了。 那么...只好调用Excel用VBA去做了。 有什么更好的方法吗? 在度娘上翻了很久,没有什么好

  • 如何获取QQ登录的unionId? 在AuthConfig中设备unionId为true AuthRequest authRequest = new AuthQqRequest(AuthConfig.builder() .clientId("clientId") .clientSecret("clientSecret") .redirectUri("

  • 本文向大家介绍Android实现拍照截图功能,包括了Android实现拍照截图功能的使用技巧和注意事项,需要的朋友参考一下 本文将向大家展示如何拍照截图。 先看看效果图: 拍照截图有点儿特殊,要知道,现在的Android智能手机的摄像头都是几百万的像素,拍出来的图片都是非常大的。因此,我们不能像对待相册截图一样使用Bitmap小图,无论大图小图都统一使用Uri进行操作。 一、首先准备好需要使用到的

  • 本文向大家介绍Selenium Webdriver实现截图功能的示例,包括了Selenium Webdriver实现截图功能的示例的使用技巧和注意事项,需要的朋友参考一下 前几天在研究中自动化的时候突发奇想,想着能不能来截个图,以便之后查看,实现的方法其实也不难,毕竟selenium webdriver已经提供了截图额功能,TakesScreenshot接口函数(英文意思就是获取屏幕截图takes