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 :

Comment faire une copie de la FENETRE ACTIVE dans une bitmap


Sujet :

Delphi

  1. #1
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    254
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 254
    Par défaut Comment faire une copie de la FENETRE ACTIVE dans une bitmap
    J'aimerais savoir comment faire une copie de la FENÊTRE ACTIVE dans une bitmap SANS UTILISER LE PRESSE-PAPIER !. J'ai lu l'article de Pierre Castelain 'Commment faire une copie d'écran et l'enregistrer dans un fichier' et j'aimerais le modifier pour faire une copie de la fenêtre active. Voici son code pour sauver l'écran au complet. Je pense qu'il n'y a pas beaucoup de modifications à faire.

    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
    procedure ScreenShot(const Filename: string);
    var
      bitmap: TBitmap;
      desktopHandle: THandle;
      deviceContext: HDC;
    begin
      {----------------------------------------------------------------------} 
      Attention il ne suffit pas de remplacer GetDesktopWindow par
      GetActiveWindow, il nous faut les dimensions de la fenêtre pour faire
      la copie dans le bitmap
      {----------------------------------------------------------------------} 
     
      desktopHandle:= GetDesktopWindow;   // Récupération du handle du bureau
      deviceContext:= GetDC(desktopHandle); // Récupération du contexte de
                                                                 périphérique du bureau
     
      bitmap:= TBitmap.Create; // Création d'une image bitmap
      try
        bitmap.Width:= Screen.Width; // Ajustement de la taille de l'image
        bitmap.Height:= Screen.Height; // pour qu'elle corresponde à celle du bureau
     
        BitBlt(bitmap.Canvas.Handle, 0, 0, bitmap.Width, bitmap.Height,
          deviceContext, 0, 0, SRCCOPY); // Copie du bureau dans l'image bitmap
     
        bitmap.SaveToFile(Filename); // Sauvegarde de l'image dans un fichier bmp
      finally
        bitmap.Free; // Libération de l'image
        ReleaseDC(desktopHandle, deviceContext); // Libération du contexte de périphérique
      end;
    end;
    Merci, Pierre-Yves Belleau

  2. #2
    Rédacteur
    Avatar de evarisnea
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Juin 2005
    Messages
    1 957
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : Transports

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 957
    Par défaut

    a première vue, je ferais ceci :
    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
    {--------------------------------------------------}
    procedure ScreenShot(const Filename: string);
    var
    bitmap: TBitmap;
    windowHandle: THandle;
    deviceContext: HDC;
    begin
    {----------------------------------------------------------------------}
    Attention il ne suffit pas de remplacer GetDesktopWindow par
    GetActiveWindow, il nous faut les dimensions de la fenêtre pour faire
    la copie dans le bitmap
    {----------------------------------------------------------------------}
    
    windowHandle:= GetDesktopWindow; // Récupération du handle du la fenêtre
    deviceContext:= GetDC(windowHandle); // Récupération du contexte de
    périphérique de la fenêtre
    
    //code pour récupérer les dimensions de la fenêtre dont on a le Handle
    //dsl, je ne sais plus trop quelle est l'API à utiliser
    //essaie de jetter un coup d'oeil du coté de GetWindowLong
    
    bitmap:= TBitmap.Create; // Création d'une image bitmap
    try
    //à remplacer
    bitmap.Width:= Screen.Width; // Ajustement de la taille de l'image
    //à remplacer
    bitmap.Height:= Screen.Height; // pour qu'elle corresponde à celle du bureau
    
    BitBlt(bitmap.Canvas.Handle, 0, 0, bitmap.Width, bitmap.Height,
    deviceContext, 0, 0, SRCCOPY); // Copie du bureau dans l'image bitmap
    //pas besoin de sauvegarder l'image
    //bitmap.SaveToFile(Filename); // Sauvegarde de l'image dans un fichier bmp
    finally
    bitmap.Free; // Libération de l'image
    ReleaseDC(desktopHandle, deviceContext); // Libération du contexte de périphérique
    end;
    end;
    {--------------------------------------------------}

  3. #3
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 294
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 294
    Par défaut
    Yep !
    C'est pas GetWindowLong, c'est GetWindowRect, je pense, et j'ai essayé comme ça :
    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
    procedure ScreenShot;
    var
      bitmap: TBitmap;
      windowHandle: THandle;
      deviceContext: HDC;
      rect : TRect;
    begin
      windowHandle  := GetActiveWindow; // Récupération du handle du la fenêtre
      deviceContext := GetDC(windowHandle); // Récupération du contexte de périphérique de la fenêtre
     
      bitmap:= TBitmap.Create; // Création d'une image bitmap
      try
        GetWindowRect(windowHandle, rect);
        bitmap.Width := rect.Right - rect.Left; // Ajustement de la taille de l'image
        bitmap.Height:= rect.Bottom - rect.Top; // pour qu'elle corresponde à celle de la fenêtre
        BitBlt(bitmap.Canvas.Handle, 0, 0, bitmap.Width, bitmap.Height,
          deviceContext, 0, 0, SRCCOPY); // Copie de la fenêtre dans l'image bitmap
        bitmap.SaveToFile('c:\img.bmp'); // Sauvegarde de l'image dans un fichier bmp
      finally
        bitmap.Free; // Libération de l'image
        ReleaseDC(windowHandle, deviceContext); // Libération du contexte de périphérique
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    begin
      ScreenShot;
    end;
    Il y a un souci, c'est qu'on dirait que ça calcule la zone client seulement, sans inclure la barre de titre ! La preuve :


    Si qqun a une meilleure idée, ch'suis intéressé aussi.
    --
    jp

  4. #4
    Expert confirmé
    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 : 63
    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
    Par défaut
    Salut,

    J'ai fait ceci et ça marche. Cependant je ne vois pas pourquoi l'exemple de Jipété ne fonctionne pas puisque qu'on fait la même chose.

    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
     
    procedure CopyWindowToBitmap(AHWnd: HWND; ABitmap: TBitmap);
    var
      WindowDC: HDC;
      WindowRect: TRect;
    begin
      // Dimensions de la fenêtre
      GetWindowRect(AHWnd, WindowRect);
      // Contexte de dessin
      WindowDC := GetWindowDC(AHWnd);
      // Effectuer une copie dans le bitmap
      try
        with ABitmap do
        begin
          with WindowRect do
          begin
            Width := Right - Left + 1;
            Height := Bottom - Top + 1;
          end;
          BitBlt(Canvas.Handle, 0, 0, Width, Height,
                 WindowDC, 0, 0, SRCCOPY);
        end;
      finally
        ReleaseDC(AHWnd, WindowDC); // Libération du DC
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
      MyBitmap: TBitmap;
    begin
      MyBitmap := TBitmap.Create;
      try
        CopyWindowToBitmap(GetActiveWindow, MyBitmap);
        MyBitmap.SaveToFile('c:\img.bmp'); // Sauvegarde de l'image
      finally
        MyBitmap.Free;
      end;
    end;
    @+

  5. #5
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 294
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 294
    Par défaut
    @Claudius40:
    Si si il y a une énorme différence entre nos 2 codes :
    je faisais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      deviceContext := GetDC(windowHandle); // Récupération du contexte de périphérique de la fenêtre
    tel que repompé du code précédement posté, alors que toi tu fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      deviceContext := GetWindowDC(windowHandle); // Contexte de dessin
    Ça change tout, ce "Window" au milieu.
    Désolé d'avoir posté un truc foiré (suis pas spécialiste de ces choses) mais ça nous aura permis à tous de récupérer un code qui fonctionne impec !

    Et pour avoir une image parfaite (testé il y a 5 secondes !),
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          with WindowRect do
          begin
            Width := Right - Left;
            Height := Bottom - Top;
          end;
    au lieu de
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          with WindowRect do
          begin
            Width := Right - Left + 1;
            Height := Bottom - Top + 1;
          end;
    Et là, que du bonheur !

    Merci Claudius40, et bon dimanche !
    --
    jp

  6. #6
    Expert confirmé
    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 : 63
    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
    Par défaut
    A vouiii, je n'avais pas vu le GetDC !

    Salut @+

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    254
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 254
    Par défaut
    J'ai contacté Zarko Gajic du site Delphi.About.com et je lui ai suggéré de faire un article la-dessus. Voici sa réponse

    http://delphi.about.com/od/adptips2006/qt/captureactive.htm

    et son code, remarquer qu'il utilise GetForegroundWindow.
    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
    procedure ScreenShot(activeWindow: bool; destBitmap : TBitmap) ;
    var
       w,h : integer;
       DC : HDC;
       hWin : Cardinal;
       r : TRect;
    begin
       if activeWindow then
       begin
         hWin := GetForegroundWindow;
         dc := GetWindowDC(hWin) ;
         GetWindowRect(hWin,r) ;
         w := r.Right - r.Left;
         h := r.Bottom - r.Top;
       end
       else
       begin
         hWin := GetDesktopWindow;
         dc := GetDC(hWin) ;
         w := GetDeviceCaps (DC, HORZRES) ;
         h := GetDeviceCaps (DC, VERTRES) ;
       end;
     
       try
        destBitmap.Width := w;
        destBitmap.Height := h;
        BitBlt(destBitmap.Canvas.Handle,
               0,
               0,
               destBitmap.Width,
               destBitmap.Height,
               DC,
               0,
               0,
               SRCCOPY) ;
       finally
        ReleaseDC(hWin, DC) ;
       end;
    end;

  8. #8
    Membre chevronné
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Par défaut
    question déjà traitée dans le forum ou j'ai eu une réponse positive de SOFIANE44 LE 25 05 2006

    à plus!

  9. #9
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 294
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 294
    Par défaut
    Salut !

    @Pierre-Yves Belleau:
    (...) je lui ai demandé de me faire un article la-dessus.
    Euh, c'est possible, ça ?
    Moi aussi je peux lui écrire pour lui demander un article (tiens, au hasard, sur la gestion de cette saleté de propriété PageSize d'une ScrollBar--me rends fou, ça...) ?
    Tout le monde peut lui écrire

    Ou tu le connais personnellement, rassure-moi.
    --
    jp, perplexe

  10. #10
    Membre éclairé
    Profil pro
    Inscrit en
    Août 2006
    Messages
    254
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 254
    Par défaut
    Salut Jipété,

    Le mot 'demandé' était abusif j'aurais du utiliser 'suggéré', j'ai fait la modification dans l'article. Je ne le connais pas personnellement mais j'ai vu sur le site dans un de ses articles un bouton 'DISCUSS' pour discuter de son article et aussi j'ai lu a quelque part qu'il acceptait des suggestions pour ses articles alors j'ai fait une premiere demande pour un problème de lecture de CD et il a écrit un article pour ca. J'ai fait d'autres demandes mais il ne répond pas toujours. Il a répondu pour la fenêtre active dans un bitmap. J'ai remarqué que ses solutions sont souvent assez expéditives, ca manque souvent de finition d'autres fois c'est très bien. Il doit avoir beaucoup de suggestions alors c'est normal de ne pas toujours avoir de réponse. Essaye toi ca ne coute rien.

    Bye.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comment faire pour entrer plus de 255 champs dans une table.
    Par adelsunwind dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 16/03/2009, 19h35
  2. Réponses: 1
    Dernier message: 20/09/2007, 18h59
  3. Réponses: 2
    Dernier message: 06/02/2007, 15h05
  4. Comment faire référence à un champ d'un etat dans une requete?
    Par polianita dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 19/06/2006, 15h26
  5. Comment faire référence à un champ d'un etat dans une requete?
    Par polianita dans le forum Autres Logiciels
    Réponses: 1
    Dernier message: 16/06/2006, 17h46

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