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ここにprocコードがあります:

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 に答える