Sauvegarder l'image d'un controle dans une fichier [Résolu]

Signaler
Messages postés
305
Date d'inscription
lundi 7 janvier 2002
Statut
Membre
Dernière intervention
10 août 2011
-
Messages postés
305
Date d'inscription
lundi 7 janvier 2002
Statut
Membre
Dernière intervention
10 août 2011
-
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

Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
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#]
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
29
Salut, effectivement cette fonction est dispo uniquement dans WinXP et Sercer2003 :/
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
arf... ok...
sous Windows 2000, le PrintWindow n'existe pas... il faut utiliser BitBlt

Sébastien FERRAND
[MVP Visual C#]
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
non... le seul moyen c'est de passer par l'api

Sébastien FERRAND
[MVP Visual C#]
Messages postés
305
Date d'inscription
lundi 7 janvier 2002
Statut
Membre
Dernière intervention
10 août 2011
4
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
Messages postés
305
Date d'inscription
lundi 7 janvier 2002
Statut
Membre
Dernière intervention
10 août 2011
4
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
Messages postés
305
Date d'inscription
lundi 7 janvier 2002
Statut
Membre
Dernière intervention
10 août 2011
4
Ok, Je vous remercie tous pour vos réponse !
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
29
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;
}
}
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
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#
*/
Messages postés
3246
Date d'inscription
lundi 25 avril 2005
Statut
Modérateur
Dernière intervention
27 octobre 2012
29
"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. : )
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
80
Ouep, c'est dans le contexte du sujet que je disais ça :-)

/*
coq
MVP Visual C#
*/
Messages postés
4936
Date d'inscription
lundi 17 février 2003
Statut
Modérateur
Dernière intervention
14 février 2014
32
en complément si tu es .net 2.0 : http://www.csharpfr.com/code.aspx?ID=35841

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