问题的原因是:
层窗口(WS_EX_LAYERED),用UpdateLayeredWindow输出的文字(用常规方法输出的:TextOut、DrawText、DrawString...),并且设置了AC_SRC_ALPHA和ULW_ALPHA,就会存在这种错误。
解决办法:
void CGDIPlus_TextTestDlg::Redraw() { CRect rect; GetClientRect(&rect); SolidBrush brush(Color(200,255,0,0)); m_pGraphics->FillRectangle(&brush,0,0,rect.Width(),rect.Height()); CFont *pFont=GetFont(); LOGFONT lf; pFont->GetLogFont(&lf); CComBSTR wszFN(lf.lfFaceName); int nHeight=-lf.lfHeight; FontFamily ff(wszFN,NULL); int nStyle=FontStyleRegular; Font font(&ff,nHeight,nStyle,UnitPixel); StringFormat format; format.SetAlignment(StringAlignmentNear); SolidBrush brush2(Color(255,0,0,0)); int nStyle2=FontStyleBold; Font font2(&ff,nHeight,nStyle2,UnitPixel); //-----直接写字,变得穿透了 CComBSTR wsz("文字Test: 直接写字,变得穿透了"); m_pGraphics->DrawString(wsz,wsz.Length(),&font,PointF(50,50),&format,&brush2); //-----文字加粗 wsz="文字Test: 文字加粗"; m_pGraphics->DrawString(wsz,wsz.Length(),&font2,PointF(50,70),&format,&brush2); //-----SetTextRenderingHint(TextRenderingHintAntiAlias) wsz="文字Test: SetTextRenderingHint(TextRenderingHintAntiAlias)"; GraphicsContainer gc=m_pGraphics->BeginContainer(); m_pGraphics->SetTextRenderingHint(TextRenderingHintAntiAlias); m_pGraphics->DrawString(wsz,wsz.Length(),&font,PointF(50,90),&format,&brush2); m_pGraphics->EndContainer(gc); //-----GraphicsPath wsz="文字Test: GraphicsPath"; gc=m_pGraphics->BeginContainer(); m_pGraphics->SetSmoothingMode(SmoothingModeHighQuality); GraphicsPath path(FillModeAlternate); path.AddString(wsz,wsz.Length(),&ff,nStyle,nHeight,PointF(50,110),&format); m_pGraphics->FillPath(&brush2,&path); m_pGraphics->EndContainer(gc); SIZE sizeWindow = rect.Size(); POINT ptSrc = { 0, 0 }; BLENDFUNCTION blend; blend.BlendOp = AC_SRC_OVER; blend.BlendFlags = 0; blend.AlphaFormat = AC_SRC_ALPHA; blend.SourceConstantAlpha = 255; UpdateLayeredWindow(m_hWnd, hdcHWND, NULL, &sizeWindow, hdcHBMP, &ptSrc, 0, &blend, ULW_ALPHA); }有三个方法避免,但是都不是真正的解决这个问题
不过,这三种方法都改变了字画出来的样子,第一种方法字被加粗了,第二三种方法字被抗锯齿了。找到一个简单的方法同时避免穿透和变形的问题,把Color的Alhpa值改成254就好了。使用DrawString + A->254 没问题。
如下段代码,点(100,10)是在透明区,所以也就是直接将文字写在了桌面上:
Graphics grpah(m_hDcBackground); FontFamily ff(L"微软雅黑"); Font font(&ff,14,FontStyleBold ,UnitPixel); StringFormat format; format.SetAlignment(StringAlignmentCenter); grpah.DrawString(L"不会出问题吧",-1,&font,PointF(100,10),&format,&SolidBrush(Color(254,0,255,0))); grpah.ReleaseHDC(m_hDcBackground);效果:
grpah.SetTextRenderingHint(TextRenderingHintAntiAlias);
也就是说更改了原字体的绘制方式;DC与HBITMAP的关系就好比是叫一个人去某目的地进行演出,而HBITMAP就好比是为这个人演出提供的设备,搭建演出舞台供DC去演绎,展示,同时HBITMAP保存演绎的信息直到调用 DeleteObject(m_hBitmap)并将m_hBitmapBk = NULL;为止;
DC:表示演出目的地,在确定好舞台后才能演绎,展示。
HBITMAP:表示演出舞台,保存演绎的信息,直到调用DeleteObject(m_hBitmap)并将m_hBitmapBk = NULL才丢失原保留的信息。