Windows Form C# mouse hover, mouse leave verses touchstart, touchend

Gennady Gurin 41 Reputation points
2022-02-15T05:16:12.637+00:00

I have a Windows Form project in C#, for example I have events like mouse hover over picture box and mouse leave from a

picture box. My question is in a case of using a tablet or a phone or touch screen monitor and no mouse is present, I would like

to have an option of touch start (similar to a mouse hover) and touch end (similar to a mouse leave event) . Of course in stead of

using a mouse, one would use a finger. Not sure how to add this event to Windows Form C# project? Since I had before a mouse

click and mouse double click, but I simply replaced with "click and double click" and it still worked. But I do not know if I just can

replace for touch start and touch end events or I have to add to the project?

Write back, thanks in advance.

Windows Forms
Windows Forms
A set of .NET Framework managed libraries for developing graphical user interfaces.
1,908 questions
{count} votes

3 answers

Sort by: Most helpful
  1. Jack J Jun 24,611 Reputation points Microsoft Vendor
    2022-02-24T01:51:31.087+00:00

    @Gennady Gurin ,Sorry for the late response, you could paste the code in the winform directly like the following code:

       namespace WindowsFormsApp1  
    {  
        public partial class Form1 : Form  
        {  
            public Form1()  
            {  
                InitializeComponent();  
            }  
            protected override void WndProc(ref Message m)  
            {  
                switch (m.Msg)  
                {  
                      
                    case Win32.WM_POINTERDOWN:  
                    case Win32.WM_POINTERUP:  
                    case Win32.WM_POINTERUPDATE:  
                    case Win32.WM_POINTERCAPTURECHANGED:  
                        break;  
      
                    default:  
                        base.WndProc(ref m);  
                        return;  
                }  
                int pointerID = Win32.GET_POINTER_ID(m.WParam);  
                Win32.POINTER_INFO pi = new Win32.POINTER_INFO();  
                if (!Win32.GetPointerInfo(pointerID, ref pi))  
                {  
                    Win32.CheckLastError();  
                }  
                Point pt = PointToClient(pi.PtPixelLocation.ToPoint());  
                MouseEventArgs me = new MouseEventArgs(System.Windows.Forms.MouseButtons.Left, 1, pt.X, pt.Y, 0);  
                switch (m.Msg)  
                {  
                    case Win32.WM_POINTERDOWN:  
                        Console.WriteLine("TOCOU" + pt);  
                        (Parent as Form1).Form1_MouseDown((this as object), me);  
                        break;  
      
                    case Win32.WM_POINTERUP:  
                        Console.WriteLine("LEVANTOU");  
                        (Parent as Form1).Form1_MouseUp((this as object), me);  
                        break;  
      
                    case Win32.WM_POINTERUPDATE:  
                        Console.WriteLine("UPDATE");  
                        (Parent as Form1).Form1_MouseMove((this as object), me);  
                        break;  
                }  
            }  
      
            private void Form1_MouseDown(object sender, MouseEventArgs e)  
            {  
      
            }  
      
            private void Form1_MouseUp(object sender, MouseEventArgs e)  
            {  
      
            }  
      
            private void Form1_MouseMove(object sender, MouseEventArgs e)  
            {  
      
            }  
        }  
      
      
         
      
      
    }  
    

    Win32 class:

     [System.Security.SuppressUnmanagedCodeSecurity()]  
            public static class Win32  
            {  
                //------------------------------------------------------------------  
                static object _lockObj = new object();  
          
                internal static int GET_POINTER_ID(IntPtr wParam)  
                {  
                    return LOWORD(wParam);  
                }  
                internal static int HIWORD(IntPtr wParam)  
                {  
                    return (int)((wParam.ToInt64() >> 16) & 0xffff);  
                }  
          
                internal static int LOWORD(IntPtr wParam)  
                {  
                    return (int)(wParam.ToInt64() & 0xffff);  
                }  
          
                internal static void CheckLastError()  
                {  
                    int errCode = Marshal.GetLastWin32Error();  
                    if (errCode != 0)  
                    {  
                        throw new Win32Exception(errCode);  
                    }  
                }  
          
                #region ** pointer constants  
          
                internal const int  
          
                    WM_PARENTNOTIFY = 0x0210,  
                    WM_NCPOINTERUPDATE = 0x0241,  
                    WM_NCPOINTERDOWN = 0x0242,  
                    WM_NCPOINTERUP = 0x0243,  
                    WM_POINTERUPDATE = 0x0245,  
                    WM_POINTERDOWN = 0x0246,  
                    WM_POINTERUP = 0x0247,  
                    WM_POINTERENTER = 0x0249,  
                    WM_POINTERLEAVE = 0x024A,  
                    WM_POINTERACTIVATE = 0x024B,  
                    WM_POINTERCAPTURECHANGED = 0x024C,  
                    WM_POINTERWHEEL = 0x024E,  
                    WM_POINTERHWHEEL = 0x024F,  
          
                    // WM_POINTERACTIVATE return codes  
                    PA_ACTIVATE = 1,  
                    PA_NOACTIVATE = 3,  
          
                    MAX_TOUCH_COUNT = 256;  
          
                internal enum POINTER_INPUT_TYPE  
                {  
                    POINTER = 0x00000001,  
                    TOUCH = 0x00000002,  
                    PEN = 0x00000003,  
                    MOUSE = 0x00000004  
                }  
          
                [Flags]  
                internal enum POINTER_FLAGS  
                {  
                    NONE = 0x00000000,  
                    NEW = 0x00000001,  
                    INRANGE = 0x00000002,  
                    INCONTACT = 0x00000004,  
                    FIRSTBUTTON = 0x00000010,  
                    SECONDBUTTON = 0x00000020,  
                    THIRDBUTTON = 0x00000040,  
                    FOURTHBUTTON = 0x00000080,  
                    FIFTHBUTTON = 0x00000100,  
                    PRIMARY = 0x00002000,  
                    CONFIDENCE = 0x00004000,  
                    CANCELED = 0x00008000,  
                    DOWN = 0x00010000,  
                    UPDATE = 0x00020000,  
                    UP = 0x00040000,  
                    WHEEL = 0x00080000,  
                    HWHEEL = 0x00100000,  
                    CAPTURECHANGED = 0x00200000,  
                }  
          
                [Flags]  
                internal enum VIRTUAL_KEY_STATES  
                {  
                    NONE = 0x0000,  
                    LBUTTON = 0x0001,  
                    RBUTTON = 0x0002,  
                    SHIFT = 0x0004,  
                    CTRL = 0x0008,  
                    MBUTTON = 0x0010,  
                    XBUTTON1 = 0x0020,  
                    XBUTTON2 = 0x0040  
                }  
          
          
          
                [Flags]  
                internal enum TOUCH_FLAGS  
                {  
                    NONE = 0x00000000  
                }  
          
                [Flags]  
                internal enum TOUCH_MASK  
                {  
                    NONE = 0x00000000,  
                    CONTACTAREA = 0x00000001,  
                    ORIENTATION = 0x00000002,  
                    PRESSURE = 0x00000004,  
                }  
          
                [Flags]  
                internal enum PEN_FLAGS  
                {  
                    NONE = 0x00000000,  
                    BARREL = 0x00000001,  
                    INVERTED = 0x00000002,  
                    ERASER = 0x00000004,  
                }  
          
                [Flags]  
                internal enum PEN_MASK  
                {  
                    NONE = 0x00000000,  
                    PRESSURE = 0x00000001,  
                    ROTATION = 0x00000002,  
                    TILT_X = 0x00000004,  
                    TILT_Y = 0x00000008,  
                }  
          
                [Flags]  
                internal enum POINTER_MESSAGE_FLAG  
                {  
                    NEW = 0x00000001,  
                    INRANGE = 0x00000002,  
                    INCONTACT = 0x00000004,  
                    FIRSTBUTTON = 0x00000010,  
                    SECONDBUTTON = 0x00000020,  
                    THIRDBUTTON = 0x00000040,  
                    FOURTHBUTTON = 0x00000080,  
                    FIFTHBUTTON = 0x00000100,  
                    PRIMARY = 0x00002000,  
                    CONFIDENCE = 0x00004000,  
                    CANCELED = 0x00008000,  
                }  
          
                internal enum TOUCH_FEEDBACK  
                {  
                    DEFAULT = 0x1,  
                    INDIRECT = 0x2,  
                    NONE = 0x3  
                }  
          
                #endregion  
          
                //------------------------------------------------------------------  
          
          
                //------------------------------------------------------------------  
                #region ** misc structs  
          
          
                #region POINT  
          
                [StructLayout(LayoutKind.Sequential)]  
                internal struct POINT  
                {  
                    public int X;  
                    public int Y;  
          
                    public POINT(int x, int y)  
                    {  
                        X = x;  
                        Y = y;  
                    }  
                    public POINT(Point pt)  
                    {  
                        X = pt.X;  
                        Y = pt.Y;  
                    }  
                    public Point ToPoint()  
                    {  
                        return new Point(X, Y);  
                    }  
                    public void AssignTo(ref Point destination)  
                    {  
                        destination.X = X;  
                        destination.Y = Y;  
                    }  
                    public void CopyFrom(Point source)  
                    {  
                        X = source.X;  
                        Y = source.Y;  
                    }  
                    public void CopyFrom(POINT source)  
                    {  
                        X = source.X;  
                        Y = source.Y;  
                    }  
                }  
          
                #endregion  
          
                #region RECT  
          
                [StructLayout(LayoutKind.Sequential)]  
                internal struct RECT  
                {  
                    public int Left;  
                    public int Top;  
                    public int Right;  
                    public int Bottom;  
          
                    public RECT(Rectangle source)  
                    {  
                        Left = source.Left;  
                        Top = source.Top;  
                        Right = source.Right;  
                        Bottom = source.Bottom;  
                    }  
                    public RECT(int x, int y, int width, int height)  
                    {  
                        Left = x;  
                        Top = y;  
                        Right = Left + width;  
                        Bottom = Top + height;  
                    }  
                    public int Width  
                    {  
                        get { return Right - Left; }  
                    }  
                    public int Height  
                    {  
                        get { return Bottom - Top; }  
                    }  
                    public Rectangle ToRectangle()  
                    {  
                        return new Rectangle(Left, Top, Width, Height);  
                    }  
                    public void Inflate(int dx, int dy)  
                    {  
                        Left -= dx;  
                        Top -= dy;  
                        Right += dx;  
                        Bottom += dy;  
                    }  
                    public void Deflate(int leftMargin, int topMargin, int rightMargin, int bottomMargin)  
                    {  
                        Left += leftMargin;  
                        Top += topMargin;  
                        Right -= rightMargin;  
                        Bottom -= bottomMargin;  
                        if (Bottom < Top)  
                        {  
                            Bottom = Top;  
                        }  
                        if (Right < Left)  
                        {  
                            Right = Left;  
                        }  
                    }  
                    public void Offset(int dx, int dy)  
                    {  
                        Left += dx;  
                        Top += dy;  
                        Right += dx;  
                        Bottom += dy;  
                    }  
                }  
          
                #endregion  
          
                #endregion  
          
                //------------------------------------------------------------------  
                #region ** pointer structs  
          
                #region POINTER_INFO  
          
                [StructLayout(LayoutKind.Sequential)]  
                internal struct POINTER_INFO  
                {  
                    public POINTER_INPUT_TYPE pointerType;  
                    public int PointerID;  
                    public int FrameID;  
                    public POINTER_FLAGS PointerFlags;  
                    public IntPtr SourceDevice;  
                    public IntPtr WindowTarget;  
                    [MarshalAs(UnmanagedType.Struct)]  
                    public POINT PtPixelLocation;  
                    [MarshalAs(UnmanagedType.Struct)]  
                    public POINT PtPixelLocationRaw;  
                    [MarshalAs(UnmanagedType.Struct)]  
                    public POINT PtHimetricLocation;  
                    [MarshalAs(UnmanagedType.Struct)]  
                    public POINT PtHimetricLocationRaw;  
                    public uint Time;  
                    public uint HistoryCount;  
                    public uint InputData;  
                    public VIRTUAL_KEY_STATES KeyStates;  
                    public long PerformanceCount;  
                    public int ButtonChangeType;  
                }  
          
                #endregion  
          
                #region POINTER_TOUCH_INFO  
          
                [StructLayout(LayoutKind.Sequential)]  
                internal struct POINTER_TOUCH_INFO  
                {  
                    [MarshalAs(UnmanagedType.Struct)]  
                    public POINTER_INFO PointerInfo;  
                    public TOUCH_FLAGS TouchFlags;  
                    public TOUCH_MASK TouchMask;  
                    [MarshalAs(UnmanagedType.Struct)]  
                    public RECT ContactArea;  
                    [MarshalAs(UnmanagedType.Struct)]  
                    public RECT ContactAreaRaw;  
                    public uint Orientation;  
                    public uint Pressure;  
                }  
          
                #endregion  
          
                #region POINTER_PEN_INFO  
          
                [StructLayout(LayoutKind.Sequential)]  
                internal struct POINTER_PEN_INFO  
                {  
                    [MarshalAs(UnmanagedType.Struct)]  
                    public POINTER_INFO PointerInfo;  
                    public PEN_FLAGS PenFlags;  
                    public PEN_MASK PenMask;  
                    public uint Pressure;  
                    public uint Rotation;  
                    public int TiltX;  
                    public int TiltY;  
                }  
          
                #endregion  
          
                #endregion  
          
                //------------------------------------------------------------------  
                #region ** interaction context structs  
          
          
          
          
          
          
                #region INTERACTION_CONTEXT_OUTPUT  
          
          
                #endregion  
          
                #endregion  
          
          
                #region ** pointer methods  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool InitializeTouchInjection(int maxCount, TOUCH_FEEDBACK feedbackMode);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool InjectTouchInput(int count, [MarshalAs(UnmanagedType.LPArray), In] POINTER_TOUCH_INFO[] contacts);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerType(int pointerID, out POINTER_INPUT_TYPE pointerType);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerInfo(int pointerID, ref POINTER_INFO pointerInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerInfoHistory(int pointerID, ref int entriesCount, [MarshalAs(UnmanagedType.LPArray), In, Out] POINTER_INFO[] pointerInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerInfoHistory(int pointerID, ref int entriesCount, IntPtr pointerInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerFrameInfo(int pointerID, ref int pointerCount, [MarshalAs(UnmanagedType.LPArray), In, Out] POINTER_INFO[] pointerInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerFrameInfo(int pointerID, ref int pointerCount, IntPtr pointerInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerFrameInfoHistory(int pointerID, ref int entriesCount, ref int pointerCount,  
                    [MarshalAs(UnmanagedType.LPArray), In, Out] POINTER_INFO[] pointerInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerFrameInfoHistory(int pointerID, ref int entriesCount, ref int pointerCount, IntPtr pointerInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerTouchInfo(int pointerID, ref POINTER_TOUCH_INFO touchInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerFrameTouchInfo(int pointerID, ref int pointerCount, [MarshalAs(UnmanagedType.LPArray), In, Out] POINTER_TOUCH_INFO[] touchInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerFrameTouchInfo(int pointerID, ref int pointerCount, IntPtr touchInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerPenInfo(int pointerID, ref POINTER_PEN_INFO penInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerFramePenInfo(int pointerID, ref int pointerCount, [MarshalAs(UnmanagedType.LPArray), In, Out] POINTER_PEN_INFO[] penInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool GetPointerFramePenInfo(int pointerID, ref int pointerCount, IntPtr penInfo);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool SkipPointerFrameMessages(int pointerID);  
          
                [DllImport("user32.dll", SetLastError = true)]  
                internal static extern bool EnableMouseInPointer([MarshalAs(UnmanagedType.Bool), In] bool enable);  
          
                [DllImport("user32.dll")]  
                internal static extern bool IsMouseInPointerEnabled();  
          
                #endregion  
          
                 
            }  
    

    If the answer is the right solution, please click "Accept Answer" and upvote it.If you have extra questions about this answer, please click "Comment".

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


  2. Gennady Gurin 41 Reputation points
    2022-02-28T22:42:55.647+00:00

    Thanks, I got it to build, however, I got a new error in Program.cs :

    Error 1 The type or namespace name 'Form1' could not be found (are you missing a using directive or an assembly reference?) C:\Users\Gennady G\Documents\Visual Studio 2013\Projects\WindowsFormsApplication-Test3\WindowsFormsApplication-Test3\Program.cs 24 17 WindowsFormsApplication-Test3

    static void Main()
    {
    string strProcessName = Process.GetCurrentProcess().ProcessName;
    Process[] Oprocesses = Process.GetProcessesByName(strProcessName);

            if (Oprocesses.Length == 1)
            {
                Form1 f1 = new Form1();
               // int height = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
              //  int width = System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
              //  f1.Size = new Size(height   , width );
    
                Application.EnableVisualStyles();
                //Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(f1);
            }
            else { }
        }
    

    this line: Form1 f1 = new Form1(); error

    and another error:

    Warning 3 Processing COM reference "WMPLib" from path "C:\WINDOWS\system32\wmp.dll". At least one of the arguments for 'IWMPGraphEventHandler.NotifyAcquireCredentials' cannot be marshaled by the runtime marshaler. Such arguments will therefore be passed as a pointer and may require unsafe code to manipulate. WindowsFormsApplication-Test3

    also, I cannot find a file to open actual form design, meaning physical form where you bring items. And could not find how to

    open explorer, meaning where I add events and items ? It is very confusing


  3. Gennady Gurin 41 Reputation points
    2022-05-17T01:27:35.733+00:00

    Hi I have tested a Windows Form C# application on the tablet , everything is working, except there is a small bug, when I top with my finger anywhere else except buttons or

    pictures, or any controls, but just on a form itself I get an exception ERROR:. I have attached a file, and would be happy to fix it.

    Get back, thanks in advance.

    202484-exception-form-error.jpg

    ************** Exception Text **************
    System.NullReferenceException: Object reference not set to an instance of an object.
    at WindowsFormsApplication_Test3.Form1.WndProc(Message& m) in c:\Users\Gennady G\Documents\Visual Studio 2013\Projects\WindowsFormsApplication-Test3\WindowsFormsApplication-Test3\Form1.cs:line 1426
    at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
    at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
    at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.