2012-03-25 10 views
2

Ich möchte Tastenanschläge an mehrere Prozesse senden. Wenn ich zum Beispiel "1" drücke, möchte ich die "1" an 3 "Notepad-Fenster" senden. Frist Ich möchte versuchen, einen Tastendruck Notizblock zu senden, aber es funktioniert nicht auf dem HWND:"SendMessage" zu 3 verschiedenen Prozessen in C++

//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); 
     } 
    } 

Aber die „Findwindow“ Methode ist für mein Programm nicht gut genug. Es gibt auch keine Möglichkeit, 3 verschiedene Prozesse mit demselben Namen zu erhalten. Also, wie kann ich 3 Griffe zu 3 verschiedenen Prozessen mit dem gleichen Namen machen? Und wie kann ich Schlüssel an die Prozesse senden?

+0

Notepad Fenstertitel ist normalerweise "Unbenannt - Editor". Und Sie sollten SendInput besser verwenden. –

Antwort

3

Sie können EnumWindows zum Aufzählen aller Top-Level-Fenster auf dem System verwenden. Sie müssen dann durch diese Fenster filtern, um diejenigen zu erhalten, an denen Sie interessiert sind. Klassenname ist wahrscheinlich eine bessere Wahl für die Filterung als für den Fensternamen. Hier einige Beispiel-Code (nicht getestet) von dem, was ich im Sinn haben:

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) 
} 

Beachten Sie die Verwendung von BroadcastToNotepad und wie können Sie verschiedene Handler in einem anderen lParam passieren müssen.

Eine letzte Sache zu beachten ist, dass PostMessage/SendMessage ist keine zuverlässige Möglichkeit, Tastatureingabe zu simulieren. Dies wird von Raymond Chen here zur Kenntnis genommen. SendInput ist die bevorzugte Methode zum Einspeisen von Eingaben. Allerdings müssen Sie sicherstellen, dass das Fenster, an das Sie senden möchten, den Tastaturfokus hat.

Ich erinnere mich vage mit etwas gespielt zu haben, was dem ähnelt, was du in der Vergangenheit machst. Wenn ich mich richtig erinnere, müssen Sie an das untergeordnete Fenster des Editors senden (Klassenname = Edit). So muss der obige Code wie folgt geändert werden:

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

Zuerst installieren Sie Spy++ von Visual Studio, mit dem Sie alle HWND-Fenster in der Hierarchie sehen können (und welcher Prozess besitzt sie).

Dann werden Sie sehen, warum Ihr FindWindow fehlschlägt. Sie kennen auch die genauen Hierarchieaufrufe, die Sie in FindWindow und GetWindow() vornehmen müssen.

Beachten Sie, dass seit Vista einige HWNDs geschützt sind und Sie ihnen nicht senden können - aber Notizblock ist wahrscheinlich in Ordnung.

Zum Senden des Schlüssels können Sie wahrscheinlich einfach PostMessage verwenden, um zu feuern und zu vergessen.

0

Vor allem, warum ist while (wahr) dort? Wollen Sie nicht lieber Ihre Software mit F12 drücken als mit einer Endlosschleife? Dieser Griff ist nicht für immer gültig, weißt du?

Zweitens möchten Sie wahrscheinlich EnumWindows verwenden, um durch alle Fenster zu gehen und den zu finden, an dem Sie interessiert sind. Dann würden Sie eine Callback-Funktion implementieren, die auf irgendeiner Basis entscheiden muss, wenn sie will um auf irgendein Fenster zu wirken oder nicht (sei es Name oder etwas anderes).

SendMessage/SendMessageA/SendMessageW sollte gut funktionieren, wenn Sie ein geeignetes Handle für das Fenster gefunden haben, für das Sie ein Targeting durchführen möchten (für einige spezielle Fenster, die davor geschützt sind).

Verwandte Themen