拦截鼠标点击其他程序

时间:2013-04-02 22:16:01

标签: c# .net winapi hook windows-messages

我正在尝试拦截来自其他程序的鼠标点击。我正在为该程序制作一个插件,它在程序上覆盖透明表单并显示其他信息。当我点击表单的透明部分时,我可以点击main程序中的内容。我不希望这种情况发生(至少不是每次都有 - 有些部分允许你点击,有些部分你不是,但这不是问题)。< / p>

我现在这样做的方法是使用WH_MOUSE_LL,这工作正常,我可以通过返回非零值(http://msdn.microsoft.com/en-gb/library/windows/desktop/ms644988(v=vs.85).aspx)来保持鼠标点击进入程序。

问题是,这使得我的主程序滞后,我不需要获取所有鼠标移动的通知,我只想在用户实际点击某些内容时收到通知。有什么方法可以限制WH_MOUSE_LL所以它只会在点击鼠标时触发吗? (滞后不是因为MouseHookProc方法中的计算 - 它除了调用CallNextHookEx(hHook, nCode, wParam, lParam)之外当前什么也没做。)

我试图通过使用挂钩WM_MOUSEACTIVATE消息的全局钩子(http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H)来解决这个问题。我的想法是仅在收到WH_MOUSE_LL通知时才挂钩WM_MOUSEACTIVATE。很遗憾WH_MOUSE_LL点击通知会在WM_MOUSEACTIVATE之前发送,因此无效。

修改

@Nanda这里是proc代码:

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

正如你所看到的那样,我对它没有做太多的事情,但它已经落后了......

@Cody Gray我对处理邮件的表单做了一个非常小的测试:

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

当你说:“返回它是否透明并让它被路由到它下面的窗口?”我可以通过使用SendMessage并基本上复制我在WndProc方法中收到的消息来做到这一点吗?

为了使事情变得更复杂,我也使用这种形式http://www.codeproject.com/Articles/1822/Per-Pixel-Alpha-Blend-in-C。根据我的理解,这使我能够在背景上反抗锯齿的表单上绘制位图。使用此表单似乎无法设置不透明度,因为它始终是透明的。是否有更好的方法在表单上绘制位图?

1 个答案:

答案 0 :(得分:2)

您可能需要查看Easyhook(http://easyhook.codeplex.com/),它允许您从单个进程而不是所有进程挂接Windows API调用。