Sauvegarder l'image d'un controle dans une fichier

Résolu
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 - 31 janv. 2006 à 14:37
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 - 1 févr. 2006 à 11:21
Salut,

Je souhaite enregistrer le rendu produit par un composant ergonomique (dans mon cas un WebBrowser) dans un fichier bmp... Quelqu'un saurait comment effectuer ce type d'opération ?

Merci d'avance !

Yoann

13 réponses

sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
31 janv. 2006 à 15:00
il y a plusieurs façon de faire.

tu peux passer par l'API PrintWindow en donnant le Handle de ton controle.
Tu peux regarder cet article pour savoir comment ca marche : http://www.dotnet-tech.com/tutoriels/capture-ecran/

Sébastien FERRAND
[MVP Visual C#]
3
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
31 janv. 2006 à 15:44
Salut, effectivement cette fonction est dispo uniquement dans WinXP et Sercer2003 :/
3
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
31 janv. 2006 à 15:45
arf... ok...
sous Windows 2000, le PrintWindow n'existe pas... il faut utiliser BitBlt

Sébastien FERRAND
[MVP Visual C#]
3
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
31 janv. 2006 à 16:21
non... le seul moyen c'est de passer par l'api

Sébastien FERRAND
[MVP Visual C#]
3

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 7
31 janv. 2006 à 15:37
Merci pour ta réponse, mais j'ai l'erreur suivante à l'éxécution de ta source :

Une exception non gérée du type 'System.EntryPointNotFoundException' s'est produite dans CaptureEcran.exe

Informations supplémentaires : Impossible de trouver le point d'entrée PrintWindow dans la DLL user32.dll.

Je tourne sous windows 2000... ça joue peut-être.

Tu as une idée ?

Yoann
0
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 7
31 janv. 2006 à 16:11
Ok,

Merci pour vos réponse, mais n'y aurai-t-il pas un moyen de sauvegarder le contenu de l'objet Graphics (en faisant un MonControle.CreateGraphics()) ?

Yoann
0
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 7
31 janv. 2006 à 16:51
Ok, Je vous remercie tous pour vos réponse !
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
31 janv. 2006 à 17:53
Je mets le code car c'est pas très simple, même si tout est expliqué dans le tutorial de Sébastien, ça servira pour toi ou pour d'autres :

public partial class Form1 : Form
{
public Form1( )
{
InitializeComponent( );


Button b = new Button( );
b.Text = "Print";
b.Location = new Point( 0, 0 );
b.Click += delegate
{
Bitmap bmp = PrintWindow( );
bmp.Save( "C:\\print.bmp", System.Drawing.Imaging.ImageFormat.Bmp );
};


this.Controls.Add( b );
}


private const int SRCCOPY = 0x00CC0020;


[ DllImport( "gdi32.dll", SetLastError = true ) ]
private static extern bool BitBlt
(
IntPtr dstHdc,
int dstX,
int dstY,
int dstW,
int dstH,
IntPtr srcHdc,
int srcX,
int srcY,
uint rop
);


public Bitmap PrintWindow( )
{
Bitmap bmp = null;


using ( Graphics srcG = this.CreateGraphics( ) )
{
int w = this.ClientSize.Width;
int h = this.ClientSize.Height;
bmp = new Bitmap( w, h, srcG );


using ( Graphics dstG = Graphics.FromImage( bmp ) )
{
IntPtr srcHdc = srcG.GetHdc( );
IntPtr dstHdc = dstG.GetHdc( );


BitBlt( dstHdc, 0, 0, w, h, srcHdc, 0, 0, SRCCOPY );


srcG.ReleaseHdc( srcHdc );
dstG.ReleaseHdc( dstHdc );
}
}


return bmp;
}
}
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
31 janv. 2006 à 19:53
Salut,

En fait je ne suis pas trop d'accord pour la méthode BitBlt pour remplacer PrintWindow : cette méthode va "dumper" tout ce qui est visible dans le rectangle.
Placez donc une fenêtre en "Always On Top" (la plus facile à trouver : le gestionnaire des tâches de win) au dessus du form avant de cliquer sur le bouton et vous comprendrez ce que je veux dire :-)

Pour remplacer PrintWindow, je pense qu'il vaut mieux utiliser la notification WM_PRINT. (il faut naturellement que les contrôles qui vont être ciblés gèrent ce message, en général c'est le cas).
Ca donne quelquechose de ce genre (à adapter et améliorer) :

private const int WM_PRINT = 0x0317;


private const int PRF_CHECKVISIBLE = 0x00000001;
private const int PRF_NONCLIENT = 0x00000002;
private const int PRF_CLIENT = 0x00000004;
private const int PRF_ERASEBKGND = 0x00000008;
private const int PRF_CHILDREN = 0x00000010;
private const int PRF_OWNED = 0x00000020;


public Bitmap PrintWindowEx()
{
Bitmap bmp = null;
Graphics gr = null;
IntPtr hdc = IntPtr.Zero;


try
{
bmp = new Bitmap(
this.ClientRectangle.Width,
this.ClientRectangle.Height,
this.CreateGraphics()
);
gr = Graphics.FromImage(bmp);
hdc = gr.GetHdc();


IntPtr wParam = hdc;
IntPtr lParam = new IntPtr(PRF_CLIENT | PRF_CHILDREN);


Message msg = Message.Create(this.Handle, WM_PRINT, wParam, lParam);
this.WndProc(ref msg);
}
catch
{
}
finally
{
if ( gr != null )
{
if (hdc != IntPtr.Zero)
gr.ReleaseHdc(hdc);


gr.Dispose();
}
}


return bmp;
}

Refaites le test avec le taskmanager :-)

/*
coq
MVP Visual C#
*/
0
Lutinore Messages postés 3246 Date d'inscription lundi 25 avril 2005 Statut Membre Dernière intervention 27 octobre 2012 41
31 janv. 2006 à 20:20
"cette méthode va "dumper" tout ce qui est visible dans le rectangle."

Dans mon cas c'était le but recherché ( si, si.. ).

Mais effectivement WM_PRINT est bien plus approprié pour ce que veut faire Yoannd. : )
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
31 janv. 2006 à 20:56
Ouep, c'est dans le contexte du sujet que je disais ça :-)

/*
coq
MVP Visual C#
*/
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
1 févr. 2006 à 11:19
en complément si tu es .net 2.0 : http://www.csharpfr.com/code.aspx?ID=35841

Sébastien FERRAND
[MVP Visual C#]
0
cs_yoannd Messages postés 305 Date d'inscription lundi 7 janvier 2002 Statut Membre Dernière intervention 10 août 2011 7
1 févr. 2006 à 11:21
erf... je suis pas aidé de ce côté là non plus : je suis en .net 1.1, mais merci quand même !
0
Rejoignez-nous