IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Récupérer le canvas de n'importe quelle fenêtre


Sujet :

Delphi

  1. #1
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut Récupérer le canvas de n'importe quelle fenêtre
    Salut!

    Est-il possible de récupérer le dessin contenu dans une fenêtre sans que celle-ci soit obligatoirement au 1er plan ?
    Si oui, comment ?

    Merci d'avance
    De retour parmis vous après 10 ans!!

  2. #2
    Membre expert
    Avatar de TicTacToe
    Inscrit en
    Septembre 2005
    Messages
    1 940
    Détails du profil
    Informations personnelles :
    Âge : 51

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 940
    Points : 3 575
    Points
    3 575
    Par défaut
    C'est juste une piste
    Tu peux chercher du coté de GetDC( HandleHote)
    pour obtenir le handle de la zone de dessin,
    et après... je sais pas, mais je pense que c'est une piste
    Section Delphi
    La mine d'or: La FAQ, les Sources

    Un développement compliqué paraitra simple pour l'utilisateur, frustrant non ?
    Notre revanche ? l'inverse est aussi vrai ;-)

  3. #3
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    et après... Tu affectes ce DC à la propriété Handle d'un TCanvas créé manuellement. Ne pas oublier d'appeler ReleaseDC lorsque ton travail est terminé.
    sjrd, ancien rédacteur/modérateur Delphi.
    Auteur de Scala.js, le compilateur de Scala vers JavaScript, et directeur technique du Scala Center à l'EPFL.
    Découvrez Mes tutoriels.

  4. #4
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Merci pour vos réponses.
    Le problème est que j'obtiens une "capture" du bureau de la fenêtre, c'est-à- dire que si une autre fenêtre la superpose, je me retrouve avec une image contenant les 2 fenêtres. Je recherche le moyen de récupérer l'image d'une fenêtre dont je connais le handle même si celle-ci est cachée par une autre, j'espère simplement que cela soit possible au moins.
    Merci
    De retour parmis vous après 10 ans!!

  5. #5
    Expert éminent sénior
    Avatar de Cl@udius
    Homme Profil pro
    Développeur Web
    Inscrit en
    Février 2006
    Messages
    4 878
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Février 2006
    Messages : 4 878
    Points : 10 008
    Points
    10 008
    Par défaut
    Bonjour,

    Je pense que dans ce cas il est préférable d'utiliser GetDCEx qu'il permet d'éviter les problèmes de clipping sur la zone client.

    A lire chez MSDN:
    http://msdn.microsoft.com/library/de...vcons_76wo.asp

    @+ Claudius

  6. #6
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Merci Claudius40 ! Ça semble être le fonction recherchée excepté que je n'arrive pas à l'utiliser comme il faudrait. J'ai essayé plusieurs paramètres, rien n'y fait...
    De retour parmis vous après 10 ans!!

  7. #7
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Est-ce ce que tu cherches ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    Interface
     
    //Copier la zone cliente d'une fenêtre dans un bitmap (screenshot de la zone cliente)
    procedure CopyClientRectToBitmap(WindowHandle:HWND;ABitmap:TBitmap);
     
    //Copier l'image d'une fenêtre dans un bitmap (screenshot de toute la fenètre)
    procedure CopyWindowRectToBitmap(WindowHandle:HWND;ABitmap:TBitmap);
     
    //L'espace du bureau
    procedure ScreenShotDesktop(ABitmap:TBitmap;AScreen:TScreen);
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
     
     
    procedure CopyClientRectToBitmap(WindowHandle:HWND;ABitmap:TBitmap);
    var WindowDeviceContext: HDC;
        WindowRect:TRect;
    begin
      //La zone cliente de la fenêtre
      GetClientRect(WindowHandle,WindowRect);
     
      //Obtient un contexte de dessin sur la zone cliente de la fenètre
      WindowDeviceContext:=GetDC(WindowHandle);
     
      try
        with ABitmap do
        begin
          with WindowRect do
          begin
            Width:=Right-Left; // Ajustement de la taille de l'image
            Height:=Bottom-top; // pour qu'elle corresponde à celle du bureau
          end;
     
          // Copie dans l'image bitmap
          BitBlt(Canvas.Handle, 0, 0, Width, Height,
            WindowDeviceContext, 0, 0, SRCCOPY);
        end;
      finally
        ReleaseDC(WindowHandle, WindowDeviceContext); // Libération du contexte de périphérique
      end;
    end;
     
    procedure CopyWindowRectToBitmap(WindowHandle:HWND;ABitmap:TBitmap);
    var WindowDeviceContext: HDC;
        WindowRect:TRect;
    begin
      //Obtenir les limites de la fenètre (bordure+barre de titre comprises)
      GetWindowRect(WindowHandle,WindowRect);
     
      //Obtient un contexte de dessin sur la fenètre
      WindowDeviceContext:=GetWindowDC(WindowHandle);
     
      try
        with ABitmap do
        begin
          with WindowRect do
          begin
            Width:=Right-Left; // Ajustement de la taille de l'image
            Height:=Bottom-top; // pour qu'elle corresponde à celle du bureau
          end;
     
          // Copie dans l'image bitmap
          BitBlt(Canvas.Handle, 0, 0, Width, Height,
            WindowDeviceContext, 0, 0, SRCCOPY);
        end;
      finally
        ReleaseDC(WindowHandle, WindowDeviceContext); // Libération du contexte de périphérique
      end;
    end;
     
    procedure ScreenShotDesktop(ABitmap:TBitmap;AScreen:TScreen);
    var
      desktopHandle: THandle;
      deviceContext: HDC;
    begin
      desktopHandle:= GetDesktopWindow; // Récupération du handle du bureau
      deviceContext:= GetDC(desktopHandle); // Récupération du contexte de périphérique du bureau
      try
        Abitmap.Width:= AScreen.Width; // Ajustement de la taille de l'image
        Abitmap.Height:= AScreen.Height; // pour qu'elle corresponde à celle du bureau
     
        BitBlt(Abitmap.Canvas.Handle, 0, 0, Abitmap.Width, Abitmap.Height,
          deviceContext, 0, 0, SRCCOPY); // Copie du bureau dans l'image bitmap
     
      finally
        ReleaseDC(desktopHandle, deviceContext); // Libération du contexte de périphérique
      end;
    end;
    Bidouilleuse Delphi

  8. #8
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Merci beaucoups pour ce code !

    J'ai réalisé un programme qui utilise une image PNG pour dessiner la fenêtre grâce à la fonction UpdateLayeredWindow.
    Je n'arrive pas à récupérer la capture, par exemple avec le programme d'une loupe... En résumé, mon programme n'est pas capturable apparemment. Auriez-vous une idée pour résoudre ce problème ?

    http://sub0.developpez.com/delphi/pngform2.zip
    http://jca.developpez.com/loupe.php

    Merci pour vos conseils.
    De retour parmis vous après 10 ans!!

  9. #9
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Le code ci-dessous fonctionne bien excepté qu'il capture aussi les fenêtres qui sont superposées... Pourtant, j'utilise la fonction CopyWindowRectToBitmap qui a été donnée plus haut :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    procedure TForm1.Timer1Timer(Sender: TObject);
    var bmp : TBitmap;
    begin
      bmp:=TBitmap.Create;
      bmp.Width := form1.Width;
      bmp.Height := form1.Height;
      bmp.PixelFormat := pf32bit;
      CopyWindowRectToBitmap(windowFromPoint(mouse.CursorPos), bmp);
      form1.Canvas.Draw(0,0,bmp);
      bmp.Free;
    end;
    Merci de votre aide!
    De retour parmis vous après 10 ans!!

  10. #10
    Membre expert
    Avatar de LadyWasky
    Femme Profil pro
    Inscrit en
    Juin 2004
    Messages
    2 932
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 53
    Localisation : France, Hauts de Seine (Île de France)

    Informations forums :
    Inscription : Juin 2004
    Messages : 2 932
    Points : 3 565
    Points
    3 565
    Par défaut
    Je me suis permis de "retravailler" ton projet, la capture d'écran fonctionne maintenant.

    La technique n'est pas aussi sophistiquée que la tienne mais elle fonctionne pour tout les Windows depuis Windows95
    Fichiers attachés Fichiers attachés
    Bidouilleuse Delphi

  11. #11
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    J'aurais bien aimer utiliser ta méthode, mais lorsqu'on éxécute plusieurs fois ton programme et qu'on déplace une fenêtre sur une autre, la partie "transparence" devient opaque...
    Peut-être aurais-tu une solution pour ce problème.
    De retour parmis vous après 10 ans!!

  12. #12
    Expert confirmé
    Avatar de Sub0
    Homme Profil pro
    Développeur Web
    Inscrit en
    Décembre 2002
    Messages
    3 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51

    Informations professionnelles :
    Activité : Développeur Web

    Informations forums :
    Inscription : Décembre 2002
    Messages : 3 573
    Points : 4 219
    Points
    4 219
    Par défaut
    Salut!

    Je suis enfin arrivé à qq chose en m'inspirant de ton code, seulement ça saccade... En tous les cas, la loupe fonctionne cette fois et la fenêtre est bien restaurer si une autre fenêtre modifie le canvas :

    http://sub0.developpez.com/delphi/alphaform4.zip

    J'espère trouver le moyen d'accélerer le traitement tout en conservant le fonctionnement.
    Merci
    De retour parmis vous après 10 ans!!

  13. #13
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Je crois bien que tu devrais utiliser
    BitBlt avec le parametre CAPTUREBLT avec ton programme de loupe....

    Citation Envoyé par MSDN
    Windows 98/Me, Windows 2000/XP: Includes any windows that are layered on top of your window in the resulting image. By default, the image only contains your window. Note that this generally cannot be used for printing device contexts.
    je crois même qu'il nous faudra tous changer nos facons de faire
    des captures d'écran de cette facon ...
    puisque la semi-transparence deviendra à la mode...
    c'est notre désigner Bill et l'arrivé de vista qui nous y forcera un peu...
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

  14. #14
    Membre éprouvé

    Profil pro
    Inscrit en
    Mai 2003
    Messages
    582
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Mai 2003
    Messages : 582
    Points : 915
    Points
    915
    Par défaut
    Et encore plus simple...suivant le post précédent...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    const
    CAPTUREBLT = $40000000;
    procedure TForm1.TCaptureScreen(Sender: TObject);
    begin
      ScreenCanvas := TCanvas.create;
      ScreenCanvas.Handle := getDC(0);  // résupération du canvas de l'écran
      Screen_bmp:=TBitmap.Create;
      Screen_bmp.Width:=screen.Width;
      Screen_bmp.Height:=screen.Height;
    Screen_bmp.Canvas.CopyMode:=Screen_bmp.Canvas.CopyMode+CAPTUREBLT;
      
      Screen_bmp.Canvas.CopyRect(Rect(0, 0, screen.Width, screen.Height),
                                 ScreenCanvas,Rect(0, 0, screen.Width, screen.Height));
    end;
    Avec ce code, je capture l'écran...
    mais aussi ton application.
    Comment dupliquer un disque...ça vous intéresse?
    Tutoriel et code source delphi ici

Discussions similaires

  1. Réponses: 0
    Dernier message: 05/09/2014, 12h54
  2. Récupérer un message dans n'importe quelle langue
    Par macumba dans le forum Grails
    Réponses: 0
    Dernier message: 02/08/2011, 22h46
  3. Réponses: 12
    Dernier message: 03/12/2010, 15h13
  4. Réponses: 0
    Dernier message: 29/08/2008, 14h45
  5. Imprimer un canvas sous n'importe quelle imprimante
    Par Bily.sdi dans le forum C++Builder
    Réponses: 3
    Dernier message: 13/12/2005, 13h02

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo