2016-10-26 3 views
2

私は、画面のどこからでも色を取得するカラーピッカーを実装しようとしています。 これを行うには、グローバルマウスフックを使用してWM_MOUSEMOVEを聞いて、マウスを移動してマウスのクリックを聞いて(WM_LBUTTONDOWN)確認するか、操作をキャンセル(WM_RBUTTONDOWN)して色を更新する予定です。マウスフックの接続が外されました

私は周りの多くのチュートリアルの1に続いていると私は(プロセスが動作するかどうかだけでテストするために、コンソールアプリケーションで)この思い付いた:

static IntPtr hook; 
static bool click; 
static NativeMethods.LowLevelHookStruct llhs; 

static void Main(string[] args) 
{ 
    hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, MouseHookCallback, (IntPtr)null, 0); 
    if (hook != IntPtr.Zero) 
    { 
    Console.WriteLine("Hook Set"); 
    while (!Console.KeyAvailable) { 
     Console.WriteLine("{0} {1} {2}", hook, llhs.pt.x, llhs.pt.y); 

     if(click) Console.WriteLine("click!"); 
     click = false; 

     System.Threading.Thread.Sleep(250); 
    } 
    } 
} 

public static IntPtr MouseHookCallback(int nCode, IntPtr wParam, IntPtr lParam) 
{ 
    if (nCode >= 0) 
    { 
    NativeMethods.LowLevelHookStruct hookStruct = (NativeMethods.LowLevelHookStruct)Marshal.PtrToStructure(lParam, typeof(NativeMethods.LowLevelHookStruct)); 

    if (NativeMethods.MouseMessages.WM_MOUSEMOVE == (NativeMethods.MouseMessages)wParam) 
    { 
     llhs = hookStruct; 
    } 

    if (NativeMethods.MouseMessages.WM_LBUTTONDOWN == (NativeMethods.MouseMessages)wParam) 
    { 
     click = true; 
    } 
    else if (NativeMethods.MouseMessages.WM_RBUTTONDOWN == (NativeMethods.MouseMessages)wParam) 
    { 
    } 
    } 

    return NativeMethods.CallNextHookEx(hook, nCode, wParam, lParam); 
} 

をNativeMethodsは単にDllImport関連のものをすべて保持するクラスです。私は、コンソールアプリケーションを実行すると

は、マウスカーソルを数秒間立ち往生、およびコンソールで、私はこれを取得 - カーソルがありながらも

Hook Set 
3945554872 0 0 
3945554872 0 0 
3945554872 0 0 
3945554872 0 0 
... 

はデバッグにそれで行く立ち往生私のフックは決して一度も呼び出されないようです。 何が間違っている可能性がありますか?

+0

質問のタイトルからタグを削除しました。なぜ[ここ](http://stackoverflow.com/help/tagging)を読んでください。 – dymanoid

+0

ああ、忘れてしまった。ありがとう:) – SirePi

+1

WH_MOUSE_LLフックはWindowsがフックコールバックを安全に呼び出せるようにメッセージループを必要とします。 Application.Run().NETプログラムで。最も簡単にWinformsやWPFプロジェクト、またはこれを行う多くのライブラリの1つから得られたものです。 –

答えて

0

@Hans Passantのコメントに続いて、テストコードをWinFormsアプリケーションに移動し、コールバックが開始されました。

そして、私がしなければならなかったすべては維持するために、

private NativeMethods.LowLevelHookProc _hookCallback; 

... 

_hookCallback = new NativeMethods.LowLevelHookProc(MouseHookCallback); 
hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, _hookCallback, (IntPtr)null, 0); 

hook = NativeMethods.SetWindowsHookEx(NativeMethods.WH_MOUSE_LL, MouseHookCallback, (IntPtr)null, 0); 

を変更した、コールバックがガベージコレクトされていたことを見つけるためにだけの問題でしたGCedされないようにコールバックを参照してください。

関連する問題