Simuliert drücken einer Taste mit PostMessage funktioniert nur in bestimmten Anwendungen?

Mein Ansatz für dieses problem stellte sich heraus, um korrekt zu sein, nur in mehreren Programmen. Warum es nicht universal?

Funktioniert gut auf:

  • Firefox
  • Visual Studio Text-Editor
  • Leider in einigen Fällen passiert nichts(auch wenn ich Sie in ein Textfeld Bereich vor der Ausführung von meinem Programm):

  • Google Chrome
  • Editor
  • GetLastError gibt immer 0, auch mit SendMessage statt PostMessage.Könnten Sie mein Fehler?

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

    UPDATE nach Maximus sugestion

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

    Gibt es keinen Unterschied in der Wirkung.

    UPDATE nach Rob Kennedy ' s Kommentar und Hans Passant die Antwort

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

    Nun, "transparent" - Nachrichten gesendet werden, jedes mal. GetLastError() sagt:

    ERROR_INVALID_WINDOW_HANDLE

    1400 (0x578)
    
    Invalid window handle.

    GetLastError() "behoben"

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

    ...Ausgänge 1400 tausend mal. Außer diesem, hat sich nichts geändert.

    Maximus schlug Sie den scan-code in der lParam argument. Sie haben das nicht getan, obwohl. Ihre zweite code-block legt die Wiederholungen. Bitte finden Sie im MSDN nach, was alle bits des lParam bedeuten.
    Haben Sie in Betracht gezogen, nur mit SendInput statt? Das ist, was es ist.
    PostMessage wird nie in der Lage sein zu simulieren input perfekt, denn es gibt andere Staat, der PostMessage nicht aktualisiert (wie Umschalttaste Staaten).
    Danke, ich habe noch nie gehört, über diese Funktion vor und ich fand es nützlich. Aber meine Frage ist noch offen.
    Klingt für mich wie eine Antwort, @Raymond.

    InformationsquelleAutor 0x6B6F77616C74 | 2012-08-09

    Schreibe einen Kommentar