0
votes

I'm currently coding some sort of custom form borders by intercepting various WndProc messages and painting in the non client area. To create some sort of hover effects for the close-button and so on, I need to keep track of the mouse pointer. This works pretty fine, but to receive an WM_NCMOUSELEAVE message, I have to call _TrackMouseEvent first, according to MSDN.

Surprisingly, it does not work. _TrackMouseEvent fails, Marshal.GetLastWin32Error() returns 998 (Invalid access to memory location).

I'm clueless, so here is my code:

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());
    }

}

Any help welcome. :)

1

1 Answers

5
votes

Change

_TrackMouseEvent(TRACKMOUSEEVENT tme);

to

_TrackMouseEvent(ref TRACKMOUSEEVENT tme);

and change

Native._TrackMouseEvent(tme)

to

Native._TrackMouseEvent(ref tme)

Rule of thumb:

You rarely pass structures as parameters; you usually pass them as pointers.