8

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

我现在这样做的方式是使用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)。)

我试图通过使用挂钩消息的全局挂钩( http://www.codeproject.com/Articles/18638/Using-Window-Messages-to-Implement-Global-System-H)来解决此问题。WM_MOUSEACTIVATE这个想法是只WH_MOUSE_LL在我收到WM_MOUSEACTIVATE通知时才连接。不幸的是WH_MOUSE_LL,点击通知之前已发送,WM_MOUSEACTIVATE因此这不起作用。

编辑:

@Nanda 这是过程代码:

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

正如你所看到的,我在 atm 上做的并不多,但它已经滞后了......

@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。据我了解,这使我能够在表单上绘制具有抗锯齿背景的位图。使用这种形式似乎无法设置不透明度,因为它一直都是透明的。有没有更好的方法在表单上绘制位图?

4

1 回答 1

2

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

于 2013-04-04T09:45:30.347 回答