Skip to content
This repository has been archived by the owner on May 25, 2022. It is now read-only.

高dpi下cefveiw显示问题 #32

Open
WilliamZhangZhe opened this issue Jan 22, 2018 · 18 comments
Open

高dpi下cefveiw显示问题 #32

WilliamZhangZhe opened this issue Jan 22, 2018 · 18 comments

Comments

@WilliamZhangZhe
Copy link

WilliamZhangZhe commented Jan 22, 2018

您好,我这边有在高dpi下(dpi = 126 等等)使用cefview显示网页,显示的网页的窗口大小与实际窗口大小不符,会出现3/4的区域为空白或者透明,请问是什么问题呢?我已启用qt的高dpi显示设置(Application::setAttribute(Qt::AA_EnableHighDpiScaling);)
image

@tishion
Copy link
Owner

tishion commented Jan 23, 2018

@WilliamZhangZhe QCefView主要解决的一个问题是native的CEF窗口和Qt窗口的融合问题,关键部件是QCefWindow

融合的方法并不是简单的把CEF的native窗口作为child添加到QCefWindow,虽然他们具有父子关系,但是CEF的native窗口的绘制并没有交给QCefWindow去管理,QCefWindow只负责把CEF的native窗口实时的移动到QCefWindows的client区域(大小,位置等)。这个过程是获取到QCefWindow的size,然后利用MoveWindow去设置CEF的native窗口。

我还没有去重现这个问题,但是我猜想应该是,Qt启用了DPI缩放,但是通过size函数获取到的QCefWindow的宽和高的数值仍然是没有经过缩放因子处理的数值。

解决这个问题的思路:
1.获取当前Qt窗口的缩放因子scale

然后有两种处理方法:
1.获取QCefWindow的size数值然后 newHeight = height * scale,newWidth = width * scale, 然后用这个newHeight和newWidth去调整CEF的natvice窗口的大小。
这种方法有个问题,Qt窗口显示的内容是经过缩放的,可是CEF的内容是没有缩放的,两部分比例不一致,会不会怪怪的?

  1. 直接对CEF的native窗口应用缩放因子scale,这里通过Windows API 或者 CEF 提供的API ?

希望对你有帮助,我有空的时候会尝试调试下

@WilliamZhangZhe
Copy link
Author

hi,非常感谢您的回复,我这边测试情况是cef在默认情况下是应用缩放的,如果想要关闭可以添加“--high-dpi-support=1 --force-device-scale-factor=1”运行参数,(亦可通过CefEnableHighDPISupport启用),您回复的关于navie窗口适应dpi缩放的qt窗口的方案一正是我所遇到问题的解决方案,非常感谢!!

@liulinhere
Copy link

我也遇到同样问题,能否分享下解决代码;另我想升级到CEF 3.3239 X64,部分接口已过时,API找到有替代方法不大会用,惭愧。。

@WilliamZhangZhe
Copy link
Author

你按照tishion所提及的解决办法修改即可,(1.获取QCefWindow的size数值然后 newHeight = height * scale,newWidth = width * scale, 然后用这个newHeight和newWidth去调整CEF的natvice窗口的大小)这个是我应用的方案,在CCefwindow.cpp 中依据当前系统的dpi scale value 修改updateCefBrowserWindow内的窗口大小设置即可

@liulinhere
Copy link

感谢,我按您的方法尝试下。在VS2015里,CCefwindow.cpp没包含在include的头文件项目里,把它忽略了;

@liulinhere
Copy link

demo
设置放大比例好,出现了一些新的情况,1. 当鼠标移入网页区域,会出现一个小网页;2. 当窗口缩很小后,大的区域不见了,只有很小的网页区。

@tishion
Copy link
Owner

tishion commented Jan 25, 2018

@liulinhere 把你修改的代码贴出来一下

@WilliamZhangZhe
Copy link
Author

@liulinhere , 你得qcefwing的编译清单文件选项上添加上“高dpi支持”

@tishion
Copy link
Owner

tishion commented Jan 25, 2018 via email

@WilliamZhangZhe
Copy link
Author

我的解决办法是:
步骤一:设置目标运行程序支持高dpi
方法1:vs可通过 工程右键 > 属性 > 清单工具 > 输入和输出 > DPI识别功能 > 高DPI识别
方法2:Qt可以添加环境变量qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", QByteArray("1"));实现
方法3:Qt可以通过QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);实现
注意:方法2和方法3需要在QApplication初始化前完成

步骤二:设置qcefwing工程和QCefViewTest工程支持高dpi

步骤三:添加获取系统dpi-scale 的接口代码,例如我的是
#include <Windows.h>
#include <math.h>
const float DEFAULT_DPI = 96.0;
float windowsDpiScaleX() {
HDC screen = CreateDC(L"DISPLAY", NULL, NULL, NULL);/GetDC(0)/;
FLOAT dpiX = static_cast(GetDeviceCaps(screen, LOGPIXELSX));
ReleaseDC(0, screen);
return dpiX / DEFAULT_DPI;
}

float windowsDpiScaleY() {
HDC screen = CreateDC(L"DISPLAY", NULL, NULL, NULL);/GetDC(0)/;
FLOAT dpiY = static_cast(GetDeviceCaps(screen, LOGPIXELSY));
ReleaseDC(0, screen);
return dpiY / DEFAULT_DPI;
}

