2013-04-02 14 views
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をフックメッセージ。私がWM_MOUSEACTIVATE通知を受け取ったときのアイデアは、WH_MOUSE_LLにしかつながっていませんでした。残念ながらWH_MOUSE_LLクリック通知はWM_MOUSEACTIVATEの前に送信されますので、これは機能しません。

EDIT:あなたは私は気圧それであまりやっていないんだけど、それはすでに遅れて見ることができるように

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

...:

@Nandaは、ここでのprocコードです

@Cody Greyメッセージを処理するフォームのための非常に小さなテストを行いました:

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も使用しています。私の理解によれば、これはバックグラウンドに対してAnti Aliasingであるフォームにビットマップを描くことを可能にします。このフォームでは、常に透過的なので、不透明度を設定する方法はないようです。フォームにビットマップを描画する方法はありますか?

+1

あなたのフックprocは、イベントの種類をチェックして無関係のイベントに出かける前に、あまりにも多くの操作を実行している可能性があります。あなたのフックprocをCallNextHook(...)だけに戻し、増分変更を加える。 – nanda

+0

オーバーレイフォームは、発生したすべてのマウスイベントを受信して​​適切にフィルタリングできないのはなぜですか?それが処理される予定の場合は、処理してください。そうでない場合は、透明であることを返し、その下のウィンドウにルーティングさせますか?グローバルフックはほとんど常に間違った解決策です(しかし、ナンダの提案はあなたがそれを使用しなければならない場合には良いものです)。 –

+0

両方のご意見ありがとうございます、私はいくつかのコードといくつかの追加情報で私の最初の質問を編集しました。 @Nanda私はあなたが何を意味しているのか正確にはわかりません、私は現在CallNextHookExを返すだけですが、これは既に遅れています(最初の投稿に自分のprocコードを追加しました)。 – VincentC

答えて

1

Easyhook(http://easyhook.codeplex.com/)を調べると、すべてのプロセスではなく単一のプロセスからWindows API呼び出しを呼び出すことができます。

関連する問題