如何在Windows桌面上绘制文本?

3

我应该如何在Windows桌面上放置文本?有人告诉我需要使用GetDesktopWindow(),但我需要一个示例。


你为什么要这样做?难道Windows中没有内置的通知系统,可以代替将文本写入桌面窗口吗?提示:很可能已经有了。 - Pod
我想制作类似于Windows侧边栏的东西。主要是为了学习经验,但我认为它也会很有用... - sowas
4个回答

9
我假设您的最终目标是在桌面上显示某种状态信息。
您需要执行以下操作之一:
- 将 DLL 注入到 Explorer 进程中并对桌面窗口 (Progman 窗口层次结构底部的 SysListView32) 进行子类化,以直接将文本绘制到该窗口上。 - 创建一个非激活窗口,其背景使用 PaintDesktop 进行绘制,并在其中绘制文本。
第一个解决方案最具侵入性,而且编码难度相当大,因此我不建议使用它。
第二个解决方案具有最大的灵活性。它没有“未经记录”的内容,也不依赖于特定的 Explorer 实现,甚至不依赖于仅将 Explorer 作为 shell。
为了防止单击窗口时将其置于顶部,您可以在 Windows 2000 及更高版本上使用扩展窗口样式 WS_EX_NOACTIVATE。在下级系统上,您可以处理 WM_MOUSEACTIVATE 消息并返回 MA_NOACTIVATE。
如果您需要真正的透明度,则可以使用分层窗口来避免 PaintDesktop 调用,但概念保持不变。我写了另一个答案,详细介绍了如何使用 GDI+ 正确地执行带有 alpha 的分层窗口。

1
为什么不直接在桌面壁纸图像文件中绘制文本?
如果您不需要经常更新信息并且有壁纸图像,则此解决方案是可行的。
可以轻松使用CImage类加载壁纸图像,CImage::GetDC()获取设备上下文进行绘制,然后保存新图像,最后将桌面壁纸更新为新图像。

我已经考虑过了,但是数据需要频繁更新。 - sowas

0
如果您的意图是创建类似侧边栏的东西,那么您可能只需要创建一个或多个分层窗口。这也将允许您处理鼠标点击和其他正常的输入来源,如果您提供了alpha通道信息,Windows将确保您的窗口始终正确地绘制。如果您不希望窗口是交互式的,请使用适当的样式(例如WS_EX_NOACTIVATE),就像Koro建议的那样。

0

我没有尝试过,但我认为你可以按照以下步骤进行:

  1. 使用GetDesktopWindow函数检索桌面窗口的句柄。
  2. 使用SetWindowLong函数将Windows消息处理程序指向你自己的过程。
  3. 在你的过程中,处理WM_PAINT消息(或其他消息),并绘制你需要的内容。
  4. 在你的过程中,调用原始消息处理程序(由SetWindowLong返回)。

不能保证百分之百可行,不过这是子类化窗口的常规方式。

-唐


1
这会导致崩溃两次:一次是当Explorer.EXE无法调用你自己的过程时(它在你的进程中,而不是Explorer中)。如果我们可以忽略这一点,那么当你尝试在Explorer的进程中而不是你自己的进程中调用原始的WndProc时,它就会崩溃。 - MSalters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接