MFC窗口透明化以及透明穿透

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

MFC编程时,有时候我们需要实现窗口透明化,可以通过SetLayeredWindowAttributes设置窗口透明色和透明度来实现窗口透明化。而要使窗口拥有透明效果,前提是窗口要有WS_EX_LAYERED扩展属性,需用SetWindowLong设置窗口支持拓展风格。

一、窗口透明化说明
1.窗口透明化有三种模式:
第一种是全窗口按透明度透明化,透明度为0时,窗口不可见,鼠标可以点击其覆盖的下层窗口;
第二种是窗口指定颜色全透明化;
第三种是窗口指定颜色全透明化,其余颜色按透明度进行透明化。
而第二、三种模式全透明化区域,根据指定颜色的不同又分为两种方式:
(1)透明,但不穿透:鼠标不能穿透窗口透明区域点击其覆盖的下层窗口。
(2)透明且穿透:鼠标可以穿透窗口透明区域点击其覆盖的下层窗口。

2.透明色特性:
(1)红色和蓝色透明色透明区域不穿透,绿色透明色透明区域穿透(其它颜色没细究过,需要自己摸索);
(2)透明色会影响画笔绘画颜色,原因不明,但可以调节透明色和画笔颜色,获得需要的绘画显示颜色,不过比较麻烦,且得不到精确RGB值的颜色。比如:红色(RGB(255,0,0))的画笔,透明色为RGB(255,0,0),在透明化窗口绘画,画笔颜色显示不为红色;透明色为RGB(0, 0, 255),在透明穿透窗口绘画,蓝色(RGB(0, 0, 255))画笔颜色显示为红色。

#define TRANSPARENT_COLOR	RGB(255,0,0)	//透明色
#define TRANSPARENT_COLOR	RGB(0,0,255)	//透明色
#define TRANSPARENT_COLOR_THROUGH	RGB(0,255,0)//透明穿透色
#define TRANSPARENT_COLOR	RGB(255,200,200) //透明色,此透明颜色时画笔颜色为RGB(255,0,0)时绘画显示仍为红色

二、SetLayeredWindowAttributes函数说明
BOOL SetLayeredWindowAttributes(
HWND hwnd, // 需要透明化窗口的句柄
COLORREF crKey, // 透明色,以RGB(r,g,b)的格式
BYTE bAlpha, // 透明度,0是全透明,255是完全不透明
DWORD dwFlags // 透明模式,有LWA_COLORKEY, LWA_ALPHA,LWA_ALPHA | LWA_COLORKEY
);
hwnd是透明窗口的句柄,
crKey为透明色,
bAlpha是透明度,取值范围是[0,255],
dwFlags是透明模式:
1.LWA_ALPHA时,crKey参数无效,bAlpha参数有效,整个窗口透明化,鼠标不能点击窗口覆盖的下层窗口,不需要在OnCtlColor指定透明色画刷,即第一种透明化模式;
2.LWA_COLORKEY时,窗体中的所有颜色为crKey的地方将变为全透明,bAlpha参数无效,需要在OnCtlColor指定透明色画刷,即第二种透明化模式。
3.LWA_ALPHA | LWA_COLORKEY时,窗体中的所有颜色为crKey的地方将变为全透明,而其它地方根据透明度bAlpha进行透明化,需要在OnCtlColor指定透明色画刷,即第三种透明化模式。
注:LWA_COLORKEY=1,LWA_ALPHA =2, LWA_ALPHA | LWA_COLORKEY=3,dwFlags亦可以设为1或者2或者3。

二、实现
MFC窗口透明化以及透明穿透

1.全窗口按透明度透明化
MFC窗口透明化以及透明穿透

HINSTANCE hInst = NULL;//DLL指针
typedef BOOL(WINAPI *MYFUNC)(HWND, COLORREF, BYTE, DWORD);
MYFUNC pFun = NULL;//函数指针

