什么会导致 WM_NCHITTEST lParam 溢出 32 位整数?

kcn*_*ard 7 c# wpf winapi

在什么条件下lParammessageWM_NCHITTEST是一个不适合 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, 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)
Run Code Online (Sandbox Code Playgroud)

违规方法的来源_HandleNCHitTest这里

我可以看到抛出溢出异常的唯一方法是在转换lParam为 Point的代码中,该代码IntPtr.ToInt32() 在此处调用. 如果lParam不适合Int32,则引发此异常。但是,我想不出可能发生这种情况的情况。什么可以做到这一点?

JCH*_*H2k 0

简短回答:使用 .NET 4.5 以来集成的 WindowChrome。


如果您无法切换到 .NET 4.5,那么答案很长,这似乎对我有用,请参阅我对原始问题的评论。你永远无法确定,因为问题有时只出现在某些机器上,而不是所有 x64 机器上:

I modified the source of WPF Shell Integration Library v2. The changed lines are marked with <---- at the end.

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;
    }
Run Code Online (Sandbox Code Playgroud)

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);
    }
Run Code Online (Sandbox Code Playgroud)

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;
    }
Run Code Online (Sandbox Code Playgroud)