La simulation de touche avec PostMessage ne fonctionne que dans certaines applications?

Mon approche à ce problème s'est avéré être correct que dans plusieurs programmes. Pourquoi il n'est pas universel?

Fonctionne très bien sur:

  • Firefox
  • Visual Studio Éditeur De Texte
  • Malheureusement, dans certains cas, rien ne se passe(même si je clique dans une zone de texte de la zone avant l'exécution de mon programme):

  • Google Chrome
  • Le bloc-notes
  • GetLastError retourne toujours 0, même en utilisant la fonction SendMessage au lieu de PostMessage.Pourriez-vous en dire mon erreur?

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

    Mise à JOUR après 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;
    }

    Il n'y a pas de différence en effet.

    Mise à JOUR après Rob Kennedy commentaire et Hans Passant la réponse de

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

    Maintenant, "transparent", les messages sont envoyés à chaque fois. GetLastError() dit:

    ERROR_INVALID_WINDOW_HANDLE

    1400 (0x578)
    
    Invalid window handle.

    GetLastError() "fixe"

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

    ...sorties 1400 mille fois. Sauf cela, rien n'a changé.

    Maximus a suggéré d'inclure le code d'analyse dans le lParam argument. Vous n'avez pas fait cela, cependant. Votre deuxième bloc de code définit la répétez le comte. Veuillez vous référer à MSDN pour que tous les bits de lParam veux dire.
    Avez-vous songé seulement à l'aide de SendInput à la place? Qu'est ce que c'est.
    PostMessage ne sera jamais en mesure de simuler l'entrée parfaitement car il y a un autre état que PostMessage ne met pas à jour (comme la touche maj unis).
    Merci, je n'ai jamais entendu parler de cette fonction, et j'ai trouvé utile. Cependant, ma question est toujours ouverte.
    Sonne pour moi comme une réponse, @Raymond.

    OriginalL'auteur 0x6B6F77616C74 | 2012-08-09