2009-04-28 6 views
3

Le code a travaillé tout le long. D'une manière ou d'une autre, je parviens à faire en sorte que Visual C++ Express n'atteigne pas le point de rupture de la déclaration de retour finale et semble fonctionner à jamais.Comment faire pour arrêter EnumWindows exécutant infiniment win32

Dans l'exemple de code ci-dessous, EnumWindows énumère à l'infini. Comment peut-on l'arrêter après que toutes les fenêtres ont été énumérées.

#include <Windows.h> 

BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam) { 
    TCHAR buff[255]; 

    if (IsWindowVisible(hWnd)) { 
     GetWindowText(hWnd, (LPWSTR) buff, 254); 
     printf("%S\n", buff); 
    } 
    return TRUE; 
} 

int _tmain(int argc, _TCHAR* argv[]) { 
    EnumWindows(EnumWindowsProc, 0); 
    return 0; 
} 
+0

Votre projet utilise-t-il UNICODE? Aussi, quelle version de la plate-forme/VS utilisez-vous? Aussi pourquoi utilisez-vous '% S'? – dirkgently

+0

Plate-forme XP SP2. GetWindowText semble renvoyer une chaîne large. Utilisé% S pour imprimer une chaîne large. – s5804

+0

Mais qu'est-ce qui est exactement imprimé ??? –

Répondre

7

Votre code fonctionne pour moi, une fois que je l'ai enlevé les trucs grand caractère et ajouté #include <stdio.h> pour obtenir la déclaration printf(). Quelle sortie produit-il sur votre système?

Le code qui fonctionne pour moi:

#include <windows.h> 
#include <stdio.h> 

BOOL CALLBACK EnumWindowsProc(HWND hWnd, LPARAM lParam) { 
    char buff[255]; 

    if (IsWindowVisible(hWnd)) { 
     GetWindowText(hWnd, (LPSTR) buff, 254); 
     printf("%s\n", buff); 
    } 
    return TRUE; 
} 

int main() { 
    EnumWindows(EnumWindowsProc, 0); 
    return 0; 
} 
+4

La vérification avec IsWindowVisible fonctionne car certaines fenêtres invisibles peuvent bloquer l'appel à GetWindowText. – pcunite

+0

@pcunite La visibilité d'une fenêtre n'affecte pas 'GetWindowText()'. Et en fait, si une fenêtre appartient à un autre processus, ['GetWindowText()' ** ne peut pas se bloquer] (https://blogs.msdn.microsoft.com/oldnewthing/20030821-00/?p=42833), intentionnellement. La seule façon de le bloquer est si la fenêtre appartient à votre propre processus et que la file d'attente des messages de la fenêtre n'est pas traitée. Ce serait un bug dans votre propre code. –

1

De la documentation:

EnumWindows continue jusqu'à ce que la dernière fenêtre de niveau supérieur est dénombrée ou la fonction de rappel retourne FALSE.

Pour continuer l'énumération, la fonction de rappel doit retourner TRUE; pour arrêter l'énumération, elle doit retourner FALSE.

+0

Il s'arrêtera quand il atteindra la dernière fenêtre de haut niveau, quelle que soit la valeur renvoyée. –

1

hmm, je ne comprends pas pourquoi il le ferait. Je l'ai couru et cela a fonctionné très bien. il a affiché toutes les fenêtres que j'ai, puis s'est arrêté. enumWindows s'arrête lorsque l'enumWindowsProc renvoie false (vous l'avez codé pour toujours renvoyer true) ou lorsqu'il ne contient plus de fenêtres de niveau supérieur à énumérer. -don

3

EnumWindowsProc ne devrait jamais fonctionner indéfiniment.

Il devrait fonctionner jusqu'à ce que:

  • retourne votre rappel FAUX
  • Il n'y a pas plus haut des fenêtres de niveau pour énumèrent

Je pense qu'il semble être en cours d'exécution à l'infini pour vous à cause de corruption de mémoire ou une violation d'accès à la mémoire.

Votre printf doit utiliser% s et non% S.

BOOL CALLBACK EnumWindowsProc(HWND hWnd, long lParam) { 
    TCHAR buff[255]; 

    if (IsWindowVisible(hWnd)) { 
     GetWindowText(hWnd, (LPWSTR) buff, 254); 
     printf("%s\n", buff);//<--- %s means use TCHAR* which is WCHAR* in your case 
    } 
    return TRUE; 
} 

De même, vous ne devriez pas avoir besoin de lancer votre amélioration en tant que LPWSTR. Si votre buff est en quelque sorte un tampon CHAR, vous devez compiler avec le jeu de caractères Unicode.

Questions connexes