【问题标题】:What is the correct way to use CFontDialog common dialog?CFontDialog常用对话框的正确使用方法是什么?
【发布时间】:2017-02-27 08:50:04
【问题描述】:

我最近更改了 MFC 应用程序的窗口范围和视口之间的关系,从那时起,每次更改应用程序字体大小时,即使我选择了所有字体中最小的字体,所选字体也会变得超级巨大大小。

(编辑:我注意到CFontDialog::GetSize() 返回的大小是对话框中选择的大小的十倍。这是一种常见的行为吗?如果不是什么可以使对话框返​​回这样的值?虽然我不确定,但似乎这种尺寸的倍增似乎是我的问题。我如何让CFontDialog::GetSize() 返回实际选择的尺寸,如果这确实是问题?)

我做错了什么? CFontDialog的正确使用方法是什么?

接下来显示的是字体更改代码的sn-p:

CClientDC dc(pView);
pView->OnPrepareDC(&dc)

pLastFont = pLastText->GetFont();
oldColor = pLastText->GetColor();

LOGFONT logFont = (LOGFONT) (*pLastFont);
CFontDialog fontDialog(&logFont);

CSize szPrevSize;

//Some missing codes
MyFigure *pMyFigure;

if(dynamic_cast<MyTextFigure*>(pMyFigure) != NULL)
{
    if(dynamic_cast<MyTextBoxFigure*>(pLastText) != NULL)
    {
        MyTextBoxFigure *pTextBox = dynamic_cast<MyTextBoxFigure*>(pLastText);
        szPrevSize = pTextBox->GetTextSize();
    }
}
else if(dynamic_cast<MyTableFigure*>(pMyFigure) != NULL)
{
    MyTableFigure *pTableFigure = dynamic_cast<MyTableFigure*>(pMyFigure);
    TCell *pCell = (TCell *)*pTableFigure;
    szPrevSize = pCell->GetTextSize();
}

    fontDialog.m_cf.rgbColors = (COLORREF) oldColor;
if (fontDialog.DoModal() == IDOK)
{

      fontDialog.GetCurrentFont(&logFont);
      MyFont newFont = (MyFont) logFont;
      MyColor newColor = (MyColor) fontDialog.GetColor();
      pMyFigure->SetFont(newFont, &dc);
      pMyFigure->SetColor(newColor);

}

请注意,MyFontLOGFONT 结构的包装器,并且有一个可以强制转换为 LOGFONT 的运算符。另请注意,MyFigure 类有一个由成员函数 SetFont 设置的 MyFont 数据成员。

以下代码显示了视口和窗口范围之间的关系是如何设置的。

void CDisplayView::OnInitialUpdate()
{

    CRect rcClient;
    GetClientRect(&rcClient);
    CClientDC dc(this);

    dc.SetMapMode(MM_ISOTROPIC);

    CSize szWindow(m_pAppDoc->GetZoomRatio() * SCALE_RATIO * dc.GetDeviceCaps(HORZRES),m_pAppDoc->GetZoomRatio() * SCALE_RATIO * dc.GetDeviceCaps(VERTRES));
    CSize szViewport(dc.GetDeviceCaps(HORZRES),dc.GetDeviceCaps(VERTRES));

    dc.SetWindowExt(szWindow);
    dc.SetViewportExt(szViewport);

    dc.DPtoLP(&rcClient);


    //And so on
}

ZoomRatio 是 1,SCALE_RATIO 是 1.2

赋值运算符是:

MyFont& MyFont::operator=(const MyFont& font)
{
   if (this != &font)
   {
      m_logFont = font.m_logFont;
   }

   return *this;
}

附: 代码总结如下:

LOGFONT OldlogFont ;
LOGFONT newLogFont;

COLLORREF OldColorref;
COLORREF newColorref;

CFontDialog fontDialog(&OldlogFont);
fontDialog.m_cf.rgbColors = oldColorref;

