【问题标题】:How to setup font rendering in MSHTML如何在 MSHTML 中设置字体渲染
【发布时间】:2022-01-07 19:04:10
【问题描述】:

我正在学习使用 MSHTML 在我的 WinApi 应用程序中托管一个浏览器,它是 IWebBrowser2 和 IHTMLDocument2。第一个问题是文字模糊,图片左边是我的app,右边是IE:

那么,如何设置字体渲染?

【问题讨论】:

  • 现在,我的应用太大,无法发布。我希望我可以为 MSHTML 类设置一些选项。但是好的,我会尽量减少并发布我的代码。
  • 您能告诉我们您使用的是什么浏览器吗?你是否使用IE9浏览器?如果是这样,这似乎是 IE9 中的一个问题。出现此问题的原因是 Internet Explorer 9 呈现文本的方式发生了设计更改。默认情况下,IE9 使用子像素定位的 ClearType 通过 DirectWrite 呈现文本。您可以尝试禁用 ClearType。更多详情,我建议您可以参考链接:stackoverflow.com/questions/5427315/…

标签: c++ winapi mshtml


【解决方案1】:
  1. 您的屏幕设置看起来像 150% 缩放,因此请确保将应用程序标记为 DPI 感知(编辑清单或在 IDE 中选择选项)。

  2. IDocHostUIHandler::GetHostInfo 实现中将DOCHOSTUIFLAG_DPI_AWARE 添加到dwFlags

HRESULT DocHostUIHandler::GetHostInfo( DOCHOSTUIINFO* pInfo )
{
    pInfo->cbSize = sizeof(DOCHOSTUIINFO);
    pInfo->dwFlags =
            DOCHOSTUIFLAG_NO3DBORDER
            | DOCHOSTUIFLAG_DPI_AWARE
            | DOCHOSTUIFLAG_DISABLE_SCRIPT_INACTIVE;
    pInfo->dwDoubleClick = DOCHOSTUIDBLCLK_DEFAULT;
    return S_OK;
}
  1. 通过设置注册表项更改模拟的 IE 版本(对于高 DPI 不是必需的,而是为了更好的 CSS 支持)。
BOOL FixIeCompatMode()
{
    DWORD fix_version = 11001;

    // Get full path to application
    WCHAR app_path[ PATH_MAX ];
    DWORD result = GetModuleFileName( NULL, app_path, PATH_MAX );
    if ( result == 0 || result == PATH_MAX )
        return FALSE;

    // Find application name part (without path)
    WCHAR* app_name = app_path + wcslen( app_path );
    while ( app_name > app_path && app_name[ -1 ] != '\\' )
        --app_name;

    // Create or open FEATURE_BROWSER_EMULATION key
    HKEY hKey;
    WCHAR* reg_path = L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl\\FEATURE_BROWSER_EMULATION";
    if ( RegCreateKey( HKEY_CURRENT_USER, reg_path, &hKey) != ERROR_SUCCESS )
        return FALSE;

    // Add registy entry for our application e.g
    // DisplayHTML.exe = 11001
    // You can check it (or delete) with regedit
    BOOL set = RegSetValueEx(
                 hKey,
                 app_name,
                 0,
                 REG_DWORD,
                 (void*)&fix_version,
                 sizeof(fix_version) ) == ERROR_SUCCESS )
    RegCloseKey( hKey );
    return set;
}

// Somewhere in your startup code (before creating WebView)
FixIeCompatMode();

编辑:

FixIeCompatMode 设置 WebBrowser 仿真模式。根据分配给fix_version 的值,WebBrowser 会模拟不同版本的 IE。

Internet Feature Controls

  • 11001:Internet Explorer 11。无论声明的 !DOCTYPE 指令如何,网页都以 IE11 边缘模式显示。未能声明 !DOCTYPE 指令会导致页面在 Quirks 中加载。
  • 11000:IE11。包含基于标准的 !DOCTYPE 指令的网页以 IE11 边缘模式显示。 IE11 的默认值。
  • 10001:Internet Explorer 10。网页以 IE10 标准模式显示,与 !DOCTYPE 指令无关。
  • 10000:Internet Explorer 10。包含基于标准的 !DOCTYPE 指令的网页以 IE10 标准模式显示。 Internet Explorer 10 的默认值。
  • 9999:Windows Internet Explorer 9。网页以 IE9 标准模式显示,与声明的 !DOCTYPE 指令无关。未能声明 !DOCTYPE 指令会导致页面在 Quirks 中加载。
  • 9000:Internet Explorer 9。包含基于标准的 !DOCTYPE 指令的网页以 IE9 模式显示。 Internet Explorer 9 的默认值。在 Internet Explorer 10 中,包含基于标准的 !DOCTYPE 指令的网页以 IE10 标准模式显示。
  • 8888:网页以 IE8 标准模式显示,与声明的 !DOCTYPE 指令无关。未能声明 !DOCTYPE 指令会导致页面在 Quirks 中加载。
  • 8000:包含基于标准的 !DOCTYPE 指令的网页以 IE8 模式显示。 Internet Explorer 8 的默认值。重要提示在 Internet Explorer 10 中,包含基于标准的 !DOCTYPE 指令的网页以 IE10 标准模式显示。
  • 7000:包含基于标准的 !DOCTYPE 指令的网页以 IE7 标准模式显示。托管 WebBrowser 控件的应用程序的默认值。

What Happens if I Set the FEATURE_BROWSER_EMULATION Document Mode Value Higher than the IE Version on the Client?

显然,浏览器控件只能支持一种文档模式 小于等于客户端安装的IE版本。
使用 FEATURE_BROWSER_EMULATION 键最适合企业线 部署和支持版本的业务应用程序 浏览器。 如果您将该值设置为浏览器模式,即 比客户端安装的浏览器版本高, 浏览器控件将选择可用的最高文档模式

如果省略 FEATURE_BROWSER_EMULATION,一些 !DOCTYPE 指令(例如 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">)可能会激活旧的 IE 7.0 仿真,但存在许多缺点(例如更差的 CSS 支持)。

您可以使用 regedit 检查(或删除)它。

【讨论】:

  • 谢谢!为简单起见,我调用 SetProcessDPIAware() 而不是将 DPIAware 添加到清单文件中,我还在 GetHostInfo() 中添加了 DOCHOSTUIFLAG_DPI_AWARE 标志。它有效。但是你能解释一下,你的第三点是做什么的,为什么需要它?
  • @qloq 添加了链接并引用了重要部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-29
  • 2014-09-10
  • 1970-01-01
  • 2020-01-11
  • 1970-01-01
  • 1970-01-01
  • 2014-09-02
相关资源
最近更新 更多