Search code examples
.netvb.netwinformswindows-messages

How to capture mouse windows messages out of the application?


First of all sorry 'cause maybe this could be a too localized question for C# but anyways I didn't find info about this for VB.NET and I don't understand in a good level C# code.

Basically I need to capture/process some mouse messages out of the application.

How I could do it?

This is just a code example of what I need to reproduce but outside the application:

Protected Overrides Sub WndProc(ByRef m As Message)

    Select Case m.Msg

        Case &H200 ' WM_MOUSEMOVE
            MsgBox("Mouse Move")

        Case &H201 ' WM_LBUTTONDOWN
            MsgBox("Left Button Down")

        Case &H202 ' WM_LBUTTONUP 
            MsgBox("Left Button Up")

        Case Else
            MyBase.WndProc(m)

    End Select

End Sub

The main idea is to press a button that will hide the application to let the user selects a region over the screen and there is where I need to capture those windows messages to know when I need to start/end the region selection.


Solution

  • There are two ways to do this.

    1. Using global hooks (Google it) I do not recommend.

    2. Making ur winform transparent.

    U need set transparent color of ur winform as the background control color. To make the form unfocusable u need add this code to ur message handler

    if (m.Msg == WM_MOUSEACTIVATE)
    {
        m.Result = new IntPtr(MA_NOACTIVATE);
        return;
    }  
    

    if u want to receive left-click message just add this code before MouseActivate massage.

    if (m.Msg == WM_LBUTTONDOWN)
    {
    } 
    

    Complete Example

    namespace
    {
        public partial class XXXXXForm : Form
        {
            private const int WM_MOUSEACTIVATE = 0x21;
            private const int WM_LBUTTONDOWN = 0x0201;
            private const int MK_LBUTTON = 0x0001;
            private const int MA_NOACTIVATE = 3;
    
            public ClockForm()
            {
                InitializeComponent();
    
                this.DoubleBuffered = true;
                this.TopMost = true;
                this.FormBorderStyle = FormBorderStyle.None;
                this.ShowIcon = false;
                this.ShowInTaskbar = false;
                this.TransparencyKey = this.BackColor;
    
            }
    
    
            [DllImport("User32.dll", EntryPoint = "SendMessage")]
            private extern static int SendMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
            [DllImport("user32.dll")]
            public static extern bool ReleaseCapture();
            private const int WM_SYSCOMMAND = 0x112;
            private const int SC_MOVE = 0xF010;
            private const int HTCAPTION = 0x0002;
    
    
            protected override void WndProc(ref Message m)
            {
    
                if (m.Msg == WM_LBUTTONDOWN)
                {
    ...
                }
                else if (m.Msg == WM_MOUSEACTIVATE)
                {
                    m.Result = new IntPtr(MA_NOACTIVATE);
                    return;
                }
                base.WndProc(ref m);
    
            }
    
            protected override bool ShowWithoutActivation
            {
                get
                {
                    return false;
                }
            }
    
            private void Form_Paint(object sender, PaintEventArgs e)
            {
    
            }
    
        }
    }