Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept mouse click from other program

I’m trying to intercept mouse clicks from another program. I’m making a plugin for the program, that overlays a transparent form on the program and displays additional information. When I click on the transparent part of the form I can click on things in the main program. I don’t want this to happen (at least not every time - there are some parts where you are allowed to click and some parts where you aren’t but this isn’t the problem).

The way I’m doing this now is by using WH_MOUSE_LL, this is working fine and I can keep the mouse click from getting to the program by returning a non zero value (http://msdn.microsoft.com/en-gb/library/windows/desktop/ms644988(v=vs.85).aspx).

The problem is, this makes my main program lag, I don’t need to get notifications for all mouse movements, I only want to get a notification if the user actually clicked something. Is there any way I can limit the WH_MOUSE_LL so it only fires on mouse clicks? (The lag isn’t because of calculations in the MouseHookProc method - it’s currently doing nothing except for calling: CallNextHookEx(hHook, nCode, wParam, lParam).)

I’ve tried to fix this by using a global hook (http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H) that hooks the WM_MOUSEACTIVATE message. The idea was to only hook up the WH_MOUSE_LL when I received a WM_MOUSEACTIVATE notification. Unfortunately WH_MOUSE_LL click notification gets sent before WM_MOUSEACTIVATE so this doesn't work.

EDIT:

@Nanda here’s the proc code:

public int MouseHookProc(int nCode, IntPtr wParam, IntPtr lParam)
{
    return WindowUtility.CallNextHookEx(hHook, nCode, wParam, lParam);
}

As you can see I’m not doing very much with it atm, but it already lags...

@Cody Gray I’ve made a very small test for the Form handling the messages:

public class Form1 : Form
{
    private TrackBar m_Trackbar;

    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }

    public Form1()
    {
        m_Trackbar = new System.Windows.Forms.TrackBar();
        m_Trackbar.LargeChange = 1;
        m_Trackbar.Location = new System.Drawing.Point(5, 10);
        m_Trackbar.Maximum = 100;
        m_Trackbar.Size = new System.Drawing.Size(280, 40);
        m_Trackbar.Value = 100;
        this.Controls.Add(m_Trackbar);

        m_Trackbar.Scroll += new System.EventHandler(this.m_TrackbarScroll);
    }


    private void m_TrackbarScroll(object sender, System.EventArgs e)
    {
        this.Opacity = ((Convert.ToDouble(m_Trackbar.Value)) / 100);
    }

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case 0x201: //WM_LBUTTONDOWN
                Console.WriteLine("MouseButton Down!");
                //I could copy the Message over to the MainProgram with this right?
                //SendMessage(MainProgramHwnd, m.Msg, m.WParam, m.LParam);
                //This will also only work on an opacity higher than 0.
                break;
        }
        base.WndProc(ref m);
    }
}

When you said: “return that it's transparent and let it be routed to the window underneath it?” Can I do this by using SendMessage and basically copying the message I receive in my WndProc method?

To make things more complicated I’m also using this form http://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C. To my understanding this enables me to draw bitmaps on the form who are Anti Aliasing against the background. With this form there seems to be no way to set the opacity, as it’s just transparent all the time. Is there a better way to draw bitmaps on a Form?

like image 457
VincentC Avatar asked Apr 02 '13 22:04

VincentC


1 Answers

You may want to look into Easyhook (http://easyhook.codeplex.com/) which will allow you to hook Windows API calls from a single process rather than for all processes.

like image 163
Nick Wilton Avatar answered Nov 18 '22 15:11

Nick Wilton