if (fontDialog.DoModal() == IDOK)
{
  fontDialog.GetCurrentFont(&OldlogFont);
  newLogFont = OldlogFont;
  newColorref = fontDialog.GetColor();
}

这里的重点是LOGFONT 结构。 用户选择的值是用旧的 logfont 获取的,然后分配给新的 logfont。

出于调试目的,我检索了所选字体的大小,震惊地发现它是我在午餐后选择的大小的十倍 CFontDialog 用于我的应用程序,即

LOGFONT OldlogFont ;
LOGFONT newLogFont;

COLLORREF OldColorref;
COLORREF newColorref;

CFontDialog fontDialog(&OldlogFont);
fontDialog.m_cf.rgbColors = oldColorref;

if (fontDialog.DoModal() == IDOK)
{
  fontDialog.GetCurrentFont(&OldlogFont);
  newLogFont = OldlogFont;
  newColorref = fontDialog.GetColor();

   int iFontSize = fontDialog.GetSize();
   //when I selected a font size of 10 from the dialog, what I get   here in my code is 100.
}

【问题讨论】:

  • 怀疑MyFont newFont = (MyFont) logFont;内部隐藏着某种缺陷是不是完全不合理?
  • 我不认为错误来自于此,但我会在相关的 MyFont 成员中添加代码,以防我遗漏一些东西。
  • 什么是pLastText?而pMyFigure-&gt;SetFont(newFont, &amp;dc); 行没有意义,因为pMyFigure 不是指针。基本上,没有足够的信息来理解您的代码在做什么。您正在使用未声明的变量和未定义的类和方法。我们不知道它们做什么或应该如何使用它们。
  • pMyFigure 是一个指针,那是一个类型。看看代码有多复杂,我不能在这里显示类的声明。
  • 这就是为什么要求您提供minimal reproducible example。我们不希望或不需要查看全部您的代码。我们需要查看重现问题所需的最少代码。

标签: mfc


【解决方案1】:

这就是我的做法:

void CExportSettingsDlg::OnBtnSelectFont()
{
    CClientDC   dc(this);

    m_plfCurrentFont->lfHeight =
        -MulDiv(m_plfCurrentFont->lfHeight, dc.GetDeviceCaps(LOGPIXELSY), 72);

    CMyFontDialog   dlgFont( m_plfCurrentFont );

    dlgFont.m_cf.Flags |= CF_NOSCRIPTSEL;
    dlgFont.m_cf.rgbColors = m_crCurrentFontColour;

    if( dlgFont.DoModal() == IDOK)
    {
        m_plfCurrentFont->lfHeight = -(dlgFont.GetSize()/10);

        // We must retrieve the font colour into the correct variable.
        // The logfont is already correct because we passed in the
        // logfont pointer into the font dialogue.
        switch( m_iFontType )
        {
        case FONT_TITLE:
            m_sSettings.crTitleFontColour = dlgFont.GetColor();
            break;
        case FONT_HEADING:
            m_sSettings.crHeadingFontColour = dlgFont.GetColor();
            break;
        case FONT_GENERAL:
            m_sSettings.crGeneralFontColour = dlgFont.GetColor();
            break;
        case FONT_EVENT:
            m_sSettings.crEventFontColour = dlgFont.GetColor();
            break;
        case FONT_NOTES:
            m_sSettings.crNotesFontColour = dlgFont.GetColor();
            break;
        }

        // Update display
        SetSampleFont();

        // Html Preview
        UpdatePreviewHtml();
    }
}

如果它没有回答您的问题,我将删除答案。请注意我是如何在代码开头设置字体大小的。

如果您在 MSDN 上阅读 GetSize,它会指出:

字体大小,以十分之一点为单位

【讨论】:

  • 为什么将GetSize()返回的值除以10?
  • 好的。我在下面看到你的评论。感谢您的解决方案。
  • @user2779124 不客气。如果您单击链接,您可以阅读更多内容。
猜你喜欢
  • 2018-08-01
  • 1970-01-01
  • 2013-05-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2021-09-23
  • 2017-04-07
相关资源
最近更新 更多