C#鼠标穿透功能(WinForm)

这篇具有很好参考价值的文章主要介绍了C#鼠标穿透功能(WinForm)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C#鼠标穿透功能(WinForm)

在WinForm开发时,会用到这样一个场景,给屏幕增加水印Logo,但不影响画面的操作。这里就会用到鼠标穿透功能。

User32.Dll函数

要想实现鼠标穿透功能,需要用到User32.Dll的几个函数:SetWindowLong、GetWindowLong、SetLayeredWindowAttributes。

SetWindowLong

语法规则

LONG SetWindowLongA(
  [in] HWND hWnd,
  [in] int  nIndex,
  [in] LONG dwNewLong
);

描述:更改指定窗口的属性。 函数还将指定偏移量的 32 位 (长) 值设置为额外的窗口内存。

参数 类型 描述
[in] hWnd HWND 窗口的句柄,以及窗口所属类的间接句柄。
[in] nIndex int 要设置的值的从零开始的偏移量。 有效值在零到额外窗口内存的字节数之间,减去整数的大小。 若要设置任何其他值,请指定以下值之一。
[in]dwNewLong LONG 替换值

其中nIndex的值含义如下,常用到值为GWL_EXSTYLE=(-20)和GWL_STYLE=(-16)

含义
GWL_EXSTYLE-20 设置新的 扩展窗口样式
GWL_HINSTANCE-6 设置新的应用程序实例句柄。
GWL_ID-12 设置子窗口的新标识符。 该窗口不能是顶级窗口。
GWL_STYLE-16 设置新 窗口样式
GWL_USERDATA-21 设置与窗口关联的用户数据。 此数据供创建窗口的应用程序使用。 其值最初为零。
GWL_WNDPROC-4 为窗口过程设置新地址。如果窗口不属于调用线程所在的进程,则无法更改此属性。

返回值:Long

如果函数成功,则返回值是指定 32 位整数的上一个值。

如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。

如果指定的 32 位整数的上一个值为零,并且函数成功,则返回值为零,但函数不会清除最后一个错误信息。 这使得很难确定成功或失败。 若要处理此问题,在调用 SetWindowLong 之前,应通过调用 SetLastError 0 来清除最后一个错误信息。 然后,函数失败将由返回值零和 GetLastError 结果指示为非零。

目前基本不做判断

GetWindowLong

语法规则

LONG GetWindowLongA(
  [in] HWND hWnd,
  [in] int  nIndex
);

描述

检索有关指定窗口的信息。 该函数还会检索 32 位 (DWORD) 指定偏移量到额外窗口内存的值。

参数 类型 描述
[in] hWnd HWND 窗口的句柄,以及窗口所属类的间接句柄。
[in] nIndex int 要检索的值的从零开始的偏移量。 有效值的范围是零到额外窗口内存的字节数减去 4;例如,如果指定了 12 个或更多字节的额外内存,则值 8 将是第三个 32 位整数的索引。 若要检索任何其他值,请指定以下值之一。

其中nIndex的值含义如下,常用到值为GWL_EXSTYLE=(-20)和GWL_STYLE=(-16)

含义
GWL_EXSTYLE-20 检索 扩展窗口样式
GWL_HINSTANCE-6 检索应用程序实例的句柄。
GWL_HWNDPARENT-8 检索父窗口的句柄(如果有)。
GWL_ID-12 检索窗口的标识符。
GWL_STYLE-16 检索 窗口样式
GWL_USERDATA-21 检索与窗口关联的用户数据。 此数据供创建窗口的应用程序使用。 其值最初为零。
GWL_WNDPROC-4 检索窗口过程的地址,或表示窗口过程地址的句柄。 必须使用 CallWindowProc函数调用窗口过程。

返回值
类型: LONG

如果函数成功,则返回值为请求的值。

如果函数失败,则返回值为零。 要获得更多的错误信息,请调用 GetLastError。

如果以前未调用 SetWindowLong , 则 GetWindowLong 为额外窗口或类内存中的值返回零。

SetLayeredWindowAttributes

语法规则

BOOL SetLayeredWindowAttributes(
  [in] HWND     hwnd, 
  [in] COLORREF crKey,
  [in] BYTE     bAlpha,
  [in] DWORD    dwFlags
);