BOOL CSelectrectDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	SetWindowLong(this->m_hWnd, GWL_EXSTYLE, GetWindowLong(this->m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);//要使使窗体拥有透明效果,首先要有WS_EX_LAYERED扩展属性
	hInst = LoadLibrary(L"User32.DLL"); //显式加载DLL
	if (hInst != NULL)
	{
		pFun = (MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");//取得SetLayeredWindowAttributes函数指针
		if (pFun != NULL)
			pFun(this->m_hWnd, 0, 0, LWA_ALPHA);//整个窗口按透明度透明化			
	}
	return TRUE;  
}

注:窗口透明化后,在窗口内绘画,绘图也会按透明度进行透明化。

2.窗口指定颜色全透明化
MFC窗口透明化以及透明穿透

#define TRANSPARENT_COLOR	RGB(255,200,200)	//透明色
HINSTANCE hInst = NULL;//DLL指针
typedef BOOL(WINAPI *MYFUNC)(HWND, COLORREF, BYTE, DWORD);
MYFUNC pFun = NULL;//函数指针
CBrush m_brush;//透明色画刷

//OnCtlColor在OnInitDialog前就调用了,故需在对话框构造函数中创建透明色画刷
CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CtestDlg::IDD, pParent)
{
	//需要此处初始化画刷,OnCtlColor才能使用
	m_brush.CreateSolidBrush(RESERVED_COLOR);//透明色画刷
}

BOOL CSelectrectDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	SetWindowLong(this->m_hWnd, GWL_EXSTYLE, GetWindowLong(this->m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);//要使使窗体拥有透明效果,首先要有WS_EX_LAYERED扩展属性
	hInst = LoadLibrary(L"User32.DLL"); //显式加载DLL
	if (hInst != NULL)
	{
		pFun = (MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");//取得SetLayeredWindowAttributes函数指针
		if (pFun != NULL)
			pFun(this->m_hWnd, TRANSPARENT_COLOR, 0, LWA_COLORKEY);//窗口指定颜色全透明化			
	}
	return TRUE;  
}
//将窗口的画刷改为透明色画刷
HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
	// TODO:  在此更改 DC 的任何特性		
	return m_brush;
	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return hbr;
}

实现原理:先在OnCtlColor中将窗口的画刷改为透明色画刷,然后窗口就变成透明色,然后OnInitDialog中SetLayeredWindowAttributes将窗口颜色为透明色的区域变成全透明。
注:如果想实现透明穿透效果,将TRANSPARENT_COLOR换成TRANSPARENT_COLOR_THROUGH。

3.窗口指定颜色全透明化,其余颜色按透明度进行透明化
MFC窗口透明化以及透明穿透

#define TRANSPARENT_COLOR	RGB(255,200,200)	//透明色
HINSTANCE hInst = NULL;//DLL指针
typedef BOOL(WINAPI *MYFUNC)(HWND, COLORREF, BYTE, DWORD);
MYFUNC pFun = NULL;//函数指针
CBrush m_brush;//透明色画刷

//OnCtlColor在OnInitDialog前就调用了,故需在对话框构造函数中创建透明色画刷
CtestDlg::CtestDlg(CWnd* pParent /*=NULL*/)
	: CDialogEx(CtestDlg::IDD, pParent)
{
	//需要此处初始化画刷,OnCtlColor才能使用
	m_brush.CreateSolidBrush(RESERVED_COLOR);//透明色画刷
}

