C#截图程序类似腾讯QQ截图实现代码
发布时间:2023-05-07 04:01:01
最近把以前制作的截图程序重新写了一下动了一个大手术 高质量仿照的TX的截图程序
先看几个效果图
拖动过程中显示当前鼠标下一小块的图像信息 尺寸、颜色信息的 注意 这里颜色是用的ARGB 本来截图的话RGB就够了 可是我把那个做成了控件 不仅截图可用 其他地方也可用作图像的选取 具体看代码就知道了
并且我还加了一个可以截图的同时把鼠标也捕获下来 现在看到的是我自己的截图程序 那个工具条啥的 是从TX的截图程序上面拔下来的
上面是几个工具条上的工具的三种粗细型号的展示 看到的蓝色的粗的刷笔 本来想的不应该是这个效果的 应该是颜色填充均匀的那种 但是仔细一想代码中用的是DrawLine(P,PointLast,PointCurrent);这种方式来画的自由线条 如果是一个像素的没什么问题 粗点的就是上面看到的那种效果 也就是由许多小线段拼接出来的自由线条而每个线段两端都是方的所以线段与线段之间的接缝处 可能就有问题 反正就那个意思 你懂得 不过再仔细一想虽然不是想要的效果但却意外的出现了 蜡笔的效果 果断也就不改了这样也不错
同样的具有自动捕获窗体边框的功能
使用也非常简单 这个截图的功能写到了一个dll中 引用名称空间 然后FrmCapture 就是截图的了给了他几个属性 也就是上面看到的
同时在拖动过程中可以通过键盘 wasd 四个键来控制鼠标精确移动
操作方式也和TX的一样
右键鼠标 如果有选择的区域则取消选择的区域 没有则退出截图
双击将选择的区域复制到剪切板
整个思路也和前面几篇文章中提到的一样 只是在代码层面上动了一个大手术 因为原来写的主要是凸显那个自动捕获窗体的功能
//根据鼠标位置找寻窗体平绘制边框
private void FoundAndDrawWindowRect() {
Win32.LPPOINT pt = new Win32.LPPOINT();
pt.X = MousePosition.X; pt.Y = MousePosition.Y;
IntPtr hWnd = Win32.ChildWindowFromPointEx(Win32.GetDesktopWindow(), pt,
Win32.CWP_SKIPINVISIBL | Win32.CWP_SKIPDISABLED);
if (hWnd != IntPtr.Zero) {
IntPtr hTemp = hWnd;
while (true) { //循环的根据坐标向内部找寻子窗体 直到无法找到位置
Win32.ScreenToClient(hTemp, out pt);
hTemp = Win32.ChildWindowFromPointEx(hTemp, pt, Win32.CWP_All);
if (hTemp == IntPtr.Zero || hTemp == hWnd)
break;
hWnd = hTemp;
pt.X = MousePosition.X; pt.Y = MousePosition.Y; //坐标还原为屏幕坐标
}
Win32.LPRECT rect = new Win32.LPRECT();
Win32.GetWindowRect(hWnd, out rect);
imageProcessBox1.SetSelectRect(
new Rectangle(rect.Left, rect.Top,
rect.Right - rect.Left, rect.Bottom - rect.Top));
}
}
同前几篇文章一样是通过禁用自身窗体然后通过ChildWindowFromPointEx函数来根据鼠标位置 获得鼠标下面的窗体 因为在获取的时候 鼠标下面是截图程序的一个窗体 所以在找寻窗体的时候得把自己忽略掉 而ChildWindowFromPointEx在查找过程中可以忽略禁用的窗体 所以讲自己禁用就到到目的了 然后通过Hook来监视鼠标的行为 来恢复禁用的窗体
private void m_MHook_MHookEvent(object sender, MHookEventArgs e) {
........
//鼠标点下恢复窗体禁用
if (e.MButton == ButtonStatus.LeftDown || e.MButton == ButtonStatus.RightDown) {
this.Enabled = true;
imageProcessBox1.IsDrawOperationDot = true;
}
........
}
还有一点 就只捕获鼠标的时候
//获取桌面图像
private Bitmap GetScreen() {
Bitmap bmp = new Bitmap(Screen.PrimaryScreen.Bounds.Width,
Screen.PrimaryScreen.Bounds.Height);
if (this.isCaptureCursor) { //是否捕获鼠标
//如果直接将捕获当的鼠标画在bmp上 光标不会反色 指针边框也很浓 也就是说
//尽管bmp上绘制了图像 绘制鼠标的时候还是以黑色作为鼠标的背景 然后在将混合好的鼠标绘制到图像 会很别扭
//所以 干脆直接在桌面把鼠标绘制出来再截取桌面
using (Graphics g = Graphics.FromHwnd(IntPtr.Zero)) { //传入0默认就是桌面 Win32.GetDesktopWindow()也可以
Win32.PCURSORINFO pci;
pci.cbSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(Win32.PCURSORINFO));
Win32.GetCursorInfo(out pci);
if (pci.hCursor != IntPtr.Zero) {
Cursor cur = new Cursor(pci.hCursor);
g.CopyFromScreen(0, 0, 0, 0, bmp.Size); //在桌面绘制鼠标前 先在桌面绘制一下当前的桌面图像
//如果不绘制当前桌面 那么cur.Draw的时候会是用历史桌面的快照 进行鼠标的混合 那么到时候混出现底色(测试中就是这样的)
cur.Draw(g, new Rectangle((Point)((Size)MousePosition - (Size)cur.HotSpot), cur.Size));
}
}
}
//做完以上操作 才开始捕获桌面图像
using (Graphics g = Graphics.FromImage(bmp)) {
g.CopyFromScreen(0, 0, 0, 0, bmp.Size);
}
return bmp;
}
我总感觉上面的方式很别扭 可是目前我也就只能通过这种方式去捕获鼠标了
有兴趣的就自己改造吧 导入那个dll自己想咋改造就咋改造