描述:设置分层窗口的不透明度和透明度颜色键。

参数 类型 描述
[in] hWnd HWND 分层窗口的句柄。 使用 CreateWindowEx 函数创建窗口时指定WS_EX_LAYERED,或者在创建窗口后通过 SetWindowLong 设置WS_EX_LAYERED来创建分层窗口。

Windows 8: 顶级窗口和子窗口支持 WS_EX_LAYERED 样式。 以前的 Windows 版本仅支持 顶级窗口WS_EX_LAYERED 。
[in] crKey COLORREF COLORREF 结构,指定要在组合分层窗口时使用的透明度颜色键。 窗口以这种颜色绘制的所有像素都是透明的。 若要生成 COLORREF,请使用 RGB 宏。
[in]bAlpha BYTE 用于描述分层窗口的不透明度的 Alpha 值。 类似于 BLENDFUNCTION 结构的 SourceConstantAlpha 成员。 当 bAlpha 为 0 时,窗口是完全透明的。 当 bAlpha 为 255 时,窗口是不透明的。
[in]dwFlags DWORD 要执行的操作。 此参数可使用以下一个或多个值。
含义
LWA_ALPHA0x00000002 使用 bAlpha 确定分层窗口的不透明度。
LWA_COLORKEY0x00000001 使用 crKey 作为透明度颜色。

第二个就是要设置的一个透明色,第三个是要设置的透明度,bAlpha的范围是 0-255,如果是0,那么完全透明,如果是255,是完全不透明。 第四个参数,就是设置是按照透明色来透明,还是按照bAlpha来透明。或者两个都设置。 如果 dwFlags 设置了LWA_COLORKEY,那么crKey就起作用,窗口中所有的crKey颜色区域就会全部透明,如果dwFlags设置了LWA_ALPHA,那么bAlpha就会起作用,整个窗口就会按照bAlpha的值来透明。也可以这两个一起设置来同时实现这两个效果。文章来源地址https://www.toymoban.com/news/detail-789689.html

功能代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace demo189_窗体移动
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        //定义user32.dll参数值
        private const uint WS_EX_LAYERED = 0x80000;
        private const int WS_EX_TRANSPARENT = 0x20;
        private const int GWL_STYLE = (-16);
        private const int GWL_EXSTYLE = (-20);
        private const int LWA_ALPHA = 0;

        //更改指定窗口的属性
        [DllImport("user32", EntryPoint = "SetWindowLong")]
        private static extern uint SetWindowLong(IntPtr hwnd,int nIndex,uint dwNewLong
        );
        //检索有关指定窗口的信息
        [DllImport("user32", EntryPoint = "GetWindowLong")]
        private static extern uint GetWindowLong(IntPtr hwnd,int nIndex
        );
        //设置分层窗口的不透明度和透明度颜色键
        [DllImport("user32", EntryPoint = "SetLayeredWindowAttributes")]
        private static extern int SetLayeredWindowAttributes(IntPtr hwnd,int crKey,int bAlpha,int dwFlags
        );

        /// <summary> 
        /// 设置窗体具有鼠标穿透效果 
        /// </summary> 
        public void SetPenetrate()
        {
            this.TopMost = true;
           //GetWindowLong(this.Handle, GWL_EXSTYLE);
            SetWindowLong(this.Handle, GWL_EXSTYLE, WS_EX_TRANSPARENT | WS_EX_LAYERED);
            SetLayeredWindowAttributes(m_hWnd,0,(BYTE)220,LWA_ALPHA);
           //SetLayeredWindowAttributes(m_hWnd,RGB(255,0,255),(BYTE)220,LWA_ALPHA|LWA_COLORKEY);
            //SetLayeredWindowAttributes(m_hWnd,RGB(0,255,0),0,LWA_COLORKEY);
        }
        private void Form1_Load(object sender, EventArgs e)
        {
            this.Opacity = 0.7;
            SetPenetrate();
        }
    }
}

