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

Langage Delphi Discussion :

Capture "écran" d'une grille


Sujet :

Langage Delphi

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 63
    Points : 40
    Points
    40
    Par défaut Capture "écran" d'une grille
    Bonjour,

    Je cherche à capturer une grille sur une feuille. Cette grille n'est pas entièrement visible, une partie est cachée et peut se dévoiler avec les ascenceurs d'un scrollbox. Comment faire pour avoir la capture de toute la grille en bmp (y compris la partie cachée)

    Pour l'instant mon code est le suivant

    ZColorStringGrid est un compo grille

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    GridImage := TBitmap.Create;
    Try
      GridImage.width := ZColorStringGrid.Canvas.ClipRect.Right - ZColorStringGrid.Canvas.ClipRect.Left;
      GridImage.Height := ZColorStringGrid.Canvas.ClipRect.Bottom - ZColorStringGrid.Canvas.ClipRect.Top;
      GridImage.canvas.CopyRect(GridImage.canvas.ClipRect, ZColorStringGrid.Canvas, ZColorStringGrid.Canvas.ClipRect);
     
      Clipboard.Assign(GridImage);
      finally
        GridImage.Free;
      end;

  2. #2
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    GridImage := TBitmap.Create;
    Try
      GridImage.width := ZColorStringGrid.Canvas.ClipRect.Right - ZColorStringGrid.Canvas.ClipRect.Left;
      GridImage.Height := ZColorStringGrid.Canvas.ClipRect.Bottom - ZColorStringGrid.Canvas.ClipRect.Top;
      GridImage.canvas.CopyRect(ZColorStringGrid.clientrect,canvas,ZColorStringGrid.Clientrect);  
      Clipboard.Assign(GridImage);
      finally
        GridImage.Free;
      end;
    [/QUOTE]


    En ajoutant un simple copyrect, ce n'est pas bon ? (il faut que rien ne soit sur la grille...)


    a+

  3. #3
    Membre chevronné
    Avatar de Archimède
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2005
    Messages
    1 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 644
    Points : 1 975
    Points
    1 975
    Par défaut
    non, apparemment...
    déjà, il faurait copier sur le canvas de la grille et définir un rect qui soit de la dimension du total des colonnes et des lignes et faire peut-être

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    GridImage.canvas.CopyRect(monrect,ZColorStringGrid.canvas,monrect);
    avec monrect dont les dimensions soient: nb de colonnes x largeur et nb de lignes x hauteur de lignes.

    à voir...mais, j'en suis pas convaincu...lol (avec les barres de défilements....

  4. #4
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Par définition un contrôle Windows ne dessine que la partie visible à l'écran !
    La méthode PaintTo du WinControl ne te donnera que ce qu'il y a d'afficher !

    Si tu souhaites imprimer une grille, utilise des composants de reporting que te permettront d'imprimer une grille sur plusieurs pages !

    tu peux encore dessiner toi même la grille, cela reste faisable !
    Si c'est pour imprimer, il faut jouer avec le conversion Pixel/Inch
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  5. #5
    Expert éminent
    Avatar de Lung
    Profil pro
    Analyste-programmeur
    Inscrit en
    Mai 2002
    Messages
    2 668
    Détails du profil
    Informations personnelles :
    Âge : 44
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste-programmeur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 2 668
    Points : 7 008
    Points
    7 008
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    Par définition un contrôle Windows ne dessine que la partie visible à l'écran !
    Il existe des outils comme snagit qui arrivent à faire une capture du contenu entier.
    Comment font-ils ?
    L'urgent est fait, l'impossible est en cours, pour les miracles prévoir un délai. ___ Écrivez dans un français correct !!

    C++Builder 5 - Delphi 6#2 Entreprise - Delphi 2007 Entreprise - Delphi 2010 Architecte - Delphi XE Entreprise - Delphi XE7 Entreprise - Delphi 10 Entreprise - Delphi 10.3.2 Entreprise - Delphi 10.4.2 Entreprise - Delphi 11.1 Entreprise
    OpenGL 2.1 - Oracle 10g - Paradox - Interbase (XE) - PostgreSQL (15.4)

  6. #6
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Ces Outils doivent change le Device Context pour dire au WinControl qu'il peut dépasser de son rectangle de fenêtre !

    C'est un bon sujet de recherche !
    Il faudrait reprendre le code de "TWinControl.PaintTo(DC: HDC; X, Y: Integer)" et d'agrandir la taille du DC au lieu de se limiter au Rectangle de fenêtre
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  7. #7
    Membre confirmé Avatar de JustMe
    Inscrit en
    Juillet 2002
    Messages
    479
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 479
    Points : 593
    Points
    593
    Par défaut
    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
    procedure ControlToBitMap(aControl: TWinControl; var aBitmap: TBitmap;
      Ratio: integer = 2);
    var
      BmpControl             : TBitmap;
      //  BmpResult: TBitmap;
    begin
      try
        BmpControl := TBitmap.Create;
     
        BmpControl.Width := aControl.Width;
        BmpControl.Height := aControl.Height;
     
        BmpControl.Canvas.Lock;
        aControl.PaintTo(BmpControl.Canvas.Handle, 0, 0);
        BmpControl.Canvas.UnLock;
     
        aBitMap.Width := BmpControl.Width div Ratio;
        aBitMap.Height := BmpControl.Height div Ratio;
     
        SetStretchBltMode(aBitMap.Canvas.Handle, HalfTone);
        StretchBlt(aBitMap.Canvas.Handle, 0, 0, aBitMap.Width, aBitMap.Height,
          BmpControl.Canvas.Handle, 0, 0, BmpControl.Width, BmpControl.Height,
          SRCCOPY);
        //aBitMap.Canvas.StretchDraw(Rect(0, 0, aBitMap.Width, aBitMap.Height)
        //  , BmpControl);
      finally
        BmpControl.Free;
      end;
    end;
    <On fait la science avec des faits, comme on fait une maison avec des pierres : mais une accumulation de faits n'est pas plus une science qu'un tas de pierres n'est une maison> **Poincaré**

  8. #8
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Merci JustMe !
    quelques remarques

    1) try doit être avant le Create, sinon Free libère une variable indéterminé si Create plante !
    2) le mot clé var pour aBitmap est inutile, tu ne modifie pas la référence de l'objet mais son contenu, c'est une erreur classique !

    Sinon, ton code imprime la partie visible, comment récupérer une grille qui contient par exemple 1000 lignes donc plus grande que sa zone d'affichage !

    Tu n'as pas lu vraiment la Question !
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  9. #9
    Expert confirmé

    Profil pro
    Leader Technique
    Inscrit en
    Juin 2005
    Messages
    1 756
    Détails du profil
    Informations personnelles :
    Âge : 46
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Leader Technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juin 2005
    Messages : 1 756
    Points : 4 173
    Points
    4 173
    Par défaut
    Citation Envoyé par ShaiLeTroll Voir le message
    1) try doit être avant le Create, sinon Free libère une variable indéterminé si Create plante !
    J'imagine que tu voulais dire après la Create...

    Citation Envoyé par ShaiLeTroll Voir le message
    Sinon, ton code imprime la partie visible, comment récupérer une grille qui contient par exemple 1000 lignes donc plus grande que sa zone d'affichage !
    En fait, la grille va se dessiner sur le HDC qu'on lui fournit en fonction de la zone de clipping du HDC et de son ClientRect.

    Donc je dirais qu'il doit suffir de surcharger GetClientRect sur la grille, en définissant un mode dans lequel la fonction renverrait une surface suffisamment large pour que toute la grille soit visible, puis de dessiner la grille également sur un bitmap (ou un metafile) suffisament grand...

    Dans le cas d'une grille, ça doit se faire assez facilement puisque la grille est entièrement dessinée par la VCL. Pour Windows ce n'est qu'une simple zone rectangulaire.

  10. #10
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 63
    Points : 40
    Points
    40
    Par défaut
    Merci à tous pour vos réponses....


    Pour ma part j'avais penser à faire plusieurs snapshots en faisant défiler l'ascenseur par code et faire une routine qui colle les images prises (c du bidouillage mais bon). Pour les compo de reporting je possède D5 avec les QReport, mais je ne vois pas trop comment procéder. Normalement ils sont orientés db non ? Lequel utilisé, j'en trouve aucun travaillant avec des grilles

    En fait ma grille possède des cellules mergées, des cellules de couleurs avec une police différentes par cellules. J'ai peur qu'un compo reporting ne tienne pas compte des ces aspects grahiques.

    En tout cas encore merci

  11. #11
    Expert éminent sénior
    Avatar de ShaiLeTroll
    Homme Profil pro
    Développeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    13 534
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Seine Saint Denis (Île de France)

    Informations professionnelles :
    Activité : Développeur C++\Delphi
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 13 534
    Points : 25 082
    Points
    25 082
    Par défaut
    Citation Envoyé par Franck SORIANO Voir le message
    J'imagine que tu voulais dire après la Create...
    euh je voulais dire que le Create devait être avant le try, mais en corrigeant le après dans ma phrase, c'est bon ! Merci !

    @The Jos
    Etudie quand même les solutions sur le HDC en refaisant ton propre PaintTo combiné à la surcharge de GetClientRect !

    QReport, tu peux l'utiliser sans DB, tu as un event genre TQuickRep.OnNeedData qui traine et qui permet de générer un liste sans DB

    Cela fonctionne, je l'ai utilisé il y a fort fort longtemps
    Aide via F1 - FAQ - Guide du développeur Delphi devant un problème - Pensez-y !
    Attention Troll Méchant !
    "Quand un homme a faim, mieux vaut lui apprendre à pêcher que de lui donner un poisson" Confucius
    Mieux vaut se taire et paraître idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la médiocrité !

    L'expérience, c'est le nom que chacun donne à ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  12. #12
    Membre confirmé Avatar de JustMe
    Inscrit en
    Juillet 2002
    Messages
    479
    Détails du profil
    Informations forums :
    Inscription : Juillet 2002
    Messages : 479
    Points : 593
    Points
    593
    Par défaut
    @ShaiLeTroll
    Merci pour tes corrections, j'apprends toujours de ce forum.
    Je voulais te dire juste que c'est un grand plaisir de lire tes réponses sur ce forum
    <On fait la science avec des faits, comme on fait une maison avec des pierres : mais une accumulation de faits n'est pas plus une science qu'un tas de pierres n'est une maison> **Poincaré**

  13. #13
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 63
    Points : 40
    Points
    40
    Par défaut J'ai une solution
    Alors voilà, je viens de trouver une solution qui ressemble plus à un bidouille qu'autre chose.

    Pour comprendre mon truc :
    La grille est dans une scrollbox qui elle est sur la form en alClient. Donc la grille est sur la totalité de la feuille.

    Voici le code

    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
     
    var
      FormImage: TBitmap;
      H,W : Integer;
    begin
      //Je ne veux pas capturer la statusbar
      StatusBar.Visible:=false;
      try
      //Pour que ça marche il faut que la feuille ait BorderStyle à bsNone (me
      //demandez pas pourquoi :) )
      BorderStyle:=bsNone;
      H:=Height;
      W:=Width;
      //La feuille prend les dimensions de la gille
      height:=ZColorStringGrid.Height;
      Width:=ZColorStringGrid.Width;
      // Hop une capture de la form sur laquelle se trouve la scrollbox en alClient
      FormImage := Form1.GetFormImage;
      // On met tout ça dans le clipboard
      Clipboard.Assign(FormImage);
      finally
        //On rétablit les paramètres d'origines 
        BorderStyle:=bsSizeable;
        height:=H;
        Width:=W;
        StatusBar.Visible:=true;
        // On libère l'image
        FormImage.Free;
      end;
    end;
    Voilà c bidouile and cie mais ça marche

    The Jos

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    63
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 63
    Points : 40
    Points
    40
    Par défaut Solution finale
    Voilà la solution que je retiens. Puisqu'une form, avec la propriété BorderStyle à bsNone et agrandie à la dimension de la grille est capable de prendre un screenshot de cette grille je propose :

    1 Créer un feuille (GrabForm)
    2 collez lui le code suivant

    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
    Unit GrabUnit;
     
    Interface
     
    Uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, clipbrd, StdCtrls, ComCtrls;
     
    Type
      TGrabForm = Class(TForm)
        Procedure FormCreate(Sender : TObject);
      Private
         { Déclarations privées }
      Public
        Procedure Execute(WControl : TWinControl;Container : TWinControl);
        { Déclarations publiques }
      End;
     
    Var
      GrabForm : TGrabForm;
    Implementation
     
    {$R *.DFM}
     
    Procedure TGrabForm.Execute(WControl : TWinControl;Container : TWinControl);
    Var
      FormImage : TBitmap;
    Begin
      Try
        //Le winControl à capturer est collé sur la feuille grabform
        WControl.Parent := GrabForm;
        // GrabForm prend les dimensions du WinControl à capturer
        Height := WControl.Height;
        Width := WControl.Width;
        // Capture 
        FormImage := GetFormImage;
        // Hop dans le presse papier
        Clipboard.Assign(FormImage);
      Finally
        // On redonne à la feuille appelante le WinControl
        WControl.Parent := Container;
        // On libère
        FormImage.Free;
      End;
    End;
     
    Procedure TGrabForm.FormCreate(Sender : TObject);
    Begin
      // Ne pas oublier pour que ça marche
      BorderStyle := bsNone;
    End;
     
    End.
    Appelez la Procedure TGrabForm.Execute(WControl : TWinControl;Container : TWinControl); comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      GrabForm.Execute(MyStringGrid, ScrollBox);
    En fait on peut passer n'importe quel WinControl à GrabForm en lui indiquant pour Container son parent

    Par exemple GrabForm.Execute(MyMemo, Form1);
    La feuille GrabForm va prendre une capture du WinControl même s'il a des partie cachées

    Remarque GrabForm n'a pas besoin d'être visibles pour faire son job, donc je ne l'affiche jamais

    Et voili

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

Discussions similaires

  1. Capture d'écran avec SDL à une résolution choisie
    Par shenron666 dans le forum OpenGL
    Réponses: 3
    Dernier message: 02/05/2006, 09h27

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