猜你喜欢
- 前言本文主要给大家介绍了关于Android模仿美团顶部滑动菜单的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧。先
- 前言上一篇文章自定义了一个左滑删除的RecyclerView,把view事件分发三个函数dispatchTouchEvent、onInter
- String:字符串类型1、构造函数。String() :构造一个空字符串对象。String(byte[] bytes) :通过byte数组
- 本文主要介绍了java中LinkedList使用迭代器优化移除批量元素原理,分享给大家,具体如下:public interface Iter
- JAVA枚举,比你想象中还要有用!我经常发现自己在Java中使用枚举来表示某个对象的一组潜在值。在编译时确定类型可以具有什么值的能力是一种强
- 进程同步用来实现程序并发执行时候的可再现性。一.进程同步及异步的概念1.进程同步:就是在发出一个功能调用时,在没有得到结果之前,该调用就不返
- 一、简介Mutex的突出特点是可以跨应用程序域边界对资源进行独占访问,即可以用于同步不同进程中的线程,这种功能当然这是以牺牲更多的系统资源为
- 本文实例讲述了C#中DataGridView的样式。分享给大家供大家参考。具体如下:1、设置grid交替行颜色public static v
- 本文实例为大家分享了android实现选项卡功能,通过计算偏移量,设置tetxview和imageView的对应值,一些color的值读者自
- 本文实例为大家分享了C#线程中弹窗的制作代码,供大家参考,具体内容如下首先建立一个ShowFrom窗体,窗体中放入两个按钮分别为确定和取消分
- Android系统里面有四种类型的菜单:options menu(选项菜单),context menu(上下文菜单),sub m
- 做了微信支付,下载了Demo,发现和之前有所改动,v3.0的版本,也许有的朋友还在摸索,这里我已经成功支付,话不多说,直接进入主题:一、首先
- 在研究性能的时候,完全可以使用Stopwatch计时器计算一项技术的效率。但是有时想知道某想技术的性能的时候,又常常想不起可以运用Stopw
- 由于工作和之前学习的原因,我需要同时使用Java和C#两门语言。这几年,我也一直在使用J2EE平台和.NET平台做开发。说起C#和Java这
- 本文实例讲述了C#实现顺序表(线性表)的方法。分享给大家供大家参考,具体如下:基本思想是使用数组作为盛放元素的容器,数组一开始的大小要实现确
- @Transactional 内部调用例子 🌰在 Spring 的 AOP 代理下,只有目标方法由外部调用,目标方法才由 Spring 生成
- 模块调用之后,记录模块的相关日志,看似简单,其实暗藏玄机。1.简述模块日志的实现方式大致有三种:AOP + 自定义注解实现输出指定格式日志
- Web控件DropDownList和WinForm控件ComboBox机制不一样。ComboBox没有对应的ListItem需要自己写一个:
- 一、项目简述(+需求文档+PPT)功能: 主页显示热销商品;所有商品展示,可进行商品搜索;点 击商品进入商品详情页,显示库存,具有立即购买和
- 首先给一个简单的Builder设计模式的例子:主实现类代码如下:/** * 实体类 包含一个静态内部类 Builder */public c