BOOL CSelectrectDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();

	// TODO:  在此添加额外的初始化
	SetWindowLong(this->m_hWnd, GWL_EXSTYLE, GetWindowLong(this->m_hWnd, GWL_EXSTYLE) | WS_EX_LAYERED);//要使使窗体拥有透明效果,首先要有WS_EX_LAYERED扩展属性
	hInst = LoadLibrary(L"User32.DLL"); //显式加载DLL
	if (hInst != NULL)
	{
		pFun = (MYFUNC)GetProcAddress(hInst, "SetLayeredWindowAttributes");//取得SetLayeredWindowAttributes函数指针
		if (pFun != NULL)
			pFun(this->m_hWnd, TRANSPARENT_COLOR, 0, LWA_ALPHA | LWA_COLORKEY);//窗口指定颜色全透明化,其余颜色按透明度进行透明化			
	}
	return TRUE;  
}
//将窗口的画刷改为透明色画刷
HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
	// TODO:  在此更改 DC 的任何特性		
	return m_brush;
	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return hbr;
}

实现原理:先在OnCtlColor中将窗口的画刷改为透明色画刷,然后窗口就变成透明色,然后OnInitDialog中SetLayeredWindowAttributes将窗口颜色为透明色的区域变成全透明,不是透明色的区域按透明度进行透明化处理。
注:如果透明度为0,效果跟第一种透明化模式一样,整个窗口不可见,鼠标可以点击其覆盖的下层窗口;如果想实现透明穿透效果,将TRANSPARENT_COLOR换成TRANSPARENT_COLOR_THROUGH。
三、拓展
OnCtlColor中通过参数pWnd或者nCtlColor判断,可以透明化客户区或者指定某几类控件或者某一控件透明化。以第二种模式为例:
1.改变某类控件的颜色进行透明化
MFC窗口透明化以及透明穿透

//将窗口的画刷改为透明色画刷
HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
	// TODO:  在此更改 DC 的任何特性		
	if (nCtlColor == CTLCOLOR_STATIC)
	{
		//有些控件需要改变字体颜色和字体背景色才能全透明 
		pDC->SetTextColor(TRANSPARENT_COLOR);   //设置字体颜色,字体全透明
		pDC->SetBkColor(TRANSPARENT_COLOR); //字体背景色,字体背景色全透明
		return m_brush;
	}		
	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return hbr;
}

2.改变某一控件的颜色进行透明化
MFC窗口透明化以及透明穿透

//将窗口的画刷改为透明色画刷
HBRUSH CtestDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
	// TODO:  在此更改 DC 的任何特性		
	if (pWnd->GetDlgCtrlID() == IDC_STATIC)
	{
		//有些控件需要改变字体颜色和字体背景色才能全透明 
		pDC->SetTextColor(TRANSPARENT_COLOR);   //设置字体颜色,字体全透明
		pDC->SetBkColor(TRANSPARENT_COLOR); //字体背景色,字体背景色全透明
		return m_brush;
	}		
	// TODO:  如果默认的不是所需画笔,则返回另一个画笔
	return hbr;
}

注:OnCtlColor可以改变客户区和某些控件的画刷颜色,但是改变不了窗口边框的颜色以及某些控件的画刷颜色,例如:Button、Slider、Picture等控件。要想将这些控件也全透明,可以使用ShowWindow(SW_HIDE)隐藏控件,在需要的时候再用ShowWindow(SW_SHOW)显示控件。如果想要将这些控件半透明,可以使用第三种透明化模式,但窗口边框也会半透明;如果想要将这些控件半透明,边框全透明,可以使用第三种透明化模式,同时用SetWindowLong去掉边框。文章来源地址https://www.toymoban.com/news/detail-492190.html

到了这里,关于MFC窗口透明化以及透明穿透的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • uni小程序canvas实现图像灰度和透明化

    在小程序原生中也一样,只不过uni改成wx 不管是在uni还是在原生都要指定 canvas  2d类型,如果不指定类型的话,透明化会有问题。  初始化完成以后通过 getImageData属性获取到画布中每一个像素的rgba值 灰度值 透明化(如果canvas没有配置type类型的情况下,修改data[i+3] = 0是不会

    2024年02月12日
    浏览(30)
  • “分布式透明化”在杭州银行核心系统上线之思考

    导读 随着金融行业数字化转型的需求,银行核心系统的升级改造成为重要议题。杭州银行成功上线以 TiDB 为底层数据库的新一代核心业务系统,该实践采用应用与基础设施解耦、分布式透明化的设计开发理念,推动银行核心系统的整体升级。 本文聚焦银行核心系统演进,结

    2024年02月20日
    浏览(30)
  • YOLOv8及其改进系列(五) modules.py 文件划分子集 | 标签透明化与文字大小调节 | 框粗细调节

    最近 YOLOv8 的官方项目又迎来了一个大更新,这次更新对基础不好的同学影响可能比较大, 这次更新主要就是将原本的 ultralytics/nn/modules.py 拆分成了以下 6 个文件: _init_.py block.py conv.py head.py trasnformer.py utils.py 有的同学可能不知道该加哪里了,我这里给大家说一下 我们原本的

    2024年03月16日
    浏览(89)
  • Qt透明窗口鼠标穿透问题及解决办法

    最近写了个项目,需要播放视频并在视频上做标记框去完成一些功能 因为视频播放使用了 VLC-qt 的库,封装好的窗口控件 没办法直接在该视频窗口上绘图(也许可以?) 出于不想动别人写好的库的想法,想着在视频窗口上加一个透明蒙版-即一个透明窗口,在透明窗口上进行

    2024年02月04日
    浏览(33)
  • MFC 透明窗体

    如何制作透明窗体 ????? 使用SetLayeredWindowAttributes可以方便的制作透明窗体,此函数在w2k以上才支持,而且如果希望直接使用的话,可能需要下载最新的SDK。不过此函数在w2k的user32.dll里有实现,所以如果你不希望下载巨大的sdk的话,可以直接使用GetProcAddress获取该函数的

    2024年02月15日
    浏览(32)
  • 【AHK】鼠标调整窗口大小/移动窗口位置/窗口置顶/透明度

    通过AHK,设置窗体大小或位置,首先是两种鼠标调节窗体方案,后面是快捷键,注意修改快捷键的位置有两个,仿照Ubuntu调节窗体的快捷键 Alt+F7、Alt+F8,个人感觉比要按着ALT调节的小工具要好用一点。 如果换成单个F7、F8触发,只需要将多出的GetKeyState删除即可,具体函数意

    2024年02月12日
    浏览(31)
  • 【MFC】06.MFC六大机制:窗口创建机制-笔记

    接上文【MFC】05.MFC第一大机制:程序启动机制-笔记,这一篇文章来带领大家逆向分析MFC第二大机制:窗口创建机制的源码。 我们知道,在Win32编程中,如果我们要创建一个窗口,基本步骤为: 注册窗口 创建一个窗口,必须要给一个类名称 消息处理回调函数 那么MFC的窗口创建

    2024年02月13日
    浏览(22)
  • 【MFC】06.MFC第二大机制:窗口创建机制-笔记

    接上文【MFC】05.MFC第一大机制:程序启动机制-笔记,这一篇文章来带领大家逆向分析MFC第二大机制:窗口创建机制的源码。 我们知道,在Win32编程中,如果我们要创建一个窗口,基本步骤为: 注册窗口 创建一个窗口,必须要给一个类名称 消息处理回调函数 那么MFC的窗口创建

    2024年02月14日
    浏览(28)
  • 2023最新unity 发布exe程序背景透明穿透

    由于网上的一些帖子比较老了,好多人评论不能用黑屏之类的。这边重新整理个最新的,亲测可用。 先大体概括下,一共就几处设置,一个脚本。 一、设置 普通渲染的项目摄像机的Clear Flags选择Solid Color,颜色为黑色(0,0,0,0)。 使用HDRP的项目,关闭掉摄像机上的脚本:HDAddi

    2024年02月08日
    浏览(31)
  • MFC 隐藏窗口

    亲测能用 改变主窗体的创建方式 将 C***App::InitInstance() 函数中的代码 替换为

    2024年02月11日
    浏览(23)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包