windows - 'SendMessage' til 3 forskellige processer i C ++

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg vil sende tastetryk til flere processer. For eksempel, hvis jeg trykker på '1', så vil jeg sende '1' til 3 'Notesblok-vinduer'. Frist Jeg vil forsøge at sende et tastetryk til notesblok, men det fejler på HWND:


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


Men 'FindWindow' -metoden er ikke god nok til mit program. Der er heller ikke mulighed for at få 3 forskellige processer med samme navn. Så hvordan kan jeg lave 3 håndtag til 3 forskellige processer med samme navn? Og hvordan kan jeg sende nøgler til processerne?

Bedste reference


Du kan bruge EnumWindows til at opregne alle topniveau vinduer på systemet. Du skal derefter filtrere gennem disse vinduer for at få de du er interesseret i. Klassenavn er nok et bedre valg til filtrering end vinduets navn. Her er nogle eksempler kode (ikke testet) af hvad jeg har i tankerne: [9]


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


Bemærk brugen af ​​BroadcastToNotepad, og hvordan du kan have forskellige håndtere passere i en anden lParam.


En sidste ting at bemærke er, at PostMessage/SendMessage ikke er en pålidelig måde at simulere tastaturindgang på. Dette bemærkes af Raymond Chen her. SendInput er den foretrukne måde at injicere input på. Men for at bruge det skal du sikre, at vinduet du vil sende til, har tastaturets fokus. [10]


Jeg husker vagt at have spillet med noget, der ligner det, du gør i fortiden. Hvis jeg husker korrekt, skal du sende til Notepads barnevindue (klassenavn=Edit. Så koden ovenfor skal ændres som sådan:


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

Andre referencer 1


Først installerer du Spy ++ fra Visual Studio, som lader dig se alle HWND-vinduerne i hierarkiet (og hvilken proces ejer dem). [11]


Så kan du se, hvorfor din FindWindow fejler. Du kan også kende det nøjagtige hierarkiopkald til FindWindow og GetWindow ().


Vær opmærksom på, at siden Vista er nogle HWND'er beskyttet, og du kan ikke sende til dem - men notepad er nok fint.


For at sende nøglen kan du nok kun bruge PostMessage til at slukke og glemme.

Andre referencer 2


Først og fremmest, hvorfor er der (sandt) der? Ville du ikke hellere aktivere din software på F12-tastetryk end at have en uendelig loop? Det håndtag er ikke gyldigt for altid, du ved det.


For det andet vil du sandsynligvis bruge EnumWindows til at gå igennem alle vinduerne og finde den du er interesseret i. Derefter implementerer du en tilbagekaldelsesfunktion, som 'skal beslutte på en eller anden basis, hvis den ønsker at handle på nogle vindue eller ej (det være sig navn eller noget andet). [12]


SendMessage/SendMessageA/SendMessageW skal fungere fint, når du har fundet et ordentligt håndtag til det vindue du vil målrette mod (gem til nogle specielle vinduer, der er beskyttet mod dette).