如何解决'PInvoke函数不平衡堆栈错误'在Windows窗体应用程序

本文关键字:错误 堆栈 Windows 应用程序 窗体 不平衡 函数 解决 何解决 PInvoke | 更新日期: 2023-09-27 18:12:43

我有一个Windows应用程序,它使用Windows API方法从客户端区域拖动Winform。现在,当我释放鼠标按钮时它给了我错误 "A call to PInvoke function 'xThemes!xThemes.API::SendMessage' has unbalanced the stack."

.net版本为3.5时不产生此错误,但当版本大于3.5时产生。

CS页面:

 private void titlebar_MouseMove(object sender, MouseEventArgs e)
        {
            //Function for form dragging.
            if (this.WindowState != FormWindowState.Maximized)
            {
                if (MouseButtons.ToString() == "Left")
                {
                    API.ReleaseCapture();
                    API.SendMessage(this.Handle, WM_NCLBUTTONDOWN, HT_CAPTION, 0);
                }
            }
        }

API类
//Windows API for resizing the window.
        [DllImport("user32.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern int SendMessage(IntPtr hWnd, uint Msg, int lParam, int wParam);
        [DllImport("user32.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern bool ReleaseCapture();
        [DllImport("user32.dll", CallingConvention = CallingConvention.Cdecl)]
        public static extern bool ShowWindow(IntPtr hWnd, int cmdShow);

如何解决'PInvoke函数不平衡堆栈错误'在Windows窗体应用程序

这意味着您的p/Invoke有一些错误的定义。通常在http://www.pinvoke.net你会找到关于本机windows API调用的好信息。他们通常是对的(不是永远!)

对于SendMessage,我找到了以下定义:

[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, UInt32 Msg, IntPtr wParam, IntPtr lParam);

听起来问题在于int x IntPtr。在msdn定义之后:

IntPtr类型被设计为一个整数,其大小为特定于平台的。也就是说,这种类型的实例应该是32位在32位硬件和操作系统上,64位在64位硬件和操作系统

换句话说,在64位环境中使用导入可以解决您的问题。

API的更改将修复此错误(由Hans Passant建议)…

//Windows API for resizing the window.
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern int SendMessage(IntPtr hWnd, uint Msg, long lParam, long wParam);
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool ReleaseCapture();
[DllImport("user32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern bool ShowWindow(IntPtr hWnd, int cmdShow);