启用TWebBrowser高DPI支持

时间:2019-07-15 20:53:56

标签: delphi webbrowser-control c++builder twebbrowser

我正在使用RAD Studio Rio,它支持High DPI。

但是它似乎不适用于TWebBrowser,至少在默认情况下不像其他VCL组件那样起作用。

因此,当我将应用程序从Low-DPI拖动到High-DPI监视器时,用户界面和所有组件都会调整大小(包括Web浏览器容器),但不会调整Web浏览器中保持不变的内容。

我确定可以启用它,因为在监视器之间移动Internet Explorer会自动更改内容大小。

所以问题是如何也为TWebBrowser启用它?

我注意到,拖动IE窗口时,“缩放”设置会自动更改(从100%变为200%-200%是“高DPI”监视器的DPI缩放值),因此可以通过使用缩放来完成,或者不知何故。但是,还有一个滚动条大小的问题。

我还注意到了DOCHOSTUIFLAG_DPI_AWARE标志的存在,这可能很有用,但我还不知道如何利用它。

2 个答案:

答案 0 :(得分:1)

TWebBrowser包装了InternetExplorer,因此控件的呈现不是由任何VCL代码完成的,而是由嵌入式Internet Explorer代码完成的。我们已在各种项目中使用了此功能,设置兼容模式是获得所需显示的关键。

由于IE 可以正确缩放,因此您需要确保以正确的模式运行。 @Ondrej Kelle的评论是一篇有用的文章,应该向您展示如何执行此操作,因此在此不再赘述。

答案 1 :(得分:0)

我发现了两种方法:

解决方案1 ​​
通过注册表项和值为您的应用程序启用IE的FEATURE_96DPI_PIXEL

uses
  System.SysUtils,
  System.Win.Registry,
  Vcl.Forms,
  Winapi.Windows;

procedure EnableDpiAwareness;
var
  Reg: TRegistry;
  App: string;
begin
  Reg := TRegistry.Create;
  try
    App := ExtractFileName(Application.ExeName);
    Reg.RootKey := HKEY_CURRENT_USER;

    if Reg.OpenKey('Software\Microsoft\Internet Explorer\Main\FeatureControl\FEATURE_96DPI_PIXEL', True) then
    begin
      Reg.WriteInteger(App, 1);
      Reg.CloseKey;
    end;
  finally;
    Reg.Free;
  end;
end;

解决方案2
实现TWebBrowser的后代类,以重新实现IDocHostUIHandler接口(如OP的编辑中所述):

unit DpiAwareWebBrowser;

interface

uses
  Winapi.Mshtmhst,
  SHDocVw;

type
  TDpiAwareWebBrowser = class(TWebBrowser, IDocHostUIHandler)
    strict private
      // IDocHostUIHandler "override"
      function GetHostInfo(var pInfo: TDocHostUIInfo): HRESULT; stdcall;
  end;

implementation

const
  DOCHOSTUIFLAG_DPI_AWARE = $40000000;

function TDpiAwareWebBrowser.GetHostInfo(var pInfo: TDocHostUIInfo): HRESULT;
begin
  // original code from TWebBrowser.GetHostInfo
  pInfo.cbSize := SizeOf(pInfo);
  pInfo.dwFlags := 0;
  pInfo.dwFlags := pInfo.dwFlags or DOCHOSTUIFLAG_NO3DBORDER;
  pInfo.dwFlags := pInfo.dwFlags or DOCHOSTUIFLAG_THEME;
  pInfo.dwFlags := pInfo.dwFlags or DOCHOSTUIFLAG_DPI_AWARE; // NEW added flag
  Result := S_OK;
//  ResizeScrollBars; // will be called by subsequent routines anyway.
end;

end.

两种方法都做同样的事情。

DOCHOSTUIFLAG_DPI_AWARE
Internet Explorer8。使布局引擎将文档像素计算为96 dpi。通常,文档像素的大小与屏幕像素的大小相同。此标志等效于按主机设置FEATURE_96DPI_PIXEL功能控制键。

来源:Microsoft Docs - DOCHOSTUIFLAG enumeration