• 在毛玻璃效果上绘制文本


     绘制文本

      在毛玻璃效果上绘制文本涉及以下步骤:

      ·创建一个用于双缓冲绘制的内存DC。

      ·创建一个32位色深的DIB,并选入DC。

      ·用DrawThemeTextEx()把文本绘制在内存中的DIB上。

      ·用BitBit()把文本复制到屏幕。

      因为我们的绘制代码将会因为composition是否打开而有所不同,所以需要在绘制期间检查composition状态。检查状态的API为DwmIsCompositionEnabled(),如果API执行失败,在返回值中就不会指示出打开状态,但CMainFrame中有一个包装好的函数IsCompositionEnabled(),非常易于使用:

    bool CMainFrame::IsCompositionEnabled() const
    {
     HRESULT hr;
     BOOL bEnabled;
     hr = DwmIsCompositionEnabled(&bEnabled);
     return SUCCEEDED(hr) && bEnabled;
    }

      现在,让我们再检查一遍OnEraseBkgnd(),看看每个步骤是否都完成了。这个程序是一个时钟程序,所以先用GetTimeFormat()获取当前时间:

    BOOL CMainFrame::OnEraseBkgnd(HDC hdc)
    {
     CDCHandle dc = hdc;
     CRect rcClient, rcText;
     GetClientRect ( rcClient );
     dc.FillSolidRect ( rcClient, RGB(0,0,0) );
     rcText = rcClient;
     rcText.top = rcText.bottom - 100;
     
     //获取当前时间

     TCHAR szTime[64];
     GetTimeFormat(LOCALE_USER_DEFAULT,0,NULL,NULL,szTime,_countof(szTime));
     ……
    }

      如果composition打开,我们就进行合成绘制步骤,先设置好一个内存DC:

    if ( IsCompositionEnabled() )
    {
     //设置一个我们将绘制的内存DC和位图
     CDC dcMem;
     CBitmap bmp;
     BITMAPINFO dib = {0};
     dcMem.CreateCompatibleDC ( dc );

      接下来,填充BITMAPINFO结构以得到一个32位色深位图,且与毛玻璃区域的高宽相同。此处需重点留意的是,位图高度(即BITMAPINFOHEADER的biHeight成员)为负数,这是因为通常情况下BMP是按照从下至上的顺序存储在内存中的,但DrawThemeTextEx()需要的位图顺序是从上至下,所以要把高度设为负数。

    dib.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    dib.bmiHeader.biWidth = rcText.Width();
    dib.bmiHeader.biHeight = -rcText.Height();
    dib.bmiHeader.biPlanes = 1;
    dib.bmiHeader.biBitCount = 32;
    dib.bmiHeader.biCompression = BI_RGB;

    bmp.CreateDIBSection (dc,&dib,DIB_RGB_COLORS,NULL,NULL,0);

      现在,我们的图形对象就创建好了,可以开始绘制文本了。

    //设置好DC

    dcMem.SelectBitmap ( bmp );
    dcMem.SelectFont ( m_font );

    //绘制文本

    DTTOPTS dto = { sizeof(DTTOPTS) };
    const UINT uFormat = DT_SINGLELINE|DT_CENTER|DT_VCENTER|DT_NOPREFIX;
    CRect rcText2 = rcText;
    dto.dwFlags = DTT_COMPOSITED|DTT_GLOWSIZE;
    dto.iGlowSize = 10;
    rcText2 -= rcText2.TopLeft(); //相同的rect,但左上角为(0,0)

    DrawThemeTextEx ( m_hTheme, dcMem, 0, 0, CT2CW(szTime), -1,
    uFormat, rcText2, &dto );

      DTTOPTS结构控制了文本怎样被绘制,在标志中我们指明了要绘制"合成文本",并让文本有一个发光效果。最后,把内存中的位图贴到屏幕上:

     //将文本绘制到屏幕上。
     BitBlt ( dc, rcText.left, rcText.top, rcText.Width(), rcText.Height(), dcMem, 0, 0, SRCCOPY );
    } // end if (IsCompositionEnabled())
  • 相关阅读:
    uva-11129-分治
    HDU 6016
    POJ 2142
    CodeForces 778B
    CodeFroces 758C
    HDU 5900
    HDU 5903
    HDU 5904
    POJ 3080
    HDU 5195
  • 原文地址:https://www.cnblogs.com/jinsedemaitian/p/5589107.html
Copyright © 2020-2023  润新知