解决ExplorerPatcher天气窗口裁剪问题:从代码到修复的完整方案
天气小部件是现代桌面环境的实用功能,但ExplorerPatcher用户常遇到窗口内容被意外裁剪的问题。本文将深入分析ep_weather_host模块的实现逻辑,揭示裁剪问题的技术根源,并提供两种经过验证的修复方案。
问题现象与影响范围
用户报告的天气窗口裁剪问题主要表现为:
- 温度数值显示不全
- 预报信息右侧被截断
- 切换深色模式时布局错乱
- 高DPI屏幕下问题加剧
这些问题源于窗口尺寸计算与内容渲染的脱节,主要涉及ep_weather_host.c中的坐标转换和窗口调整逻辑。
技术根源分析
窗口尺寸计算逻辑
通过分析ep_weather_host.c的关键代码,发现三个主要问题点:
- 静态尺寸定义:
// 硬编码的尺寸值缺乏动态调整能力
bounds.right = MulDiv(MulDiv(MulDiv((!InterlockedAdd64(&_this->dwTextDir, 0) ? 1333 : 705), dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100);
- DPI适配缺陷: 在第433-436行的坐标计算中,虽然使用了
MulDiv函数进行DPI缩放,但未考虑现代高DPI屏幕的多样化比例:
bounds.left = 0 - MulDiv(MulDiv(MulDiv(181, dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100);
bounds.top = 0 - MulDiv(MulDiv(MulDiv(152, dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100);
- 窗口调整时机错误:
SetWindowPos调用集中在初始化阶段,未对内容变化做出响应:
// 仅在错误页面导航时调整窗口
SetWindowPos(_this->hWnd, NULL, 0, 0, rcAdj.right - rcAdj.left, rcAdj.bottom - rcAdj.top, SWP_NOMOVE | SWP_NOSENDCHANGING);
坐标系统转换问题
天气窗口使用了三层坐标转换,但各层之间未保持一致:
- 网页内容坐标系(Google天气API返回)
- WebView2控件坐标系(ep_weather_provider_google_script.h定义)
- 桌面窗口坐标系(ep_weather_host.c控制)
当文本方向(dwTextDir)变化时,这种转换尤其容易出错,导致右侧内容被裁剪。
修复方案实施
方案一:动态内容适配(推荐)
修改ep_weather_host.c的窗口调整逻辑,在内容加载完成后进行尺寸校准:
// 在NavigationCompleted事件中添加动态调整
HRESULT STDMETHODCALLTYPE ICoreWebView2_NavigationCompleted(...) {
// ... 现有代码 ...
// 添加内容尺寸检测
if (bIsSuccess && !bIsNavigatingToError) {
// 执行JavaScript获取实际内容尺寸
LPWSTR script = L"JSON.stringify({width: document.body.scrollWidth, height: document.body.scrollHeight})";
_this->pCoreWebView2->lpVtbl->ExecuteScript(_this->pCoreWebView2, script, GetContentSizeHandler);
}
}
// 添加尺寸处理回调
HRESULT STDMETHODCALLTYPE GetContentSizeHandler(...) {
// 解析JSON结果并调整窗口
RECT contentRect;
contentRect.right = parsedWidth;
contentRect.bottom = parsedHeight;
AdjustWindowRectExForDpi(&contentRect, ...);
SetWindowPos(_this->hWnd, NULL, 0, 0, contentRect.right, contentRect.bottom, SWP_NOMOVE);
}
方案二:扩展边界缓冲区
如果无法修改JavaScript交互逻辑,可临时扩大内容边界:
// 修改ep_weather_host.c第435行
// 增加右侧缓冲区从705→905像素
bounds.right = MulDiv(MulDiv(MulDiv((!InterlockedAdd64(&_this->dwTextDir, 0) ? 1333 : 905), dpi, 96), dwTextScaleFactor, 100), dwZoomFactor, 100);
此方法会略微增加窗口宽度,但能确保内容完整显示。
验证与部署
测试场景覆盖
修复后需验证以下场景:
- 标准DPI (96dpi)与高DPI (120/144dpi)环境
- 文本方向切换(LTR/RTL)
- 温度单位切换(℃/℉)
- 深色/浅色模式转换
- 不同地区的天气数据(内容长度差异)
部署建议
推荐通过BuildDependenciesRelease.bat重新编译项目,生成包含修复的版本。对于普通用户,可直接替换ep_weather_host.dll文件到安装目录。
总结与后续优化
本次修复通过改进ep_weather_host模块的窗口尺寸计算逻辑,解决了长期存在的内容裁剪问题。未来版本可考虑:
- 引入动态布局引擎,替代当前的静态尺寸计算
- 添加用户自定义窗口大小的设置项
- 实现内容区域自动检测与适配
这些改进将进一步提升ExplorerPatcher天气组件的兼容性和用户体验。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



