在C++ Win32中创建透明窗口

2023-11-27

我正在创建一个非常简单的 Win32 C++ 应用程序,其唯一目的是仅显示半透明的 PNG。窗口不应该有任何镶边,并且所有不透明度都应该在 PNG 本身中控制。

我的问题是,当窗口下的内容发生变化时,窗口不会重新绘制,因此 PNG 的透明区域与应用程序最初启动时窗口下的内容“粘在一起”。

这是我设置新窗口的行:

hWnd = CreateWindowEx(WS_EX_TOPMOST, szWindowClass, szTitle, WS_POPUP, 0, height/2 - 20, 40, 102, NULL, NULL, hInstance, 0);

对于对 RegisterClassEx 的调用,我将其设置为背景:

wcex.hbrBackground = (HBRUSH)0;

这是我的 WM_PAINT 消息处理程序:

 case WM_PAINT:
 {
   hdc = BeginPaint(hWnd, &ps);
   Gdiplus::Graphics graphics(hdc);
   graphics.DrawImage(*m_pBitmap, 0, 0);
   EndPaint(hWnd, &ps);
   break;
 }

需要注意的一件事是应用程序始终停靠在屏幕左侧并且不会移动。但是,当用户打开、关闭或移动应用程序下面的窗口时,应用程序下面的内容可能会发生变化。

当应用程序第一次启动时,它看起来很完美。 PNG 的透明(和半透明)部分完美显示。但是,当应用程序下面的背景发生变化时,背景不会更新,它只是与应用程序首次启动时保持不变。事实上,当背景改变时,WM_PAINT(或WM_ERASEBKGND不会被调用)。

我已经玩了很长一段时间了,已经接近 100% 正确,但还没有完全达到。例如,我尝试将背景设置为 (HBRUSH) NULL_BRUSH,并尝试处理 WM_ERASEBKGND。

当窗口下面的内容发生变化时,可以做什么来让窗口重新绘制?


通过使用本系列第 1 部分和第 2 部分中的代码,我能够准确地完成我想要的操作:

使用 C++ 显示启动屏幕


  • Part 1: Creating a HBITMAP archive
  • Part 2: Displaying the window archive

这些博客文章讨论的是在 Win32 C++ 中显示启动屏幕,但它与我需要做的几乎相同。我相信我缺少的部分是,我需要使用 GDI+ 将 PNG 绘制到窗口上,而不是使用UpdateLayeredWindow功能与适当的BLENDFUNCTION范围。我将粘贴下面的 SetSplashImage 方法,该方法可以在上面链接的第 2 部分中找到:

void SetSplashImage(HWND hwndSplash, HBITMAP hbmpSplash)
{
  // get the size of the bitmap
  BITMAP bm;
  GetObject(hbmpSplash, sizeof(bm), &bm);
  SIZE sizeSplash = { bm.bmWidth, bm.bmHeight };

  // get the primary monitor's info
  POINT ptZero = { 0 };
  HMONITOR hmonPrimary = MonitorFromPoint(ptZero, MONITOR_DEFAULTTOPRIMARY);
  MONITORINFO monitorinfo = { 0 };
  monitorinfo.cbSize = sizeof(monitorinfo);
  GetMonitorInfo(hmonPrimary, &monitorinfo);

  // center the splash screen in the middle of the primary work area
  const RECT & rcWork = monitorinfo.rcWork;
  POINT ptOrigin;
  ptOrigin.x = 0;
  ptOrigin.y = rcWork.top + (rcWork.bottom - rcWork.top - sizeSplash.cy) / 2;

  // create a memory DC holding the splash bitmap
  HDC hdcScreen = GetDC(NULL);
  HDC hdcMem = CreateCompatibleDC(hdcScreen);
  HBITMAP hbmpOld = (HBITMAP) SelectObject(hdcMem, hbmpSplash);

  // use the source image's alpha channel for blending
  BLENDFUNCTION blend = { 0 };
  blend.BlendOp = AC_SRC_OVER;
  blend.SourceConstantAlpha = 255;
  blend.AlphaFormat = AC_SRC_ALPHA;

  // paint the window (in the right location) with the alpha-blended bitmap
  UpdateLayeredWindow(hwndSplash, hdcScreen, &ptOrigin, &sizeSplash,
      hdcMem, &ptZero, RGB(0, 0, 0), &blend, ULW_ALPHA);

  // delete temporary objects
  SelectObject(hdcMem, hbmpOld);
  DeleteDC(hdcMem);
  ReleaseDC(NULL, hdcScreen);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在C++ Win32中创建透明窗口 的相关文章

随机推荐

  • 如何在 Windows 上安装 rmagick gem?

    如何为 Windows XP 安装 rmagick gem 我已经使用头文件安装了 ImageMagick 并且安装了 DevKit 附带的 RailsInstaller org 我不知道到哪里去修复这些错误 C RailsInstalle
  • 一次迭代两个数组的每个循环

    我有两个大小相同的 Javascript 数组 var demo new Array var demo3 new Array 我需要在 JQuery 代码中的每个循环中访问两个数组的值 冲浪了一段时间后 我遇到了 zip 操作 我尝试使用代
  • 根据用户更改主题/CSS

    我正在开发一款产品 我们最终将为其贴上白标标签 现在 我正在尝试找出以编程方式满足这些要求的最佳方法 以便用户可以通过其个人资料 设置表单更新网站的基本设计 即标题颜色等 要求 用户可以更新徽标 已完成 用户可以更新基本设计元素 基于 CS
  • 如何用JS以不可变的方式连接数组

    我想知道如何联系不可变的数组 让我们想象一下我从数组开始list 4 1 然后我从动作响应中接收数组 如下所示items 5 2 6 如何连接结果为的数组 4 1 5 2 6 并且该操作是不可改变的 Bonus 如何覆盖具有相同 id 的项
  • C++ std::string 是容器吗?

    对于你们中的一些人来说 这可能是一个简单的问题 但我想知道是否std string是一个容器 我所说的容器是指容器 例如std vector std list and std deque Since std basic string lt
  • 使用 Asyncio 进行非阻塞 Websocket 接收

    我正在开发一个 Python 3 程序 它试图做两件事 1 从外部 websocket 非阻塞 读取数据 类型 1 并且 2 在常规UDP套接字上接收数据 类型2 非阻塞 有很长一段时间 websocket 和 UDP 套接字上都没有数据
  • 以编程方式更新 Android 操作系统

    我正在从事一个移动设备管理项目 我们项目的要求之一是以编程方式更新 Android 设备操作系统 流程如下 服务器发送有关操作系统更新的推送通知 Android 客户端下载更新 现在我想以编程方式更新 Android 设备操作系统 我怎样才
  • 如何根据特定索引范围对 ArrayList 进行排序

    我的需要是根据特定的索引范围对字符串的 ArrayList 进行排序 例如 我的列表中有以下项目 abc xyz pqr asd 现在我想从索引 1 到最后一个索引对该列表进行排序 一种方式我认为我可以从具有所需索引范围的主列表创建一个子列
  • Delphi:检查文件是否正在使用

    我想写入 删除文件 但有时如果该文件正在被另一个程序使用 我会崩溃 如何检查文件是否被其他进程打开或者我可以打开它进行写入 问题是 在您检查是否可以获得独占访问权限和打开文件之间 其他东西获得了对该文件的独占访问权限 无论如何您都会收到异常
  • 如何分散客户使用 IE6 的注意力

    我们如何才能分散客户使用 IE6 的注意力 我们知道IE6并不是一个很好的符合标准的浏览器 有很多问题 如何满足客户不使用IE6 谢谢 我目前正在为我的公司建立一个新网站 我一直在考虑http code google com p ie6 u
  • Node.js:获取响应时间

    如何知道 URL 的响应时间 我在用着http get 发出 HTTP GET 请求 没有内置函数或值来获取响应时间 但您自己可以轻松获得该值 var http require http var start new Date http ge
  • Haskell 函数名中 ' 的含义?

    什么是报价 用于 我已经阅读了有关柯里化函数的内容 并阅读了定义 add 函数的两种方法 柯里化和非柯里化 咖喱版本 myadd Int gt Int gt Int myadd x y x y 但即使没有引号 它也同样有效 那么这有什么意义
  • appengine-mapreduce 达到内存限制

    我正在研究 appengine mapreduce 函数 并修改了演示以适应我的目的 基本上我有超过一百万行 格式如下 userid time1 time2 我的目的是找到每个用户 ID 的 time1 和 time2 之间的差异 但是 当
  • grep 最后一场比赛及其以下几行

    我已经学会了如何grep比赛前后的线路以及grep上一场比赛 但我还没找到如何做grep最后一场比赛及其下方的线条 该场景是服务器日志 我想列出命令的动态输出 该命令可能在一个服务器日志中使用多次 所以我想匹配将是命令并且以某种方式grep
  • HTML 范围滑块和 jQuery?

    我的网站中有以下代码 并使用 HTML5 集成了范围滑块 我希望滑块用值更新文本输入 反之亦然 我会使用 jQuery 来做到这一点吗 如果可以的话你能给我示例代码吗 Thanks
  • SELECT COUNT(*) 昂贵吗?

    您认为在每次页面加载时对一个非常大的表 例如 50K 行 中的条目进行计数是一个好主意吗 SELECT COUNT FROM table 现在我有大约 2000 行 看起来相当快 我没有看到页面加载有任何延迟 但表应该达到 50K 条目 我
  • 使用 wix 生成可执行文件

    我正在学习 Wix 我想生成 setup exe 文件而不是 setup msi 那可能吗 安装 EXE 通常称为引导程序 or chainer WiX 3 5 将附带一个名为burn exe 不幸的是 这仍在大力开发中 如果您只是想要一个
  • 验证AWS API网关的请求路径参数?

    假设我有一个带有路径的 api and pets and pets pet 现在我正在尝试验证路径 pets 参数 以便只有长度为 6 的字母数字字符的路径才会被验证并处理到后端 lambda 所有其他路径都将被拒绝 我尝试了以下 swag
  • 我可以使用 gmail 作为我网站的 smtp 服务器吗

    您好 我正在尝试建立并运行一个网站 它目前托管在 AWS 上 因此我目前没有运行自己的 smtp 服务器 所以在阅读了几篇文章后 我了解到我们可以使用gmail作为smtp服务器 我想仔细检查我读到的内容是否正确 我将使用智能求职板软件 我
  • 在C++ Win32中创建透明窗口

    我正在创建一个非常简单的 Win32 C 应用程序 其唯一目的是仅显示半透明的 PNG 窗口不应该有任何镶边 并且所有不透明度都应该在 PNG 本身中控制 我的问题是 当窗口下的内容发生变化时 窗口不会重新绘制 因此 PNG 的透明区域与应