首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UpdateLayeredWindow和DrawText

UpdateLayeredWindow和DrawText
EN

Stack Overflow用户
提问于 2011-03-15 09:42:58
回答 1查看 4.4K关注 0票数 3

我使用UpdateLayeredWindow来显示应用程序窗口。我已经创建了我自己的自定义按钮,我想创建我自己的静态文本。问题是,当我试图在hdc上绘制文本时,DrawText或TextOut函数将覆盖图片的alpha通道,文本将变得透明。我试图找到解决这一问题的办法,但找不到任何解决办法。我的自定义控件的设计方式是,它们将在名为hdc的成员函数(Hdc hDc)中执行所有绘图,因此它们只能访问hdc。我想保留这个设计。有谁可以帮我?我使用的是MFC,我希望在不使用GDI+的情况下实现预期的结果。

EN

回答 1

Stack Overflow用户

发布于 2012-04-13 21:47:06

我知道这是个老职位..。但我只是遇到了同样的问题。把我逼疯了。

最后,我偶然发现了迈克·萨顿( Mike )给microsoft.public.win32.programmer.gdi新闻组的这个microsoft.public.win32.programmer.gdi.从近7年前开始!

基本上,DrawText (和TextOut)不能很好地处理alpha通道和UpdateLayeredWindow .,你需要将R,G,B通道与α通道相乘。

在Mike的文章中,他展示了他是如何创建另一个DIB (设备独立位图)的,他以此为基础绘制文本.阿尔法把它和其他位图混合在一起。

做完这件事后,我的文字看上去很完美!

以防万一,新闻组帖子的链接死了.我要把密码写在这里。所有的功劳都归于迈克·萨顿(@mikedsutton)。

下面是创建带有文本的alpha混合位图的代码:

代码语言:javascript
复制
HBITMAP CreateAlphaTextBitmap(LPCSTR inText, HFONT inFont, COLORREF inColour)
{ 
    int TextLength = (int)strlen(inText); 
    if (TextLength <= 0) return NULL; 

    // Create DC and select font into it 
    HDC hTextDC = CreateCompatibleDC(NULL); 
    HFONT hOldFont = (HFONT)SelectObject(hTextDC, inFont); 
    HBITMAP hMyDIB = NULL; 

    // Get text area 
    RECT TextArea = {0, 0, 0, 0}; 
    DrawText(hTextDC, inText, TextLength, &TextArea, DT_CALCRECT); 
    if ((TextArea.right > TextArea.left) && (TextArea.bottom > TextArea.top))
    { 
        BITMAPINFOHEADER BMIH; 
        memset(&BMIH, 0x0, sizeof(BITMAPINFOHEADER)); 
        void *pvBits = NULL; 

        // Specify DIB setup 
        BMIH.biSize = sizeof(BMIH); 
        BMIH.biWidth = TextArea.right - TextArea.left; 
        BMIH.biHeight = TextArea.bottom - TextArea.top; 
        BMIH.biPlanes = 1; 
        BMIH.biBitCount = 32; 
        BMIH.biCompression = BI_RGB; 

        // Create and select DIB into DC 
        hMyDIB = CreateDIBSection(hTextDC, (LPBITMAPINFO)&BMIH, 0, (LPVOID*)&pvBits, NULL, 0); 
        HBITMAP hOldBMP = (HBITMAP)SelectObject(hTextDC, hMyDIB); 
        if (hOldBMP != NULL)
        { 
            // Set up DC properties 
            SetTextColor(hTextDC, 0x00FFFFFF); 
            SetBkColor(hTextDC, 0x00000000); 
            SetBkMode(hTextDC, OPAQUE); 

            // Draw text to buffer 
            DrawText(hTextDC, inText, TextLength, &TextArea, DT_NOCLIP); 
            BYTE* DataPtr = (BYTE*)pvBits; 
            BYTE FillR = GetRValue(inColour); 
            BYTE FillG = GetGValue(inColour); 
            BYTE FillB = GetBValue(inColour); 
            BYTE ThisA; 
            for (int LoopY = 0; LoopY < BMIH.biHeight; LoopY++) { 
                for (int LoopX = 0; LoopX < BMIH.biWidth; LoopX++) { 
                    ThisA = *DataPtr; // Move alpha and pre-multiply with RGB 
                    *DataPtr++ = (FillB * ThisA) >> 8; 
                    *DataPtr++ = (FillG * ThisA) >> 8; 
                    *DataPtr++ = (FillR * ThisA) >> 8; 
                    *DataPtr++ = ThisA; // Set Alpha 
                } 
            } 

            // De-select bitmap 
            SelectObject(hTextDC, hOldBMP); 
        } 
    } 

    // De-select font and destroy temp DC 
    SelectObject(hTextDC, hOldFont); 
    DeleteDC(hTextDC); 

    // Return DIBSection 
    return hMyDIB; 
}

下面是驱动CreateAlphaTextBitmap方法的代码:

代码语言:javascript
复制
void TestAlphaText(HDC inDC, int inX, int inY)
{ 
    const char *DemoText = "Hello World!\0"; 
    RECT TextArea = {0, 0, 0, 0}; 
    HFONT TempFont = CreateFont(50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, "Arial\0"); 
    HBITMAP MyBMP = CreateAlphaTextBitmap(DemoText, TempFont, 0xFF); 
    DeleteObject(TempFont); 
    if (MyBMP)
    {
        // Create temporary DC and select new Bitmap into it 
        HDC hTempDC = CreateCompatibleDC(inDC); 
        HBITMAP hOldBMP = (HBITMAP)SelectObject(hTempDC, MyBMP); 
        if (hOldBMP)
        {
            // Get Bitmap image size
            BITMAP BMInf;
            GetObject(MyBMP, sizeof(BITMAP), &BMInf); 

            // Fill blend function and blend new text to window 
            BLENDFUNCTION bf; 
            bf.BlendOp = AC_SRC_OVER; 
            bf.BlendFlags = 0; 
            bf.SourceConstantAlpha = 0x80; 
            bf.AlphaFormat = AC_SRC_ALPHA; 
            AlphaBlend(inDC, inX, inY, BMInf.bmWidth, BMInf.bmHeight, hTempDC, 0, 0, BMInf.bmWidth, BMInf.bmHeight, bf); 

            // Clean up 
            SelectObject(hTempDC, hOldBMP); 
            DeleteObject(MyBMP); 
            DeleteDC(hTempDC); 
        } 
    } 
} 
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5309914

复制
相关文章

相似问题

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