C# WINFORM 屏幕绘画+透明窗体+鼠标穿透

发布时间 2023-08-15 14:46:55作者: 多见多闻

通过长时间研究终于找到关于在C# WINFORM下制作真正的透明窗体在系统桌面上画图的完美解决方案;

可以避免解决与其网上其它画图工具的很多不足,网上实现思路如下几种:

1、使用API透明窗体+底层鼠标钩子可以实现,但要重新实现鼠标的监听操作,实再太麻烦了;

2、使用第三方透明窗体控件(如LayeredSkin等),也可成功但需通过UpdateLayeredWindow实现,而且记录轨迹多层画布也会出现不透明无法透视到系统桌面问题;

3、大部分画图工具都采用抓假桌面背景图进行画图,不能完全时时看到桌面其它程序运行的界面;

4、直接在透明窗体上画,使用TransparencyKey会出现透明窗体鼠标穿透现像,而使用Opacity则字迹也会被透明看不清;

5、使用Paint重绘窗体画布背色为Color.FromArgb(1, 255, 255, 255)强制透明在XP系统下可以用,但在WIN7以上系统还是会穿透,因为FrameWork底层透明操作都是使用API的SetLayeredWindowAttributes参数实现的。

以上方式我都试过,通过总结教训取长补短最终简单有效解决方案思路如下:

我的解决方案为两层透明窗体重叠,一层透明窗体showForm显示图像(TransparencyKey因为鼠标穿透,但字迹显示清楚正常),用另一层窗体drawForm做绘图轨迹(Opacity鼠标不穿透,可以不必显示图像),两个都为透明窗体,Opacity透明绘图层的轨迹在透明窗体TransparencyKey图画层上显示,直接上代码:

drawForm.cs只新建窗体drawForm即可,可以不用写其它代码,功能都在showForm中完成;

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace draw
{
    public partial class showForm : Form
    {
        private drawForm df;//透明窗体不穿透鼠标
        private bool startdraw = false;//是否开始画图
        private Graphics gs;//画版
        private Pen pen;//画笔
        private Point startpt;//画图起点
        public showForm()
        {
            InitializeComponent();
            WindowState = FormWindowState.Maximized;//本窗体最大化
            TransparencyKey = BackColor;//背景透明(鼠标穿透)
            DoubleBuffered = true;//双缓存处理

            df = new drawForm();//不穿透鼠标透明窗体
            //设置不穿透鼠标透明窗体画板鼠标事件为本显示画图窗体鼠标事件进行同步
            df.MouseDown += showForm_MouseDown;//鼠标按下事件
            df.MouseMove += showForm_MouseMove;//鼠标移动事件
            df.MouseUp += showForm_MouseUp;//鼠标弹起事件

            //不穿透鼠标透明窗体参数设置如下
            df.WindowState = FormWindowState.Maximized;//最大化
            df.Opacity = 0.1;//背景透明不穿透鼠标
            df.TopMost = true;//让不穿透鼠标透明窗体画板为最上层
            df.DoubleBuffered = true;//双缓存处理
            df.Show();//显示
            gs = CreateGraphics();//创建窗体画板
            pen = new Pen(Color.Black, 3f);//画笔
        }

        private void showForm_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                startdraw = true;//开始画图
                startpt = e.Location;
            }
        }

        private void showForm_MouseMove(object sender, MouseEventArgs e)
        {
            if (startdraw)
            {
                gs.DrawLine(pen, startpt, e.Location);
                startpt = e.Location;
            }
        }

        private void showForm_MouseUp(object sender, MouseEventArgs e)
        {
            startdraw = false;//结束画图
        }
    }
}

下载地址:http://download.csdn.net/detail/litongshun/9108699