2012-03-25 14 views
2

複数のプロセスにキーストロークを送信したい。たとえば、「1」を押すと、「1」〜「3」のメモ帳ウィンドウが送信されます。フリストは、私がメモ帳にキーストロークを送信するために試してみたいが、それはHWNDに失敗します。"SendMessage"をC++の3つの異なるプロセスに

//HANDLE hWin; 
    HWND windowHandle = FindWindowA(NULL, "Notepad"); //Can’t find a proccess 

    //Send a key 
    if(windowHandle) //This one fails 
    { 
     while(true) 
     { 
      if(GetAsyncKeyState(VK_F12) != 0) 
      { 
       SendMessageA(windowHandle, WM_KEYDOWN, VK_NUMPAD1, 0); 
       Sleep(1000); 
       SendMessageA(windowHandle, WM_KEYUP, VK_NUMPAD1, 0); 
      } 
        Sleep(100); 
     } 
    } 

しかし、「FindWindowを」方法は私のプログラムのために十分ではありません。同じ名前の3つの異なるプロセスを取得する方法もありません。だから私は3つの異なるプロセスに3つのハンドルを同じ名前で作ることができますか?そして、どのようにキーをプロセスに送ることができますか?

+0

メモ帳のウィンドウタイトルは通常「無題 - メモ帳」です。 SendInputを使うほうがよいでしょう。 –

答えて

3

あなたは、システム上のすべてのトップレベルウィンドウを列挙するためEnumWindowsを使用することができます。興味のあるものを取得するには、これらのウィンドウをフィルタリングする必要があります。ウィンドウ名ではなく、クラス名はおそらくフィルタリングの方がいいでしょう。

BOOL CALLBACK BroadcastToNotepad(HWND hwnd, LPARAM lParam) 
{ 
    wchar_t lpClassName[16]; 

    /* 
    * More reliable to filter by class name. We could additionally filter 
    * by caption name too if necessary. 
    */ 
    if(GetClassName(hwnd, lpClassName, _countof(lpClassName))) { 
     if(wcscmp(lpClassName, L"Notepad") == 0) { 
      SendMessage(hwnd, WM_KEYDOWN, (WPARAM)lParam, 0); 
      Sleep(1000); 
      SendMessage(hwnd, WM_KEYUP, (WPARAM)lParam, 0); 
     } 
    } 

    return TRUE; 
} 

// Some handler which gets invoked when your hotkey is hit. 
void handlerKey1(...) 
{ 
    EnumWindows(BroadcastToNotepad, (lParam)VK_NUMPAD1) 
} 

BroadcastToNotepadの使用を注意してください、あなたは別のハンドラが異なるlParamに渡すことができますどのように:ここで私は心の中で持っているもののいくつかのサンプルコードは(テストしていない)です。

最後に、PostMessage/SendMessageは、キーボード入力をシミュレートする信頼できる方法ではありません。これはRaymond Chen hereによって指摘されています。 SendInputは入力を入力するのに適した方法です。しかし、それを使用するには、送信するウィンドウにキーボードのフォーカスがあることを確認する必要があります。

私は漠然と、あなたが過去に何をしているかに似たものと共演したリコール。私が正しく覚えていれば、メモ帳の子ウィンドウ(クラス名= Edit)に送る必要があります。したがって、上記のコードは次のように変更する必要があります。

if(wcscmp(lpClassName, L"Notepad") == 0) { 
    HWND hwndChild = FindWindowEx(hwnd, NULL, L"Edit", NULL); 

    SendMessage(hwndChild, WM_KEYDOWN, (WPARAM)lParam, 0); 
    Sleep(1000); 
    SendMessage(hwndChild, WM_KEYUP, (WPARAM)lParam, 0); 
} 
1

まずあなたが階層内のすべてのHWNDウィンドウを参照してください(とプロセスがそれらを所有している)ことができますのVisual StudioからSpy++をインストールします。

FindWindowが失敗している理由がわかります。また、FindWindowとGetWindow()で行う階層呼び出しも正確にわかります。

はビスタ以来、いくつかのHWNDが保護され、あなたがそれらに送る傾けることに注意してください - しかし、メモ帳はおそらく大丈夫です。

キーを送信するために、あなたはおそらくちょうどファイア・アンド・フォーゲットするのPostMessageを使用することができます。

0

まず第一に、while(true)はなぜですか?むしろ無限ループを持つよりF12キーを押してソフトウェアをアクティブにしたいのですか?そのハンドルは永遠に有効ではありません。

第2に、EnumWindowsを使用して、すべてのウィンドウを調べて興味のあるものを探したい場合があります。次に、必要に応じて何らかの基準で決定する必要があるコールバック関数を実装しますいくつかのウィンドウで動作するかどうか(名前など)。

SendMessage/SendMessageA/SendMessageWは、対象とするウィンドウの適切なハンドルを見つけたときにうまく動作するはずです(このウィンドウから保護されている特別なウィンドウでは保存します)。

関連する問題