到了这里,关于C#鼠标穿透功能(WinForm)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C# winform中无标题栏窗口如何实现鼠标拖动?

    在C#中,可以通过重写窗体的鼠标事件来实现无标题栏窗体的拖动。 具体步骤如下: 禁用窗体的默认标题栏:在窗体属性中设置FormBorderStyle为None。 重写鼠标事件:在窗体类中重写MouseDown、MouseMove和MouseUp事件。 定义变量存储鼠标点击时的坐标。 在MouseDown事件中记录鼠标的位

    2024年02月02日
    浏览(42)
  • C#:如何用VS开启人生中第一个Windows窗体应用程序(Winform)?

    摘要:Windows窗体应用程序(Winform,下文以此指代)既能有效、直观地设计Windows窗体界面,又支持内部逻辑的编写。那么,对于C#初学者来说,如何开启第一个Winform程序呢?    编程语言:C# 编程环境:Visual Studio 2019 目录 步骤 每篇寄语         1、点击桌面Visual Studio 2019图

    2024年02月09日
    浏览(58)
  • 【C#】【串口通信(Serial Port)】建议串口调试WinForm桌面应用实例——已实现功能<存在未知BUG>

    1、界面组件  2、界面实现代码 界面代码   3、逻辑代码 逻辑代码   4、效果展示   5、错误提醒   参考网址:C# 实现串口通信 - 编程教程 (17bigdata.com)

    2024年02月08日
    浏览(48)
  • C# Windows登录界面进行截图,控制鼠标键盘等操作实现(三)

    在Windows登录界面进行截图,目前尝试到的以下的截图方法可以截取到图,其它的方式要么卡住,要么截出来是黑屏的,直接上代码: 操作鼠标键盘等操作可以参考本人另一篇文章:使用C#制作可以录制自动化执行Windows操作脚本工具——类似于按键精灵 - log9527 - 博客园 (cnbl

    2024年02月12日
    浏览(38)
  • C# Windows登录界面进行截图,控制鼠标键盘等操作实现(二)

    上一篇:C# Windows登录界面进行截图,控制鼠标键盘等操作实现(一) - log9527 - 博客园 (cnblogs.com) 我们了解了要实现在Windows登录界面进行截图等操作必须满足的条件,这一篇我们主要通过代码实现这些条件。 首先先建一个项目A 下面一些windows自带非托管dll的调用类。 外部调用

    2024年02月12日
    浏览(39)
  • C# winform应用

    需求:导入Excel文件时需要执行其他操作,实现如果取消导入就不执行其他操作 C#代码实现 效果图

    2024年01月18日
    浏览(34)
  • 【WinForm项目】C#模拟交通信号灯|WinForm交通红绿灯

    交通信号灯十字路口通行原理图。 实际上归类为四大类: 南北双向直行 东西双向直行 一对黑色粗线的左转 一对红色粗线的左转。 状态逻辑图如下图所示: 假定通行顺序为:南北直行、南北左转、东西直行、东西左转。 南北行人只在南北车流绿灯和黄灯的时候可以通行,

    2024年02月09日
    浏览(56)
  • C#桌面程序 winform 集成内置WebApi C# 创建HTTP Web API服务,winform项目创建HTTP WEB服务,不使用IIS业务 C#桌面程序WebApi C#winform集

     在维护旧的项目时,有时需要提供APP连接的需求,就要提供HTTP服务,winform项目就要提供HTTP服务,就不用再去写个c# web的IIS相关的业务了,简化项目的复杂度。只需要简单化实例就可以实现提供HTTP服务

    2024年02月08日
    浏览(52)
  • 解决Winform的ComboBox下拉框鼠标双击事件无效的问题

    今天碰到一个需求:就是鼠标双击ComboBox后,然后模拟键盘空格键按下,测试发现,在ComboBox可以展开下拉框的情况下,鼠标双击事件是没有用的。想要实现鼠标双击事件,需要利用到鼠标单击事件,在鼠标单击事件中判断(当前时间减去上一次单击的时间)是否小于某个值(如

    2024年02月12日
    浏览(45)
  • C# WinForm —— 05 控件简介

    简介 窗体中用于输入或操作的对象,有自己的属性、方法、事件 特征 可视化,与用户进行交互,属性,方法,事件,可供开发人员使用,可发布和重用 控件开发 复合控件:各种控件组合起来,形成一个新的控件 扩展控件:现有控件上派生出一个新的控件,为原有框架增加

    2024年04月12日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包