什么会导致WM_NCHITTEST lParam溢出32位整数?
本文关键字:溢出 lParam 32位 整数 NCHITTEST WM 什么 | 更新日期: 2023-09-27 18:18:48
消息WM_NCHITTEST
的lParam
在什么情况下不适合32位整数?
我们的一个客户在他的64位机器上看到崩溃,原因是我们的WPF应用程序中出现了一个未处理的异常,我很难找到原因。从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, 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 MS.Internal.Threading.ExceptionFilterHelper.TryCatchWhen(Object source, Delegate method, Object args, Int32 numArgs, Delegate catchHandler)
违规方法_HandleNCHitTest
的来源在这里。
我能看到被抛出的溢出异常的唯一方法是在将lParam
转换为Point的代码中,它在这里调用IntPtr.ToInt32()
。如果lParam
不适合Int32
,则引发此异常。然而,我想不出这种情况何时会发生。是什么让这一切发生呢?
简短的回答:使用。net 4.5以来集成的WindowChrome。
很长的回答,如果你不能切换到。net 4.5,这似乎对我有用,看看我对最初问题的评论。您永远无法确定,因为问题有时只在某些机器上显示,而不是所有的x64机器:
我修改了WPF Shell集成库v2的源代码。更改后的行在末尾用<----
标记。
WindowChromeWorker.cs:
private IntPtr _HandleSize(WM uMsg, IntPtr wParam, IntPtr lParam, 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, IntPtr wParam, IntPtr lParam, 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;
}