11
votes

C ++ - Comment saisir la capture d'écran, à l'exception de certaines fenêtres

Situation : J'ai un logiciel qui effectue un partage d'écran sur Internet, où un utilisateur agit en tant que présentateur et que d'autres utilisateurs agissent en tant que téléspectateurs / participants.

Outre la présentation Windows, le présentateur dispose également d'un ensemble de fenêtres non partagées qui apparaissent à l'écran (une barre de boutons pour commencer partager / arrêter de partage / etc., une fenêtre Skype, etc.).

Le présentateur peut configurer à partir de la configuration du logiciel de partage d'écran pour rendre ces fenêtres non partagées invisibles (c'est-à-dire qu'ils n'apparaîtront pas dans le partage de l'écran envoyé aux participants, mais le contenu de la fenêtre derrière eux apparaîtra. dans la capture d'écran).

Les captures d'écran sont envoyées à environ 10 images par seconde, ou plus rapides.

question : Comment puis-je capturer par programme l'écran, à l'exception de ces fenêtres sans partage-windows?

notes :

  • En raison de la valeur supérieure des cadres - par seconde, je ne peux pas minimiser / maximiser / définir Alpha pour ces fenêtres, car les fenêtres scintillent. L'application est écrite dans Win32 C ++.
  • J'utiliserais des fenêtres en couches, mais en raison de la fonction de composition de bureau Windows 7, il n'est pas utilisable hors de la zone (et sous Windows 8, vous ne pouvez plus utiliser DWMenablecomposition pour désactiver temporairement et programmatiquement la composition)
  • Je pourrais utiliser l'approche de la fenêtre en couches pour Windows XP / 2000/7, etc., et une approche différente de Windows 8 (s'il y en a une), bien que je préférerais un processus unique qui fonctionne sur tous les systèmes
  • Je pourrais également essayer de "composer" les captures d'écran en capturant des images individuelles (du bureau, les fenêtres qui doivent être capturées) et en utilisant leur index z pour créer l'image finale, mais en raison des cadres requis -Sublique secondaire, ce processus serait trop lent.

12 commentaires

Je sais que ma réunion de MSFT est un bon exemple, même si vous ne savez pas comment est-ce fait.


Merci - il y a des produits similaires qui font cela (JoinMe ou GTM), je vais également essayer d'enquêter sur cela, mais j'espérais une réponse plus rapide.


La capture d'écran capture normalement la "zone d'écran au-dessus de la fenêtre" plutôt que le contenu dessiné de la fenêtre elle-même. Vous pouvez essayer de capturer toutes les fenêtres de niveau supérieur visibles et de les recomposer.


En fait, vous auriez toujours besoin de dessiner les fenêtres partiellement visibles, pas seulement des fenêtres de niveau supérieur. En outre, les fenêtres non partagées pourraient également être de haut niveau.


@Deanna Modifier En réalité, vous devez toujours dessiner les fenêtres partiellement visibles, pas seulement les fenêtres de niveau supérieur. En outre, les fenêtres non partagées pourraient également être de niveau de haut niveau. Je devrais donc avoir le contenu des fenêtres sous ces fenêtres non partagées.


J'ai oublié de mentionner un point de départ pour cette fonctionnalité: Link Le code de ce lien fonctionne bien pour les fenêtres en couches, mais pas par défaut dans Windows 7 (vous pouvez utiliser Dwmenablecomposition pour contourner par programme ce" inconvénient ", mais dans Windows 8, la méthode DWMenablecomposition est obsolète)


@SucatamiHNHNHNEA: Oui, je suggérais d'obtenir chaque fenêtre (à l'exclusion des non partagées) et de la recomposer dans une image finale au lieu de la capture d'écran complète.


Est-ce que quelqu'un ici sait comment WebEx ou Gootometing comme des services gère de faire la même chose?


@Sucatamihnnea Avez-vous eu une solution? Je cherche également répondre à la même question.


@Vishnu non, pas encore de solutions (au moins aucune nécessité de composer l'image, qui est trop lente pour la diffusion en temps réel). En regardant dans le API de grossissement < / a>, mais cela a des descentes aussi bien


Si vous cherchez toujours à vous référer à Media Ce projet contient une classe appelée ScreenCapture Dans cette classe, vous pouvez définir des coordonnées de l'écran de la partie de tous vos écrans que vous souhaitez capturer. Tous vos écrans sont traités comme une image large et tout ce que vous avez à faire est de définir des coordonnées de l'endroit où vous souhaitez commencer et terminer.


Il n'y a toujours pas de solution pour le sujet?


3 Réponses :


-1
votes

Je pense que pour limiter le contenu de capture dans une grande fenêtre sera plus simple. Sinon, vous devrez couper des fenêtres de la capture d'écran.


2 commentaires

Merci, mais puisqu'il s'agit d'une application de partage d'écran (à nouveau, S / W telle que JoinMe et GotOtOtOneting le faisiez-le déjà), il n'est pas convivial (ni d'affaires sage) de forcer l'utilisateur à choisir une seule fenêtre :)


Quoi qu'il en soit, ma question était davantage sur le côté technique - Est-ce que quelqu'un sait que C / C ++ instructions Je peux utiliser pour capturer des écrans dans Windows 7 et / ou 8 et pas Render certaines des fenêtres visibles? Je cherche l'équivalent des fenêtres en couches (voir Lien MSDN pour un exemple d'utilisation des fenêtres en couches)



1
votes

dans Windows Même le bureau est considéré comme une fenêtre et a son propre HWND. Il semble toutefois, pas facilement possible de copier uniquement le "fond d'écran" seul.

Alors je vois fondamentalement deux façons de le faire. 1. Copiez le bureau complet par exemple. BITBLT (GETWINDOWOWDC (GETDESKTOPWINDOW ()), ...)

ou

  1. Utilisez GetWindow et traverser la liste de la fenêtre dans la direction arrière à partir du bureau de bureau à partir de la fenêtre de bureau dont vous pouvez déterminer avec getDesktopwindow (), comme ceci:

    // peinture sur un DC noir hwnd = getdesktopwindow () tandis que (hwnd = getwindow (hwnd, gw_hwndprev)) { // Cette fenêtre n'est-elle pas partagée? Continuez // d'autremut bitblt dans notre DC }

    J'espère que j'ai donné une inspiration :-) Si quelqu'un sait un moyen de copier uniquement le bureau sans ses fenêtres enfants, faites-le moi savoir.


1 commentaires

J'ai essayé cela il y a 4 mois. Cette méthode créera un problème pour capturer certains éléments de bureau tels que le menu Démarrer et la barre d'outils. Celles-ci seront imprimées comme noires sur le CC et il n'y a pas de transparence créée.



0
votes

Vous pouvez utiliser API de loupe.

Il existe une fonction dans l'API de la loupe qui vous permet d'exclure des fenêtres spécifiques de votre fenêtre cible (votre fenêtre avec un grossissement 1x où la loupe rend plus).

Vous pouvez définir cette fenêtre en plein écran et la rendre transparente, puis utiliser la fonction PrintWindow.

La fonction: HTTPS: // docs.microsoft.com/en-us/windows/desktop/api/magnification/nf-magnification-magsetwindowfilterlist

Exemples de projets:

https://www.codeproject.com/articles / 607288 / Capture d'écran - Utilisation-la bibliothèque de grossissement

https://code.msdn.microsoft.com/windowsdesktop / Grossissement-API-SAMPLE-14269FD2


0 commentaires