WPF 已知问题 某些设备上的应用在 WindowChromeWorker 抛出 System.OverflowException 异常
准确来说,这个不算是 WPF 的问题,而是系统等的问题。在某些设备上的使用了 WindowChrome 功能的 WPF 应用,将在运行过程,在 WindowChromeWorker 类里面抛出 System.OverflowException 异常。核心原因是这些设备是 x64 设备,运行的 x64 的 WPF 应用程序,在消息循环里面传入的 lParam 是一个 x64 的指针,但在 WPF 里面使用 ToInt32 方法进行转换,刚好此 x64 的指针超过 int 的范围,从而抛出异常
这是一个上古就存在的问题,有人报告说安装了某些驱动就会存在此异常,但是我没有调查到在符合什么情况下就会抛出此异常。此异常的调用堆栈大概如下
System.OverflowException
HResult=0x80131516
Message=Arithmetic operation resulted in an overflow.
Source=PresentationFramework
StackTrace:
at System.Windows.Shell.WindowChromeWorker._HandleNCHitTest(WM uMsg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Shell.WindowChromeWorker._WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
异常的中文描述是 算术运算导致溢出
通过阅读代码可以了解到是在 WindowChromeWorker._WndProc 方法里面接收到 Windows 消息,在 _HandleNCHitTest 转换 lParam 参数读取时抛出异常,以下是此方法的有删减的代码
private IntPtr _HandleNCHitTest(WM uMsg, IntPtr wParam, IntPtr lParam, out bool handled)
{
DpiScale dpi = _window.GetDpi();
// Let the system know if we consider the mouse to be in our effective non-client area.
var mousePosScreen = new Point(Utility.GET_X_LPARAM(lParam), Utility.GET_Y_LPARAM(lParam));
Rect windowPosition = _GetWindowRect();
// 忽略代码
}
现在的 WPF 是基于最友好的 MIT 协议开源的,所有的源代码都可以从 https://github.com/dotnet/wpf 下载到。如果对以上的 _HandleNCHitTest 方法感兴趣,想要阅读完全的代码,还请到官方开源仓库获取
通过以上代码可以看到,使用 Utility 的 GET_X_LPARAM 方法从 lParam 参数获取一个点的 x 参数。从业务分析上,实际上 lParam 转换的 x 参数是作为屏幕的坐标点,而屏幕的坐标点在 2022 时还是一个 Int16 范围的值。换句话说,如果 lParam 转换出一个 Int64 的长度,那一定是不符合预期的
在 GET_X_LPARAM 方法里面,将会通过 ToInt32 的方法进行转换,且取其低位。在 GET_Y_LPARAM 里,将会转换 lParam 为 Int32 取高位。而抛出的异常就是 ToInt32 这个方法
如果传入了一个 IntPtr 是一个 long 的值,那将会在 ToInt32 方法抛出 OverflowException 异常
我将此问题报告给 WPF 官方,请看 System.OverflowException in PresentationFramework.dll in System.Windows.Shell.WindowChromeWorker · Issue #6777 · dotnet/wpf
然而有趣的是我就是 WPF 官方开发者,于是我就自己修复了这个问题,请看 Fix System.OverflowException in WindowChromeWorker._HandleNCHitTest by lindexi · Pull Request #6779 · dotnet/wpf
我的修复的方法是转换为 Long 再进行裁剪,这个做法我认为是对的,我也阅读了一些相关的对 NCHitTest 消息处理的博客,例如 当无边框窗口被子窗口遮挡导致难以调节窗口大小时,可通过处理 NCHITTEST 消息重新支持调节窗口大小 - walterlv 也都是如此处理
不过在我的代码还没被合入之前,可以先采用以下代码减少抛出异常
protected override void OnSourceInitialized( EventArgs e )
{
base.OnSourceInitialized( e );
( (HwndSource)PresentationSource.FromVisual( this ) ).AddHook( HookProc );
}
private IntPtr HookProc( IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled )
{
if ( msg == 0x0084 /*WM_NCHITTEST*/ )
{
// 如果尝试转换失败,那就吃掉这个消息
// This prevents a crash in WindowChromeWorker._HandleNCHitTest
try
{
lParam.ToInt32();
}
catch ( OverflowException )
{
handled = true;
}
}
return IntPtr.Zero;
}
更多的相关链接:
OverflowException when converting 64-bit IntPtr to Int32 ControlzEx/ControlzEx#30
Arithmetic operation resulted in an overflow. MahApps/MahApps.Metro#3301
Exception:算术运算导致溢出。 HandyOrg/HandyControl#886
https://developercommunity.visualstudio.com/t/overflow-exception-in-windowchrome/167357
WPF 已知问题 某些设备上的应用在 WindowChromeWorker 抛出 System.OverflowException 异常的更多相关文章
- WPF窗体视图中绑定Resources文件中字符串时,抛出:System.Windows.Markup.StaticExtension
问题描述: 在Resources.resx定义了一个静态字符串字段Title,并在WPF窗体视图中绑定为窗体的标题: Title="{x:Static local:Resources.Tit ...
- 调用远程主机上的 RMI 服务时抛出 java.rmi.ConnectException: Connection refused to host: 127.0.0.1 异常原因及解决方案
最近使用 jmx 遇到一个问题,client/server 同在一台机器上,jmx client能够成功连接 server,如果把 server 移植到另一台机器上192.168.134.128,抛出 ...
- Java13新特性 -- 新增 移除 废弃 已知问题等
新增 添加FileSystems.newFileSystem(Path, Map<String, ?>) Method 新的java.nio.ByteBuffer Bulk get/put ...
- Java知多少(49)throw:异常的抛出
到目前为止,你只是获取了被Java运行时系统抛出的异常.然而,程序可以用throw语句抛出明确的异常.Throw语句的通常形式如下: throw ThrowableInstance;这里,Thr ...
- 记一次asp.net core 在iis上运行抛出502.5错误
asp.net core 在iis上运行抛出502.5异常的部分原因以及解决方案 环境说明 已安装 .net core runtime 2.1.401 已安装 .net core windows ho ...
- c# throw抛出上一个异常
catch(exception e) { throw; } 不仅抛出这次的异常,也抛出之前的异常. 用法示例:函数A调用函数B,A用到此throw时,B中发生的异常也会继承过来. catch(exce ...
- 已知圆上三个点坐标,求圆半径 r 和 圆心坐标
问题: 已知圆上三个点坐标分别为(x1,y1).(x2,y2).(x3,y3) 求圆半径R和圆心坐标(X,Y) X,Y,R为未知数,x1,y1,x2,y2,x3,y3为常数 则由圆公式:(x1-X)² ...
- 已知空间两点组成的直线求线上某点的Z值
已知空间两点组成的直线求线上某点的Z值,为什么会有这种看起来比较奇怪的求值需求呢?因为真正三维空间的几何计算是比较麻烦的,很多时候需要投影到二维,再反推到三维空间上去. 复习下空间直线方程:已知空间上 ...
- HoloLens开发手记 - Known issues 已知问题
本文主要提及一份问题清单,这些问题都可能对我们开发HoloLens应用造成困扰. Visual Studio 在使用VS 2015 Update 1连接HoloLens时,可能会有些小问题.但是这些小 ...
- 实战分享:如何成功防护1.2T国内已知最大流量DDoS攻击
作者:腾讯云宙斯盾安全团队&腾讯安全平台部 引言: DDoS攻击势头愈演愈烈,除了攻击手法的多样化发展之外,最直接的还是攻击流量的成倍增长.3月份国内的最大规模DDoS攻击纪录还停留在数百G规 ...
随机推荐
- 手把手制作mobileconfig文件,在iphone上创建h5网页桌面图标
1,下载mobileconfig文件制作工具 下载地址:点击关注公众号,回复appicon, 获取工具的下载地址 新建配置描述文件,填写通用信息 填写Web Clip信息 点击菜单栏的导出,注意这里一 ...
- Elasticsearch内核解析 - 数据模型篇【转载】
原文链接 Elasticsearch是一个实时的分布式搜索和分析引擎,它可以帮助我们用很快的速度去处理大规模数据,可以用于全文检索.结构化检索.推荐.分析以及统计聚合等多种场景. Elasticsea ...
- axios封装(处理token跟get中Content-Type的请求问题)
axios封装 import axios from 'axios' //引入axios import store from '@/store/index' //引入store //此处引入router ...
- MySQL8.0 ERROR 1045 (28000)
第一步:关闭服务 net stop mysql 这个需要在管理员权限才行 ,具体怎么用管理员打开cmd略过 第二步:进入到安装的bin目录 执行 :mysqld --console --skip-gr ...
- Csharp中表达式树
Csharper中的表达式树 这节课来了解一下表示式树是什么? 在C#中,表达式树是一种数据结构,它可以表示一些代码块,如Lambda表达式或查询表达式.表达式树使你能够查看和操作数据,就像你可以查看 ...
- java实战:多属性排序
多属性排序的核心点就是对Arrays.sort()和Collections.sort()方法的Comparator进行重写 Arrays.sort()的三种用法 1.1.Arrays.sort(int ...
- #点分树#洛谷 6626 [省选联考 2020 B 卷] 消息传递
题目 多组数据多组询问,对于一个点 \(x\) 和 树上的距离 \(k\),问 \(\sum_{i=1}^n[Dis(x,i)==k]\) 分析 卡了一页的常,发现两个 \(\log\) 过不去,有一 ...
- #AC自动机#洛谷 2444 [POI2000]病毒
题目 给定若干01串,问是否存在无限长的01串任意子串不是给定的若干串 分析 如果在AC自动机上跳到了访问过的前缀即代表存在一个循环可以无限跳, 在AC自动机上记录哪些状态是不能访问的,在AC自动机上 ...
- #zkw线段树,扫描线,dp,离散#NOIP2020.9.26模拟speike
分析 由于可以走边界,那么最短路径一定按横坐标递增并且经过矩形的顶点, 考虑扫描线,找到当前线段(矩形右边界可以忽略)两个端点离的最近而又可达的线段, dp一下并用线段树维护就可以了 代码 #incl ...
- 1.NCC算法实现及其优化[基础实现篇]
NCC算法实现及其优化 本文将集中探讨一种实现相对简单,效果较好的模板匹配算法(NCC) \[R(x,y)= \frac{ \sum_{x',y'} (T'(x',y') \cdot I'(x+x', ...