首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Gdiplus DrawString在远程桌面上绘制透明文本

Gdiplus DrawString在远程桌面上绘制透明文本
EN

Stack Overflow用户
提问于 2012-11-14 18:18:01
回答 2查看 2.1K关注 0票数 5

我正在将文本绘制到一个DIB部分的屏外位图中,它有32位深,并且使用alpha通道(ARGB)。我直接将像素绘制到内存中。然后,我创建了一个Gdiplus Graphics对象,将我的内存DC传递给它,并使用Graphics::DrawString绘制文本。这在正常情况下工作得很好。然而,在远程桌面上,呈现的文本是完全透明的,也就是说,您可以看到文本的位置,而不是绘制任何颜色的像素。有没有人知道为什么会这样,以及如何修复?

下面是我的drawString例程:

代码语言:javascript
运行
复制
void SplashScreen::drawString (MyString &ivText, Gdiplus::RectF &r, 
  Gdiplus::ARGB c, Gdiplus::StringAlignment align, Gdiplus::Font &fnt,
  Gdiplus::Graphics &gfx)
  {
  Gdiplus::StringFormat fmt;
  fmt.SetAlignment (align);
  Gdiplus::SolidBrush brush (c);
  wchar_t *wstr = new wchar_t [ivText.length()+1];
  std::mbstowcs (wstr, ivText.cstr(), ivText.length()+1);
  gfx.DrawString (wstr, ivText.length(), &fnt, r, &fmt, &brush);
  delete wstr;
  }

这就是我创建DIB的方法:

代码语言:javascript
运行
复制
BITMAPV5HEADER bhd;
memset (&bhd, 0, sizeof (bhd));
bhd.bV5Size = sizeof (BITMAPV5HEADER);
bhd.bV5Width = nWidth;
bhd.bV5Height = -nHeight;  // negative height indicates top-down DIB
bhd.bV5Planes = 1;
bhd.bV5BitCount = 32;
bhd.bV5Compression = BI_BITFIELDS;
bhd.bV5RedMask   = 0x00FF0000;
bhd.bV5GreenMask = 0x0000FF00;
bhd.bV5BlueMask  = 0x000000FF;
bhd.bV5AlphaMask = 0xFF000000; 
m_pBuf = NULL;
m_hBmp = ::CreateDIBSection (m_hDC, (BITMAPINFO *) &bhd, DIB_RGB_COLORS,
   (void **) &m_pBuf, NULL, 0);
if (m_hBmp == NULL || m_pBuf == NULL)
   {
   // error...
   }
HGDIOBJ oldObj = ::SelectObject (m_hDC, m_hBmp);
if (oldObj == NULL)
   {
   // error...
   }

在将文本绘制到DIB中之后,我这样做了

代码语言:javascript
运行
复制
gfx.Flush (Gdiplus::FlushIntentionSync);

编辑:您可能还会感兴趣的是,最终绘制DIB的窗口是一个WS_EX_LAYERED窗口。它是一个闪屏,显示应用程序启动的时间,并使用计时器和以下方法慢慢淡入和淡出:

代码语言:javascript
运行
复制
void SplashScreen::setWindowTransparency (int nAlpha)
  // @param nAlpha: 255 is opaque, 0 is fully transparent.
  {
  HWND hwnd = getHwnd();
  BLENDFUNCTION blend;
  blend.BlendOp = AC_SRC_OVER;
  blend.BlendFlags = 0;
  blend.SourceConstantAlpha = nAlpha;
  blend.AlphaFormat = AC_SRC_ALPHA;
  BOOL bResult = ::UpdateLayeredWindow (hwnd, NULL, NULL, NULL, NULL,
     NULL, RGB (0, 0, 0), &blend, ULW_ALPHA);
  }
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-11-16 04:39:28

我很惊讶这能行得通。使用gdi32绘制会丢失alpha信息,据我所知,使用gdi32在32位DIB上绘制会使DIB中的alpha信息未定义。在这种情况下,GDI+必须通过gdi32,因为您给了它一个HDC。

要使用GDI+绘制到RGBA DIB,您需要创建一个GDI+ Bitmap对象,该对象由DIB的内存支持,具有正确的像素格式(使用接受像素数据指针的构造函数,如this one),然后是create a Graphics object from your Bitmap。这允许GDI+直接绘制到DIB的内存并正确处理alpha通道,而不是通过gdi32。

票数 4
EN

Stack Overflow用户

发布于 2013-02-27 07:20:02

我有一个可能的解决方案。不确定您连接的是哪个版本的Windows,但在远程计算机上,您可能必须为终端服务启用32位颜色模式。否则,您的客户端可能会被限制为16位模式。

在服务器上,使用gpedit.msc将“限制最大颜色深度”选项配置为32位。在Windows 2008/2012中,这位于管理模板- Windows组件-远程桌面服务-远程会话环境中。

如果您连接到Windows XP/Vista/7/8计算机,我不确定此gpedit设置是否可用。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13376883

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档