J’ai injecté mon dll dans le processus. Comment puis-je obtenir le handle de la fenêtre principale de l’application hôte?
L’application hôte peut avoir plusieurs «fenêtres principales». Pour les détecter, vous pourriez
GetCurrentProcessId
pour obtenir le PID du processus en cours EnumWindows
pour parcourir toutes les fenêtres de niveau supérieur du bureau GetWindowThreadProcessId
pour obtenir le PID du processus qui a créé la fenêtre. Cela vous donne une liste des fenêtres de niveau supérieur créées par le processus dans lequel vous avez injecté votre DLL. Toutefois, veuillez noter que cette approche peut générer des fenêtres détruites au moment où vous traitez la liste de fenêtres créée. Par conséquent, lorsque vous faites quelque chose avec Windows, veillez à utiliser la fonction IsWindow
pour vous assurer que la fenêtre disponible est toujours valide (ceci est toujours sujet aux conditions de IsWindow
car la fenêtre peut devenir invalide entre votre appel à IsWindow
et l’access à la fenêtre). , mais la fenêtre de temps est beaucoup plus petite).
Voici une fonction C ++ implémentant cet algorithme. Il implémente une fonction getToplevelWindows
qui produit un std::vector
contenant les descripteurs de toutes les fenêtres de niveau supérieur du processus en cours.
struct EnumWindowsCallbackArgs { EnumWindowsCallbackArgs( DWORD p ) : pid( p ) { } const DWORD pid; std::vector handles; }; static BOOL CALLBACK EnumWindowsCallback( HWND hnd, LPARAM lParam ) { EnumWindowsCallbackArgs *args = (EnumWindowsCallbackArgs *)lParam; DWORD windowPID; (void)::GetWindowThreadProcessId( hnd, &windowPID ); if ( windowPID == args->pid ) { args->handles.push_back( hnd ); } return TRUE; } std::vector getToplevelWindows() { EnumWindowsCallbackArgs args( ::GetCurrentProcessId() ); if ( ::EnumWindows( &EnumWindowsCallback, (LPARAM) &args ) == FALSE ) { // XXX Log error here return std::vector (); } return args.handles; }
MISE À JOUR: Ces jours-ci (environ quatre ans après avoir donné la réponse), je considérerais également parcourir la liste des threads de l’application, puis utiliser EnumThreadWindows
sur chaque thread. J’ai remarqué que cela est beaucoup plus rapide dans de nombreux cas.