加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

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

发布时间:2020-12-15 20:56:22 所属栏目:百科 来源:网络整理
导读:在什么条件下,消息WM_NCHITTEST的lParam是一个不适合32位整数的值? 由于我们的WPF应用程序中出现未处理的异常,我们的一位客户看到他的64位计算机出现崩溃,我无法追查原因.从WPF代码引发异常,如堆栈跟踪中所示: System.OverflowException: Arithmetic opera
在什么条件下,消息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)

违规方法的来源_HandleNCHitTest是here.

我可以看到抛出溢出异常的唯一方法是将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;
    }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读