基于VS2013MFC左移显示效果

主要思路:
  采用双缓冲的方法,将背景位图和文本位图统一绘制到一个新的位图上,再将新的位图张贴到窗口上。
直接上代码:

//以下代码是基于ANSI编码方式
BOOL CPlugIn::DrawRollLight()
{
    HDC hScrDC,hScrDC1, hMemDC1, hMemDC_a;
    CDC MemDC;
    if (!MemDC.CreateCompatibleDC(pDC))     //建立一个与pDC 设备上下文环境的句柄
    {
        return 0;
    }
    CBitmap m_BitmapQuotes;
    if (!m_BitmapQuotes.CreateCompatibleBitmap(pDC, MaxLength, Height)) //建立与pDC相兼容的位图
    {
        return 0;
    }

    CBitmap *pOldBitmap = (CBitmap *)MemDC.SelectObject(&m_BitmapQuotes);

    //背景
    if (BgMode == 1)        //背景色
    {
        CRect rct;
        GetClientRect(ParentHwnd, &rct);
        CBrush   brush;
        brush.CreateSolidBrush(BgColor);
        MemDC.FillRect(&rct, &brush);
    }
    else if (BgMode == 2)   //背景图片
    {
        wchar_t m_BgFileName[200];
        c2w(m_BgFileName, 200, strBgPt);
        Graphics graphicsp(MemDC);
        if (nBgPtForm == 0)     //平铺
        {
            Bitmap backgroundmiddle(m_BgFileName);
            TextureBrush brush(&backgroundmiddle, WrapModeTileFlipXY);
            graphicsp.FillRectangle(&brush, RectF(0.0f, 0.0f, (float)Width, (float)Height));
        }
        if (nBgPtForm == 1)
        {

            ImageAttributes imAtt;
            imAtt.SetWrapMode(WrapModeTile);
            //拉伸图片
            Bitmap Backgroundtop(m_BgFileName);
            graphicsp.DrawImage(&Backgroundtop, Rect(0, 0, Width, Height),
                0, 0, Backgroundtop.GetWidth(), Backgroundtop.GetHeight(),
                UnitPixel,
                &imAtt);
        }
    }
    pDC->BitBlt(0, 0, Width, Height, &MemDC, 0, 0, SRCCOPY); 
    UpdateWindow(ParentHwnd);

    HBITMAP hBitmap, hOldBitmap, hBitmap_a, hOldBitmap_a;
    int width, height;
    int i, x, y = 0;
    int lineSpaceTemp = 0;
    int angle;
    CString str1, str2, textFontName, textStr;
    str1 = strAllInfo;
    try
    {
        //创建一个用于绘制文本的位图
        hScrDC = CreateDC(_T("Display"), NULL, NULL, NULL);   //创建指定设备的设备上下文
        hMemDC1 = CreateCompatibleDC(hScrDC);                   //创建hScrDC设备上下文的句柄, hMemDC1
        width = Width + 100 + 20;
        height = Height + 100;

        //创建一个用于张贴图片和文本汇总的位图
        hMemDC_a = CreateCompatibleDC(NULL);
        hBitmap_a = CreateCompatibleBitmap(pDC->GetSafeHdc(), Width, Height);   //创建与hScrDC1相兼容的位图
        hOldBitmap_a = (HBITMAP)SelectObject(hMemDC_a, hBitmap_a);
        CRect rct;
        GetClientRect(ParentHwnd, &rct);
        CBrush   brush;
        brush.CreateSolidBrush(BgColor);
        if (BgMode == 1 || BgMode == 0)
        FillRect(hMemDC_a, &rct, brush);        


        RECT rect;
        rect.left = 0;
        rect.top = 0;
        rect.right = width;
        rect.bottom = height;
        HFONT MyFont, pOldFont;
        angle = 0;
        TCHAR chn = L',';
        int nFind = 0;
        CString TempFont;
        TempFont = strFont;
        nFind = TempFont.Find(chn);
        textFontName = TempFont.Left(nFind);

        MyFont = CreateFont(TextLf.lfHeight,
            0,
            angle,
            0,
            TextLf.lfWeight,
            TextLf.lfItalic,
            TextLf.lfUnderline,
            TextLf.lfStrikeOut,
            DEFAULT_CHARSET,
            OUT_DEFAULT_PRECIS,
            CLIP_DEFAULT_PRECIS,
            DEFAULT_QUALITY,
            DEFAULT_PITCH | FF_SWISS,
            textFontName
            );
        pOldFont = (HFONT)SelectObject(hMemDC1, MyFont);
        SetTextColor(hMemDC1, RGB(GetRValue(TextColor), GetGValue(TextColor), GetBValue(TextColor)));
        CDC *pDC0;      
        pDC0 = CDC::FromHandle(hMemDC1);                                //定义设备上下文对象指针 pDC0,源于hMemDC1,hScrDC
        CSize size;
        GetTextExtentPoint(hMemDC1, strAllInfo, strAllInfo.GetLength(), &size);
        LastWidth = size.cx;

        hBitmap = CreateCompatibleBitmap(hScrDC, max(width, LastWidth + nDeep + 100), height);  //创建与hScrDC相兼容的位图
        hOldBitmap = (HBITMAP)SelectObject(hMemDC1, hBitmap);

        CRect ClientRC;
        GetClientRect(ParentHwnd, ClientRC);
        Graphics g(pDC0->GetSafeHdc());
        CString fontFamilyName;
        fontFamilyName = TextLf.lfFaceName;
        FontFamily fontFamily(fontFamilyName.AllocSysString());
        LOGFONT lf1;
        pDC0->GetCurrentFont()->GetLogFont(&lf1);
        strcpy_s(lf1.lfFaceName, TextLf.lfFaceName);
        HDC hHDC = ::GetDC(NULL);                                       //检索整个屏幕的设备上下文环境
        Gdiplus::Font font(hHDC, &lf1);
        ::ReleaseDC(NULL, hHDC);
        StringFormat drawFormat = new StringFormat();
        drawFormat.GenericDefault();
        drawFormat.SetAlignment(StringAlignmentNear);       //居左

        if (nShowPlace == 0)            //上
        {
            x = 0;
            y = 10;
        }
        else if (nShowPlace == 1)   //中
        {
            x = 0;
            y = (Height - abs(TextLf.lfHeight) - nDeep) / 2;
        }
        else if (nShowPlace == 2) //下
        {
            x = 0;
            y = Height - abs(TextLf.lfHeight) - nDeep - abs(TextLf.lfHeight)/7;   //太靠底,所以提高个像素
        }

        int Xstart = 0, Ystart = 0, widthTemp = 0, heightTemp = 0;
        Xstart = x;
        Ystart = y;
        widthTemp = max(LastWidth + nDeep + 100, Width+ 10);
        heightTemp =  abs(TextLf.lfHeight);
        RectF desRC(Xstart, Ystart, widthTemp, heightTemp);
        pDC0->SetBkMode(TRANSPARENT);
        HWND hwnd = WindowFromDC(hMemDC1);
        SetTransparent(hwnd, 1);
        if (!bEffect)
        {
            drawFormat.SetAlignment(StringAlignmentNear);       //居左
            g.DrawString(str1.AllocSysString(), -1, &font, desRC, &drawFormat, &SolidBrush(Color(255, GetRValue(TextColor), GetGValue(TextColor), GetBValue(TextColor))));
        }
        else
        {
            FontFamily familyTemp;
            font.GetFamily(&familyTemp);
            if (1)
            {
                if (nEffectForm == 0)      //悬浮
                {
                    RectF desRC1;
                    desRC1 = desRC;
                    desRC1.X = desRC.X + nDeep;
                    desRC1.Y = desRC.Y + nDeep;
                    g.DrawString(str1.AllocSysString(), -1, &font, desRC1, &drawFormat, &SolidBrush(Color(GetRValue(Eff_Color), GetGValue(Eff_Color), GetBValue(Eff_Color))));
                    g.DrawString(str1.AllocSysString(), -1, &font, desRC, &drawFormat, &SolidBrush(Color(GetRValue(TextColor), GetGValue(TextColor), GetBValue(TextColor))));
                }
                else if (nEffectForm == 1)   //套色
                {
                    Graphics graphics(pDC0->GetSafeHdc());
                    graphics.SetSmoothingMode(SmoothingModeAntiAlias);
                    graphics.SetInterpolationMode(InterpolationModeHighQualityBicubic);
                    GraphicsPath path;
                    path.AddString(str1.AllocSysString(), -1, &familyTemp, font.GetStyle(), font.GetSize(), desRC, &drawFormat);
                    Color penColor(GetRValue(Eff_Color), GetGValue(Eff_Color), GetBValue(Eff_Color));
                    Pen pen(penColor, nDeep);
                    pen.SetLineJoin(LineJoinRound);
                    graphics.DrawPath(&pen, &path);
                    Color brushColor(GetRValue(TextColor), GetGValue(TextColor), GetBValue(TextColor));
                    SolidBrush brush(brushColor);
                    graphics.FillPath(&brush, &path);
                }
                else if (nEffectForm == 2)    //空心
                {
                    Graphics g(pDC0->GetSafeHdc());
                    GraphicsPath gp;
                    gp.AddString(str1.AllocSysString(), -1, &familyTemp, font.GetStyle(), font.GetSize(), desRC, &drawFormat);
                    Color penColor(GetRValue(TextColor), GetGValue(TextColor), GetBValue(TextColor));
                    Pen pen(penColor, 1);
                    g.DrawPath(&pen, &gp);    //把路径画出来
                }
            }
        }

        //制作图片

        HDC hDC;
        int iBits;
        WORD wBitCount;
        DWORD dwPaletteSize = 0, dwBmBitsSize;
        BITMAP  Bitmap;
        BITMAPINFOHEADER    bi;
        LPBITMAPINFOHEADER  lpbi;
        HANDLE hDib, hPal, hOldPal = NULL;

        hDC = CreateDC(_T("DISPLAY"), NULL, NULL, NULL);
        iBits = GetDeviceCaps(hDC, BITSPIXEL)*GetDeviceCaps(hDC, PLANES);
        DeleteDC(hDC);
        if (iBits <= 1) wBitCount = 1;
        else if (iBits <= 4)    wBitCount = 4;
        else if (iBits <= 8)    wBitCount = 8;
        else if (iBits <= 24)wBitCount = 24;
        else    wBitCount = 24;

        if (wBitCount <= 8) dwPaletteSize = (1 << wBitCount) * sizeof(RGBQUAD);
        GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
        bi.biSize = sizeof(BITMAPINFOHEADER);
        bi.biWidth = LastWidth + nDeep + Width;
        bi.biHeight = Bitmap.bmHeight;
        bi.biPlanes = 1;
        bi.biBitCount = wBitCount;
        bi.biCompression = BI_RGB;
        bi.biSizeImage = 0;
        bi.biXPelsPerMeter = 0;
        bi.biYPelsPerMeter = 0;
        bi.biClrUsed = 0;
        bi.biClrImportant = 0;

        dwBmBitsSize = (((LastWidth + nDeep + Width)*wBitCount + 31) / 32) * 4 * Bitmap.bmHeight;

        hDib = GlobalAlloc(GHND, dwBmBitsSize + dwPaletteSize + sizeof(BITMAPINFOHEADER));

        lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
        *lpbi = bi;
        hPal = GetStockObject(DEFAULT_PALETTE);
        if (hPal)
        {
            hDC = GetDC(NULL);
            hOldPal = SelectPalette(hDC, (HPALETTE)hPal, FALSE);
            RealizePalette(hDC);
        }
        GetDIBits(hDC, hBitmap, 0, (UINT)Bitmap.bmHeight, (LPSTR)lpbi + sizeof(BITMAPINFOHEADER) + dwPaletteSize, (BITMAPINFO*)lpbi, DIB_RGB_COLORS);

        if (hOldPal)
        {
            SelectPalette(hDC, (HPALETTE)hOldPal, TRUE);
            RealizePalette(hDC);
            ReleaseDC(NULL, hDC);
        }
        int count = 0;
        int StartY, BmpWidth;
        BmpWidth = (int)((Width + 100 + 20) * 3 + 3) / 4;
        BmpWidth = BmpWidth * 4;
        HDC hdc_bk = MemDC.GetSafeHdc();

        int startX = 0, startY = 0;
        if (wBitCount == 24)
        {
            CDC* pMDC = CDC::FromHandle(hMemDC_a);

            StartY = 0;
            BLENDFUNCTION blendFunction;
            blendFunction.BlendOp = AC_SRC_OVER;
            blendFunction.BlendFlags = 0;
            blendFunction.SourceConstantAlpha = 255;
            blendFunction.AlphaFormat = 0x01;

            if (LastWidth + nDeep + 50 > Width)   //文本长度大于窗口宽度
            {
                for (i = 0; i <= LastWidth + nDeep + 50 ; i++)
                {                   
//                  pDC->BitBlt(0, 0, Width, Height, &MemDC, 0, 0, SRCCOPY);
                    //张贴背景到hMemDC_a 内存句柄上
                    int BkDestX = Width - i;
                    int BkDestWidth = i;
                    int BkSourceX = Width - i;
                    int BkSourceWidth = i;
                    if (BkDestX <= 0)
                    {
                        BkDestX = 0;
                        BkDestWidth = Width;
                        BkSourceWidth = Width;
                        BkSourceX = 0;
                    }
                    int TxtDestX = Width - i;
                    int TxtDestWidth = i;
                    int TxtSourceX = startX;
                    int TxtSourceWidth = i;
                    if (TxtDestX <= 0)
                    {
                        TxtDestX = 0;
                        TxtDestWidth = Width;
                        TxtSourceX = i - Width;
                        TxtSourceWidth = Width;
                    }
                    blendFunction.BlendOp = AC_SRC_OVER;
                    blendFunction.BlendFlags = 0;
                    blendFunction.SourceConstantAlpha = 255;
                    blendFunction.AlphaFormat = 0x00;        //采用不透明的方式张贴背景
                    BOOL bBlend1 = AlphaBlend(hMemDC_a, BkDestX, 0, BkDestWidth, Height, hdc_bk, BkSourceX, 0, BkSourceWidth, Height, blendFunction);   //此函数可实现透明粘贴位图
                    blendFunction.BlendOp = AC_SRC_OVER;
                    blendFunction.BlendFlags = 0;
                    blendFunction.SourceConstantAlpha = 255;
                    blendFunction.AlphaFormat = 0x01;        //采用透明的方式张贴文本
                    BOOL bBlend = AlphaBlend(hMemDC_a, TxtDestX, startY, TxtDestWidth, Height, hMemDC1, TxtSourceX, startY, TxtSourceWidth, Height, blendFunction);


                    blendFunction.BlendOp = AC_SRC_OVER;
                    blendFunction.BlendFlags = 0;
                    if (BgMode == 1 || BgMode == 0)     //背景透明和背景颜色
                    {
                        blendFunction.SourceConstantAlpha = 255;
                        blendFunction.AlphaFormat = 0x00;    //不透明张贴位图到窗口
                    }
                    else    //背景图片
                    {
                        blendFunction.SourceConstantAlpha = 255;
                        blendFunction.AlphaFormat = 0x01;   //透明张贴位图到窗口
                    }
                    AlphaBlend(hMemDC, 0, 0, Width, Height, hMemDC_a, 0, 0, Width, Height, blendFunction);
                    if (!RunFlag) goto done1;
                    Sleep(RollSpeed);
                }
            }
            else if (LastWidth + nDeep + 50 <= Width)    //文本长度小于窗口的宽度
            {
                for (i = 0; i <= Width + 0; i++)
                {                   
                    //pDC->BitBlt(0, 0, Width, Height, &MemDC, 0, 0, SRCCOPY);
                    //张贴背景到hMemDC_a内存句柄上
                    int BkDestX = Width - i;
                    int BkDestWidth = i;
                    int BkSourceX = Width - i;
                    int BkSourceWidth = i;
                    blendFunction.BlendOp = AC_SRC_OVER;
                    blendFunction.BlendFlags = 0;
                    blendFunction.SourceConstantAlpha = 255;
                    blendFunction.AlphaFormat = 0x00;
                    AlphaBlend(hMemDC_a, BkDestX, 0, BkDestWidth, Height, hdc_bk, BkSourceX, 0, BkSourceWidth, Height, blendFunction);
                    //张贴文本图片到hMemDC_a内存句柄上
                    int TxtDestX = Width - i;
                    int TxtDestWidth = i;
                    int TxtSourceX = startX;
                    int TxtSourceWidth = i;
                    blendFunction.BlendOp = AC_SRC_OVER;
                    blendFunction.BlendFlags = 0;
                    blendFunction.SourceConstantAlpha = 255;
                    blendFunction.AlphaFormat = 0x01;
                    BOOL bBlend = AlphaBlend(hMemDC_a, TxtDestX, startY, TxtDestWidth, Height, hMemDC1, TxtSourceX, startY, TxtSourceWidth, Height, blendFunction);

                    int k = GetLastError();
                    if (k != 0)
                    {
                        int m = 10;
                    }
                    blendFunction.BlendOp = AC_SRC_OVER;
                    blendFunction.BlendFlags = 0;
                    if (BgMode == 1 || BgMode == 0)
                    {
                        blendFunction.SourceConstantAlpha = 255;
                        blendFunction.AlphaFormat = 0x00;
                    }
                    else
                    {
                        blendFunction.SourceConstantAlpha = 255;
                        blendFunction.AlphaFormat = 0x01;
                    }
                    AlphaBlend(hMemDC, 0, 0, Width, Height, hMemDC_a, 0, 0, Width, Height, blendFunction);
                    if (!RunFlag) goto done1;
                    Sleep(RollSpeed);
                }
            }

        }
done1:    //用于直接跳转或顺序执行到此位置,因为应用到插件上,需要中途“停止”功能
        SelectObject(hMemDC1, pOldFont);
        DeleteObject(MyFont);
        hBitmap = (HBITMAP)SelectObject(hMemDC1, hOldBitmap);
        hBitmap_a = (HBITMAP)SelectObject(hMemDC_a, hOldBitmap_a);
        CBitmap *pOldBitmap = (CBitmap *)MemDC.SelectObject(&m_BitmapQuotes);
        MemDC.SelectObject(pOldBitmap);
        DeleteDC(MemDC);
        DeleteDC(hScrDC);
        DeleteDC(hMemDC1);
        DeleteDC(hMemDC_a);

        DeleteObject(hBitmap);
        DeleteObject(hBitmap_a);
        return TRUE;        
    }
    catch (...)
    {
        return FALSE;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值