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 régulier
    Profil pro
    Inscrit en
    Août 2006
    Messages
    249
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Août 2006
    Messages : 249
    Points : 106
    Points
    106
    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
    Points : 4 384
    Points
    4 384
    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 éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 833
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 833
    Points : 15 259
    Points
    15 259
    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
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    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
    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 éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 833
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 833
    Points : 15 259
    Points
    15 259
    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
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  6. #6
    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
    A vouiii, je n'avais pas vu le GetDC !

    Salut @+

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

    Informations forums :
    Inscription : Août 2006
    Messages : 249
    Points : 106
    Points
    106
    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 averti
    Inscrit en
    Octobre 2005
    Messages
    338
    Détails du profil
    Informations forums :
    Inscription : Octobre 2005
    Messages : 338
    Points : 383
    Points
    383
    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 éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 833
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 833
    Points : 15 259
    Points
    15 259
    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
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

    Informations forums :
    Inscription : Août 2006
    Messages : 249
    Points : 106
    Points
    106
    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