步骤四:修改QCefWindow.cpp下的 updateCefBrowserWindow()实现如下:
void CCefWindow::updateCefBrowserWindow()
{
if (!hwndCefBrowser_)
hwndCefBrowser_ = ::FindWindowExA((HWND)winId(), nullptr, CEF_BROWSER_WINDOW_CLASS_NAME_A, nullptr);

int dpi_x_scale = round(windowsDpiScaleX());
int dpi_y_scale = round(windowsDpiScaleY());

if (hwndCefBrowser_)
	::MoveWindow(hwndCefBrowser_, 0, 0, width() * dpi_x_scale, height() * dpi_y_scale, TRUE);

}

以上是我的具体的实现方法,希望可以帮到你
@liulinhere

@WilliamZhangZhe
Copy link
Author

我选择round的方式是因为在windows平台下实测125%实际会按照100%的比例放大,150% 175% 200% 实际会按照200%放大,不知道其他平台是否也是这样

@liulinhere
Copy link

liulinhere commented Jan 25, 2018

是的,QT的理解是四舍五入,4K,WIN10默认是250%,QT为3。
修改的地方,直接在:CCefWindow.cpp,updateCefBrowserWindow里,
`void CCefWindow::updateCefBrowserWindow()
{
if (!hwndCefBrowser_)
hwndCefBrowser_ = ::FindWindowExA((HWND)winId(), nullptr, CEF_BROWSER_WINDOW_CLASS_NAME_A, nullptr);

if (hwndCefBrowser_) {		
	HDC hdc = GetDC(hwndCefBrowser_);
	int ppix = GetDeviceCaps(hdc, LOGPIXELSX);
	int ppiy = GetDeviceCaps(hdc, LOGPIXELSY);
	ReleaseDC(hwndCefBrowser_, hdc);

	cout << "ppix:"<< ppix<<endl;
	cout << "ppiy:" << ppiy << endl;
	
	
	float scale = roundf((float)ppix / 96);
	cout << "scale:" << scale << endl;
	
	::MoveWindow(hwndCefBrowser_, 0, 0, width()*scale, height()*scale, TRUE);		
}		

}`

@liulinhere
Copy link

QCefViewTest.zip

放上 QCefViewSDK 试下,VS2015 X86+QT5.9.3

@liulinhere
Copy link

33

  1. 当不启用放缩的情况下,这两个边线怎么不知道哪来的?
  2. 启用放缩后,再到控制面板改放缩比,取出来还是一样的,会撑出去;
  3. qcefwing我没改过清单文件,是不是这儿有问题?

@bairutai
Copy link

bairutai commented Jan 6, 2020

33

  1. 当不启用放缩的情况下,这两个边线怎么不知道哪来的?
  2. 启用放缩后,再到控制面板改放缩比,取出来还是一样的,会撑出去;
  3. qcefwing我没改过清单文件,是不是这儿有问题?

请问您这个问题解决了么

@bairutai
Copy link

bairutai commented Jan 6, 2020

我的解决办法是:
步骤一:设置目标运行程序支持高dpi
方法1:vs可通过 工程右键 > 属性 > 清单工具 > 输入和输出 > DPI识别功能 > 高DPI识别
方法2:Qt可以添加环境变量qputenv("QT_AUTO_SCREEN_SCALE_FACTOR", QByteArray("1"));实现
方法3:Qt可以通过QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);实现
注意:方法2和方法3需要在QApplication初始化前完成

步骤二:设置qcefwing工程和QCefViewTest工程支持高dpi

步骤三:添加获取系统dpi-scale 的接口代码,例如我的是
#include <Windows.h>
#include <math.h>
const float DEFAULT_DPI = 96.0;
float windowsDpiScaleX() {
HDC screen = CreateDC(L"DISPLAY", NULL, NULL, NULL);/GetDC(0)/;
FLOAT dpiX = static_cast(GetDeviceCaps(screen, LOGPIXELSX));
ReleaseDC(0, screen);
return dpiX / DEFAULT_DPI;
}

float windowsDpiScaleY() {
HDC screen = CreateDC(L"DISPLAY", NULL, NULL, NULL);/GetDC(0)/;
FLOAT dpiY = static_cast(GetDeviceCaps(screen, LOGPIXELSY));
ReleaseDC(0, screen);
return dpiY / DEFAULT_DPI;
}

步骤四:修改QCefWindow.cpp下的 updateCefBrowserWindow()实现如下:
void CCefWindow::updateCefBrowserWindow()
{
if (!hwndCefBrowser_)
hwndCefBrowser_ = ::FindWindowExA((HWND)winId(), nullptr, CEF_BROWSER_WINDOW_CLASS_NAME_A, nullptr);

int dpi_x_scale = round(windowsDpiScaleX());
int dpi_y_scale = round(windowsDpiScaleY());

if (hwndCefBrowser_)
	::MoveWindow(hwndCefBrowser_, 0, 0, width() * dpi_x_scale, height() * dpi_y_scale, TRUE);

}

以上是我的具体的实现方法,希望可以帮到你
@liulinhere

为什么我用这种方法做了,网页有时显示 有时不显示。。

@phiysng
Copy link

phiysng commented Oct 27, 2020

我选择round的方式是因为在windows平台下实测125%实际会按照100%的比例放大,150% 175% 200% 实际会按照200%放大,不知道其他平台是否也是这样

125%不缩放这个问题似乎是Chromium的BUG,详见 https://bugs.chromium.org/p/chromium/issues/detail?id=410696

@oopses
Copy link

oopses commented Oct 27, 2020

不是chrome的,是qt5.9的版本对文本缩放的支持只能是整数倍,会四舍五入,5.12后开始支持小数倍
https://bbs.huaweicloud.com/blogs/137316
官方文档也有说明,链接可以查一下

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants