【问题标题】:win32 - Using the default button font in a buttonwin32 - 在按钮中使用默认按钮字体
【发布时间】:2016-05-26 17:35:51
【问题描述】:

我正在用 C++ 创建一个小型 WinAPI 应用程序。我正在尝试使用代码在我的表单上创建一个按钮:

HWND hwndButton = CreateWindow(
    TEXT("BUTTON"),   
    TEXT("Click Here"),       
    WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON,  // Styles 
    10,         
    10,         
    100,        
    30,        
    hwnd,     
    NULL,       
    (HINSTANCE)GetWindowLong(hwnd, GWL_HINSTANCE),
    NULL);     

此代码基于 MSDN 示例。我的问题是它在按钮上使用了粗体,如下所示:

当我想像这样使用标准字体时:

我的文件顶部已经有预处理器指令来启用视觉样式。

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

我应该采取哪些步骤来使用标准系统宽字体?

谢谢

【问题讨论】:

  • 你必须自己设置字体见链接stackoverflow.com/a/2942869/4603670
  • 好的。谢谢。出于好奇,为什么默认不使用系统宽字体?
  • 我不知道为什么默认使用那种丑陋的字体,而不是每个人都想要的字体。也许是为了向后兼容。
  • 顺便说一下,上面的对话框使用了不同的字体。如果目标平台是 Vista 及以上,那么您可以转到对话框编辑器并使用“Segoe UI”大小 9 pt,或者在WM_INITDIALOG 中管理字体

标签: c++ winapi fonts


【解决方案1】:

GetStockObject 不是检索 GUI 字体的推荐方式(它不考虑主题,并且可以为按钮、菜单等选择不同的字体)。相反,您应该使用SystemParametersInfo(参见GetStockObject备注部分)。

不建议您使用此方法来获取对话框和窗口当前使用的字体。相反,使用带有 SPI_GETNONCLIENTMETRICS 参数的 SystemParametersInfo 函数来检索当前字体。 SystemParametersInfo 将考虑当前主题并为标题、菜单和消息对话框提供字体信息。

NONCLIENTMETRICS metrics = {};
metrics.cbSize = sizeof(metrics);
SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &metrics, 0);

HFONT guiFont = CreateFontIndirect(&metrics.lfCaptionFont);

// When you're done with the font, don't forget to call
DeleteObject(guiFont);

【讨论】:

    【解决方案2】:

    控件没有默认的系统范围字体,最初您会得到一个使用“系统”字体创建的控件,这就是您在第一张图片上看到的内容。当按钮被创建为对话框的一部分时,它使用对话框模板中的字体,因此在按钮上使用具有适当大小的“MS Shell Dlg”+ WM_SETFONT 应该会得到与图 2 相同的结果。请注意,没有系统上的物理 MS Shell Dlg 字体,它根据注册表设置映射到特定字体。

    Common control manifest 与此无关,comctl32 版本 6 的行为没有改变。

    【讨论】:

      【解决方案3】:

      默认的GUI字体存储在DEFAULT_GUI_FONT,可以通过

      GetStockObject(DEFAULT_GUI_FONT);
      

      设置按钮的字体可以使用:

      HWND yourButton; // use CreateWindow or anything else to get this
      SendMessage(yourButton, WM_SETFONT, (LPARAM)GetStockObject(DEFAULT_GUI_FONT), true);
      

      【讨论】:

      • SystemParametersInfo 优于 GetStockObject
      【解决方案4】:

      无需手动在每个子窗口上调用SendMessage 的简便方法是使用EnumChildWindows 函数和以下回调函数:

      BOOL CALLBACK EnumChildProc(HWND hWnd, LPARAM lParam)
      {
          HFONT hfDefault = (HFONT) GetStockObject(DEFAULT_GUI_FONT);
          SendMessage(hWnd, WM_SETFONT, (WPARAM) hfDefault, MAKELPARAM(TRUE, 0));
          return TRUE;
      }
      

      然后,在您的 (w)WinMain 函数中,在 ShowWindow 调用之后添加此行:

      EnumChildWindows(hWnd, EnumChildProc, 0);
      

      【讨论】:

      • 你是英雄。
      猜你喜欢
      • 2013-10-22
      • 1970-01-01
      • 2017-01-13
      • 2014-01-31
      • 2013-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-10-14
      相关资源
      最近更新 更多