为非客户端鼠标离开调用_TrackMouseEvent时的Win32 ERROR_NOACCESS(C#)

Emi*_*elt 0 c# winapi nonclient mouseevent

我目前正在通过拦截各种WndProc消息并在非客户区绘制来编写某种自定义表单边框.要为关闭按钮等创建某种悬停效果,我需要跟踪鼠标指针.这很好用,但是要接收WM_NCMOUSELEAVE消息,我必须先调用_TrackMouseEvent,根据MSDN.

令人惊讶的是,它不起作用._TrackMouseEvent失败,Marshal.GetLastWin32Error()返回998(对内存位置的无效访问).

我很无能,所以这是我的代码:

class Native
{
    [DllImport("comctl32.dll", SetLastError = true)]
    public static extern bool _TrackMouseEvent(TRACKMOUSEEVENT tme);

    public struct TRACKMOUSEEVENT
    {
        public int cbSize;
        public int dwFlags;
        public IntPtr hwndTrack;
        public int dwHowerTime;
    }

    public const int TME_LEAVE = 0x00000002;
    public const int TME_NONCLIENT = 0x00000010;
}

private void ActivateLeaveTracking()
{
    Native.TRACKMOUSEEVENT tme = new Native.TRACKMOUSEEVENT();
    tme.hwndTrack = this.Handle;
    tme.dwHowerTime = 0;
    tme.dwFlags = Native.TME_LEAVE | Native.TME_NONCLIENT;
    tme.cbSize = Marshal.SizeOf(typeof(Native.TRACKMOUSEEVENT));
    if (!Native._TrackMouseEvent(tme))
    {
        throw new Exception(Marshal.GetLastWin32Error().ToString());
    }

}
Run Code Online (Sandbox Code Playgroud)

欢迎任何帮助.:)

Meh*_*dad 5

更改

_TrackMouseEvent(TRACKMOUSEEVENT tme);
Run Code Online (Sandbox Code Playgroud)

_TrackMouseEvent(ref TRACKMOUSEEVENT tme);
Run Code Online (Sandbox Code Playgroud)

并改变

Native._TrackMouseEvent(tme)
Run Code Online (Sandbox Code Playgroud)

Native._TrackMouseEvent(ref tme)
Run Code Online (Sandbox Code Playgroud)

经验法则:

很少将结构作为参数传递; 你通常把它们作为指针传递给你.