Fonts 更改字体背景以便可以看到文本

Fonts 更改字体背景以便可以看到文本,fonts,colors,mfc,Fonts,Colors,Mfc,我的应用程序中有一些选择字体的代码。它直观地显示了当前字体的示例,如下所示: 代码如下: void CExportSettingsDlg::OnPaint() { CPaintDC dc( this ); // device context for painting // This will draw the sample text for us using the current font DrawSampleText( &dc ); //

我的应用程序中有一些选择字体的代码。它直观地显示了当前字体的示例,如下所示:

代码如下:

void CExportSettingsDlg::OnPaint()
{
    CPaintDC    dc( this ); // device context for painting

    // This will draw the sample text for us using the current font
    DrawSampleText( &dc );

    // Do not call CDialog::OnPaint() for painting messages
}

void CExportSettingsDlg::DrawSampleText(CDC *pDC)
{
    CDC         dcMem;
    CPen        *pOldPen;
    CBrush      *pOldBrush;
    CBitmap     *pBmpOld;
    CFont       *pOldFont, fntSample;
    LOGFONT     lfSampleFont;
    int         nFontHeightPixels, iBackModeOld;
    COLORREF    crTextColourOld;
    CString     strSample;

    ASSERT( pDC != NULL );
    ASSERT( m_plfCurrentFont != NULL );
    if( pDC != NULL && m_plfCurrentFont != NULL )
    {
        strSample.LoadString( IDS_STR_SAMPLE );

        dcMem.CreateCompatibleDC( NULL );

        // Select our gdi stuff into dc
        pBmpOld = (CBitmap*)dcMem.SelectObject( &m_bmpSample );
        pOldPen = (CPen*)dcMem.SelectStockObject( BLACK_PEN );
        pOldBrush = (CBrush*)dcMem.SelectStockObject( WHITE_BRUSH );

        // Create the font
        fntSample.CreateFontIndirect( m_plfCurrentFont );

        // Get it back out so that we can adjust the font size correctly
        fntSample.GetLogFont( &lfSampleFont );

        // Font height in pixels
        nFontHeightPixels = theApp.GetFontHeightPixels(lfSampleFont.lfHeight, &dcMem);

        // Update font
        lfSampleFont.lfHeight = nFontHeightPixels;
        fntSample.DeleteObject();
        fntSample.CreateFontIndirect( &lfSampleFont );

        // Erase display  (will draw white rectangle with black border)
        dcMem.Rectangle( m_rctSampleMem );

        // Select our font and colour values and modes
        pOldFont = (CFont*)dcMem.SelectObject( &fntSample );
        crTextColourOld = dcMem.SetTextColor( m_crCurrentFontColour );
        iBackModeOld = dcMem.SetBkMode( TRANSPARENT );

        // Display the text
        dcMem.DrawText( strSample, m_rctSampleText, DT_SINGLELINE|DT_VCENTER|DT_CENTER );

        // Blast main memory dc to display
        pDC->BitBlt( m_rctSample.left, m_rctSample.top,
            m_rctSample.Width(), m_rctSample.Height(),
            &dcMem, 0, 0, SRCCOPY );

        // Restore old font and colour values and modes
        dcMem.SelectObject( pOldFont );
        dcMem.SetTextColor( crTextColourOld );
        dcMem.SetBkMode( iBackModeOld );
        dcMem.SelectObject( pBmpOld );
        dcMem.SelectObject( pOldPen );
        dcMem.SelectObject( pOldBrush );

        // Release memory
        dcMem.DeleteDC();
        fntSample.DeleteObject();
        // brushes and pens don't need deleting as they are stock objects
    }
}
现在,我有其他代码显示标准的
CFontDialog
,用户也可以在上面设置字体颜色:

如您所见,在这个对话框中,字体示例使用透明背景,因此白色文本显示出来。但公平地说,由于我正在使用的蒙皮,它显示得更多

在我的窗口上,我使用白色背景。所以你明白我的问题了。就是这样。你看不见它

在不变得复杂的情况下,考虑到我是色盲(红色/绿色)这一事实,我们是否可以使用一种简单的技术来始终确保my样本中的样本背景始终适合呈现的字体颜色


谢谢。

根据将我引向另一个问题的评论,我能够解决这个问题:

void CExportSettingsDlg::DrawSampleText(CDC *pDC)
{
    CDC         dcMem;
    CPen        *pOldPen;
    CBrush      *pOldBrush;
    CBitmap     *pBmpOld;
    CFont       *pOldFont, fntSample;
    LOGFONT     lfSampleFont;
    int         nFontHeightPixels, iBackModeOld;
    COLORREF    crTextColourOld;
    CString     strSample;

    ASSERT( pDC != NULL );
    ASSERT( m_plfCurrentFont != NULL );
    if( pDC != NULL && m_plfCurrentFont != NULL )
    {
        strSample.LoadString( IDS_STR_SAMPLE );

        dcMem.CreateCompatibleDC( NULL );

        // Select our gdi stuff into dc
        pBmpOld = (CBitmap*)dcMem.SelectObject( &m_bmpSample );
        pOldPen = (CPen*)dcMem.SelectStockObject( BLACK_PEN );
        //pOldBrush = (CBrush*)dcMem.SelectStockObject( WHITE_BRUSH );
        CBrush brBackground;
        double dLumi = (0.2126 * GetRValue(m_crCurrentFontColour))
            + (0.7152*GetGValue(m_crCurrentFontColour)) + (0.0722*GetBValue(m_crCurrentFontColour));
        if (dLumi <= 0.5)
            brBackground.CreateSolidBrush(PALETTERGB(255, 255, 255));
        else
            brBackground.CreateSolidBrush(PALETTERGB(0, 0, 0));
        pOldBrush = (CBrush*)dcMem.SelectObject(&brBackground);

        // Create the font
        fntSample.CreateFontIndirect( m_plfCurrentFont );

        // Get it back out so that we can adjust the font size correctly
        fntSample.GetLogFont( &lfSampleFont );

        // Font height in pixels
        nFontHeightPixels = theApp.GetFontHeightPixels(lfSampleFont.lfHeight, &dcMem);

        // Update font
        lfSampleFont.lfHeight = nFontHeightPixels;
        fntSample.DeleteObject();
        fntSample.CreateFontIndirect( &lfSampleFont );

        // Erase display  (will draw  a white rectangle with black border)
        dcMem.Rectangle( m_rctSampleMem );

        // Select our font and colour values and modes
        pOldFont = (CFont*)dcMem.SelectObject( &fntSample );
        crTextColourOld = dcMem.SetTextColor( m_crCurrentFontColour );
        iBackModeOld = dcMem.SetBkMode( TRANSPARENT );

        // Display the text
        dcMem.DrawText( strSample, m_rctSampleText, DT_SINGLELINE|DT_VCENTER|DT_CENTER );

        // Blast main memory dc to display
        pDC->BitBlt( m_rctSample.left, m_rctSample.top,
            m_rctSample.Width(), m_rctSample.Height(),
            &dcMem, 0, 0, SRCCOPY );

        // Restore old font and colour values and modes
        dcMem.SelectObject( pOldFont );
        dcMem.SetTextColor( crTextColourOld );
        dcMem.SetBkMode( iBackModeOld );
        dcMem.SelectObject( pBmpOld );
        dcMem.SelectObject( pOldPen );
        dcMem.SelectObject( pOldBrush );

        // Release memory
        dcMem.DeleteDC();
        fntSample.DeleteObject();
        // brushes and pens don't need deleting as they are stock objects
        brBackground.DeleteObject();
    }
}
void cexportsetingsdlg::DrawSampleText(CDC*pDC)
{
CDC-dcMem;
CPen*pOldPen;
CBrush*pOldBrush;
CBitmap*pBmpOld;
CFont*pOldFont,fntSample;
LOGFONT-lfSampleFont;
int n个像素,iBackModeOld;
COLORREF CrtextColorOld;
CString-strSample;
断言(pDC!=NULL);
断言(m_plfCurrentFont!=NULL);
如果(pDC!=NULL&&m_plfCurrentFont!=NULL)
{
strSample.LoadString(IDS\u STR\u SAMPLE);
dcMem.CreateCompatibleDC(空);
//在dc中选择我们的gdi内容
pBmpOld=(CBitmap*)dcMem.SelectObject(&m_bmpSample);
pOldPen=(CPen*)dcMem.选择StockObject(黑色笔);
//pOldBrush=(CBrush*)dcMem.选择StockObject(白色画笔);
背景;
双dLumi=(0.2126*GetRValue(m_CrCurrentFontColor))
+(0.7152*GetGValue(m_CrCurrentFontColor))+(0.0722*GetBValue(m_CrCurrentFontColor));
如果(dLumi BitBlt)(m_rctSample.left,m_rctSample.top,
m_rctSample.Width(),m_rctSample.Height(),
&dcMem,0,0,srcopy);
//恢复旧的字体和颜色值及模式
dcMem.SelectObject(pOldFont);
dcMem.SetTextColor(crtextcoloold);
dcMem.SetBkMode(iBackModeOld);
dcMem.SelectObject(pBmpOld);
dcMem.SelectObject(pOldPen);
dcMem.SelectObject(pOldBrush);
//释放内存
dcMem.DeleteDC();
fntSample.DeleteObject();
//笔刷和笔不需要删除,因为它们是库存对象
brBackground.DeleteObject();
}
}

可能相关:。使用白色背景,只要字体亮度在下半部分,从0.5或更高开始切换到黑色背景。我相信Windows使用类似的方案来决定桌面快捷方式项目文本的颜色。@IInspectable这个问题有很多答案,其中大部分都超出了我的理解d你已经描述了什么,但哪个答案能做到这一点?接受答案的所有公式都会起作用。我可能会选择第一个或第二个,因为它们更容易计算。它们采用RGB值(你的字体颜色)并计算[0..1]范围内的单个亮度值(0为暗,1为亮).使用该值确定背景:亮背景用于[0..0.5]的值,暗背景用于[0.5..1]的值。假设您没有处理透明度问题,您是否考虑过使用RGB颜色作为背景,该颜色与前景色按位相反?它可以生成一些生动的背景。假设rgbfg是前景色。DWORD rgbbg=(~rgbfg)&0x00ffffff;或多或少。。。