dig*_*doo 5 c++ gdi+ remote-desktop drawstring
我正在将文本绘制到DIB部分的屏幕外位图,该位图深度为32位并使用alpha通道(ARGB).我将像素直接绘制到内存中.然后,我创建一个Gdiplus Graphics对象,将我的内存DC传递给它,并使用Graphics :: DrawString绘制文本.这在正常情况下工作正常.但是,在远程桌面上,渲染的文本是完全透明的,即不是绘制任何颜色像素,而是可以看到文本的位置.有谁知道为什么会这样,以及如何解决它?
这是我的drawString例程:
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;
}
Run Code Online (Sandbox Code Playgroud)
这就是我创建DIB的方式:
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...
}
Run Code Online (Sandbox Code Playgroud)
在将文本绘制到DIB之后,我做到了
gfx.Flush (Gdiplus::FlushIntentionSync);
Run Code Online (Sandbox Code Playgroud)
编辑:您可能还感兴趣的是,最终绘制DIB的窗口是WS_EX_LAYERED窗口.这是一个启动画面,显示应用程序何时启动,并使用计时器和以下方法慢慢淡入淡出:
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);
}
Run Code Online (Sandbox Code Playgroud)
我很惊讶这竟然有效。使用 gdi32 绘图会丢失 alpha 信息,据我了解,使用 gdi32 在 32 位 DIB 上进行的任何绘图都会使 DIB 中的 alpha 信息未定义。在这种情况下,GDI+ 必须通过 gdi32,因为您给了它一个 HDC。
要使用 GDI+ 绘制到 RGBA DIB,您需要创建一个由 DIB 内存支持的具有正确像素格式的 GDI+ 位图对象(使用采用像素数据指针的构造函数,例如这个),然后从你的位图。这允许 GDI+ 直接绘制到 DIB 内存并正确处理 Alpha 通道,而不是通过 gdi32。
当然,如果您不需要每像素 Alpha,您可以通过在混合函数中使用 AlphaFormat 0 来忽略 DIB 中的 Alpha 通道来简化操作。