在什么条件下,消息WM_NCHITTEST的lParam是一个不适合32位整数的值?
由于我们的WPF应用程序中出现未处理的异常,我们的一位客户看到他的64位计算机出现崩溃,我无法追查原因.从WPF代码引发异常,如堆栈跟踪中所示:
System.OverflowException: Arithmetic operation resulted in an overflow. at Microsoft.Windows.Shell.WindowChromeWorker._HandleNCHitTest(WM uMsg,IntPtr wParam,IntPtr lParam,Boolean& handled) at Microsoft.Windows.Shell.WindowChromeWorker._WndProc(IntPtr hwnd,Int32 msg,Boolean& handled) at System.Windows.Interop.HwndSource.PublicHooksFilterMessage(IntPtr hwnd,Boolean& handled) at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd,Boolean& handled) at MS.Win32.HwndSubclass.dispatcherCallbackOperation(Object o)
 at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback,Object args,Int32 numArgs) at MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source,Delegate method,Int32 numArgs,Delegate catchHandler)
我可以看到抛出溢出异常的唯一方法是将lParam转换为Point的代码,该Point调用IntPtr.ToInt32()here.如果lParam不适合Int32,则引发此异常.但是,我不能想到这种情况可能发生的情况.是什么让这种情况发生?
解决方法
简短回答:使用自.NET 4.5以来集成的WindowChrome.
如果你不能切换到.NET 4.5,这很好的答案,这似乎对我有用,看看我对原始问题的评论.您永远无法确定,因为问题有时仅显示在某些计算机上,而不是所有x64计算机上:
我修改了WPF Shell Integration Library v2的源代码.更改的行在末尾标有< ----. WindowChromeWorker.cs:
private IntPtr _HandleSize(WM uMsg,out bool handled) { const int SIZE_MAXIMIZED = 2; // Force when maximized. // We can tell what's happening right Now,but the Window doesn't yet kNow it's // maximized. Not forcing this update will eventually cause the // default caption to be drawn. WindowState? state = null; if (wParam.ToInt64() == SIZE_MAXIMIZED) <----- { state = WindowState.Maximized; } _UpdateSystemMenu(state); // Still let the default WndProc handle this. handled = false; return IntPtr.Zero; }
Utilities.cs:
[SuppressMessage("Microsoft.Performance","CA1811:AvoidUncalledPrivateCode")] public static int GET_X_LParaM(IntPtr lParam) { return LOWORD(lParam.ToInt64()); <---- } [SuppressMessage("Microsoft.Performance","CA1811:AvoidUncalledPrivateCode")] public static int GET_Y_LParaM(IntPtr lParam) { return HIWORD(lParam.ToInt64()); <---- } [SuppressMessage("Microsoft.Performance","CA1811:AvoidUncalledPrivateCode")] public static int HIWORD(long i) <---- { return (short)((i >> 16) & 0xFFFF); <---- } [SuppressMessage("Microsoft.Performance","CA1811:AvoidUncalledPrivateCode")] public static int LOWORD(long i) <---- { return (short)(i & 0xFFFF); }
TaskbarItemInfo.cs:
private IntPtr _WndProc(IntPtr hwnd,int uMsg,ref bool handled) { WM message = (WM)uMsg; if (message == WM_TASKBARBUTTONCREATED) { _OnIsAttachedChanged(true); _isAttached = true; handled = false; } else { switch (message) { case WM.COMMAND: if (Utility.HIWORD(wParam.ToInt64()) == THUMBBUTTON.THBN_CLICKED) <----- { int index = Utility.LOWORD(wParam.ToInt64()); <---- ThumbButtonInfos[index].InvokeClick(); handled = true; } break; case WM.SIZE: _UpdateThumbnailClipping(_isAttached); handled = false; break; } } return IntPtr.Zero; }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。