Symulowanie naciśnięcia klawisza za pomocą PostMessage działa tylko w niektórych aplikacjach?

Moje podejście do tego problemu okazało się poprawne tylko w kilku programach. Dlaczego nie jest uniwersalny?

Działa dobrze na:

Firefox
Edytor tekstu Visual Studio

Niestety w niektórych przypadkach nic się nie dzieje (nawet jeśli kliknę w pole tekstowe przed wykonaniem mojego programu):

Google ChromeNotatnik

GetLastError zwraca zawsze 0, nawet używając SendMessage zamiast PostMessage. Czy możesz wskazać mój błąd?

#include <Windows.h>
#include <iostream>

int main()
{
    HWND hCurrentWindow;

    Sleep(5000);

    hCurrentWindow = GetForegroundWindow();

    std::cout<<"GO!!!\n";

    for(int i=0; i<500; i++) //simulate 500 keystrokes of 'E'.
        {
            PostMessage(hCurrentWindow,WM_KEYDOWN,0x45,NULL);
            PostMessage(hCurrentWindow,WM_KEYUP,0x45,NULL);
        }

    std::cout<<GetLastError()<<std::endl;

    system("Pause");
    return 0;
}

AKTUALIZUJ po sugestii Maximusa

#include <Windows.h>
#include <iostream>

int main()
{
    HWND hCurrentWindow;

    Sleep(5000);

    hCurrentWindow = GetForegroundWindow();

    if(!hCurrentWindow)
        std::cout<<"Failed get set the window handle\n";

    std::cout<<"GO!!!\n";

    for(int i=0; i<500; i++)
        {
            PostMessage(hCurrentWindow,WM_KEYDOWN,0x45,0x45);
            PostMessage(hCurrentWindow,WM_KEYUP,0x45,0x45);
        }

    std::cout<<GetLastError()<<std::endl;

    system("Pause");
    return 0;
}

Nie ma żadnej różnicy w działaniu.

AKTUALIZUJ po komentarzu Roba Kennedy'ego i odpowiedzi Hansa Passanta

#include <Windows.h>
#include <iostream>

int main()
{
    HWND hCurrentWindow;
    DWORD procID;
    GUITHREADINFO currentWindowGuiThreadInfo;

    Sleep(5000);

    hCurrentWindow = GetForegroundWindow();

    if(!hCurrentWindow)
        std::cout<<"Failed get main the window handle\n";

    GetWindowThreadProcessId(hCurrentWindow,&procID); 
    GetGUIThreadInfo(procID,&currentWindowGuiThreadInfo);               
    hCurrentWindow = currentWindowGuiThreadInfo.hwndFocus;

    if(!hCurrentWindow)
        std::cout<<"Failed get the child window handle\n";

    std::cout<<"GO!!!\n";

    for(int i=0; i<500; i++)
        {
            PostMessage(hCurrentWindow,WM_KEYDOWN,0x45, MapVirtualKey(0x45,MAPVK_VK_TO_VSC));
            PostMessage(hCurrentWindow,WM_KEYUP,0x45, MapVirtualKey(0x45,MAPVK_VK_TO_VSC));
        }

    std::cout<<GetLastError()<<std::endl;

    system("Pause");
    return 0;
}

Teraz „przezroczyste” wiadomości są wysyłane za każdym razem. GetLastError () mówi:

ERROR_INVALID_WINDOW_HANDLE

1400 (0x578)

Invalid window handle.

GetLastError () „fixed”

int main()
{
    HWND hCurrentWindow;
    DWORD procID;
    GUITHREADINFO currentWindowGuiThreadInfo;

    Sleep(5000);

    hCurrentWindow = GetForegroundWindow();

    if(!hCurrentWindow)
        std::cout<<"Failed get main the window handle\n";

    GetWindowThreadProcessId(hCurrentWindow,&procID); 
    GetGUIThreadInfo(procID,&currentWindowGuiThreadInfo);               
    hCurrentWindow = currentWindowGuiThreadInfo.hwndFocus;

    if(!hCurrentWindow)
        std::cout<<"Failed get the child window handle\n";

    std::cout<<"GO!!!\n";

    for(int i=0; i<500; i++)
        {

            if(!PostMessage(hCurrentWindow,WM_KEYDOWN,0x45, MapVirtualKey(0x45,MAPVK_VK_TO_VSC))) std::cout<<GetLastError()<<std::endl;
            if(!PostMessage(hCurrentWindow,WM_KEYUP,0x45, MapVirtualKey(0x45,MAPVK_VK_TO_VSC)))   std::cout<<GetLastError()<<std::endl;
        }



    system("Pause");
    return 0;
}

... wyjścia1400 tysiąc razy. Poza tym nic się nie zmieniło.

questionAnswers(4)

yourAnswerToTheQuestion