Here you go
--
Daniel Fisher(lennybacon)
http://www.lennybacon.com
using System;
using System.IO;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
// Interop
using AxSHDocVw;
using mshtml;
using SHDocVw;
namespace StaticDust
{
/// <summary>
/// Converts HTML documents to PNG format.
/// </summary>
public class Html2Image : System.Windows.Forms.UserControl
{
private AxSHDocVw.AxWebBrowser m_IE;
private System.ComponentModel.Container m_Components = null;
#region Html2Image()
private Html2Image()
{
// setups our embedded ie control
InitializeComponent();
}
#endregion
#region Convert()
/// <summary>
/// Converts a HTML file to a PNG file(s).
/// </summary>
/// <param name="url">A string with the url of the HTML file that should
be converted.</param>
/// <param name="pageLength">A int with the heigth of the PNG file(s).
Use -1 to capture the full HTML file.</param>
/// <param name="outputDir">A <see cref="System.String">string</see> with
the path of the directory, where the PNG file(s) should be saved.</param>
/// <param name="outputFile">A <see cref="System.String">string</see>
with the name of the PNG file(s).</param>
/// <returns>An array with filenames of the created PNG
file(s).</returns>
/// <remarks>This method converts a HTML file to PNG file(s).</remarks>
public static String[] Convert(string url, int pageLength, string
outputDir, string outputFile)
{
Html2Image _html2Image = new Html2Image();
_html2Image.CreateControl();
string[] _f = _html2Image.CreateFiles(url, pageLength, outputDir,
outputFile);
_html2Image.Dispose();
return _f;
}
#endregion
#region CreateFiles()
private string[] CreateFiles(string url, int pageLength, string
outputDir, string outputFile)
{
while(!m_IE.Created)
{
Application.DoEvents();
}
object _arg1 = 0;
object _arg2 = "";
object _arg3 = "";
object _arg4 = "";
m_IE.Navigate(url, ref _arg1, ref _arg2, ref _arg3, ref _arg4);
while(!this.m_DocComplete)
{
Application.DoEvents();
}
Application.DoEvents();
while(GetHtmlBody() == null)
{
Application.DoEvents();
}
Application.DoEvents();
m_DocComplete = false;
m_IE.Navigate(url, ref _arg1, ref _arg2, ref _arg3, ref _arg4);
while(!this.m_DocComplete)
{
Application.DoEvents();
}
Application.DoEvents();
while(GetHtmlBody() == null)
{
Application.DoEvents();
}
Application.DoEvents();
for(int i=0; i<2000000; i++)
{
Application.DoEvents();
}
m_DocComplete = false;
m_IE.Navigate(url, ref _arg1, ref _arg2, ref _arg3, ref _arg4);
while(!this.m_DocComplete)
{
Application.DoEvents();
}
Application.DoEvents();
for(int i=0; i<2000000; i++)
{
Application.DoEvents();
}
while(GetHtmlBody() == null)
{
Application.DoEvents();
}
Application.DoEvents();
Bitmap _htmlimage = CaptureImage();
if (_htmlimage!=null)
{
if(pageLength==-1)
{
pageLength = _htmlimage.Height;
}
Bitmap _pageBitmap = new Bitmap(_htmlimage.Width, pageLength);
Graphics _g = Graphics.FromImage(_pageBitmap);
int _p = (int)Math.Floor(_htmlimage.Height/pageLength);
if(_p*pageLength<_htmlimage.Height)
{
_p++;
}
string[] _files = new string[_p];
for (int i=0;i<_files.GetLength(0);i++)
{
_g.Clear(Color.White);
_g.DrawImage(_htmlimage, new Rectangle(0, 0, _pageBitmap.Width,
pageLength), new Rectangle(0, (i*pageLength), _pageBitmap.Width,
pageLength), GraphicsUnit.Pixel);
_files
= Path.Combine(outputDir, outputFile+i+".png");
_pageBitmap.Save(_files, ImageFormat.Png);
}
_htmlimage.Dispose();
_g.Dispose();
_pageBitmap.Dispose();
return _files;
}
return null;
}
#endregion
#region OnDocumentComplete()
private bool m_DocComplete = false;
private void OnDocumentComplete(object sender,
AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEvent e)
{
m_DocComplete = true;
}
#endregion
#region CaptureImage()
private Bitmap CaptureImage()
{
try
{
IHTMLElement2 _htmlBody2 = GetHtmlBody();
Application.DoEvents();
int _w = _htmlBody2.scrollWidth;
int _h = _htmlBody2.scrollHeight;
// Make our embedded ie control that size
if((m_IE.Height != _h + 30) || (m_IE.Width != _w + 30))
{
m_IE.Height = _h + 30;
m_IE.Width = _w + 30;
}
// Setup bitmap memory and wrap a DC around it
Bitmap _bitmap = new Bitmap(_w, _h, PixelFormat.Format24bppRgb);
Graphics _graphics = Graphics.FromImage(_bitmap);
IntPtr _memdc = _graphics.GetHdc();
IntPtr _hbitmap = _bitmap.GetHbitmap();
SelectObject(_memdc, _hbitmap);
// Tell ie to print into our dc/bitmap
// Use PrintWindow windows api
//
const uint PW_CLIENTONLY = 0x00000001;
//
bool _rv = PrintWindow(m_IE.Handle, _memdc, PW_CLIENTONLY);
// Send it a print msg + flags
const uint WM_PRINT = 0x0317;
// const uint WM_PRINTCLIENT = 0x0318;
// const uint PRF_CHECKVISIBLE = 0x00000001;
const uint PRF_NONCLIENT = 0x00000002;
const uint PRF_CLIENT = 0x00000004;
const uint PRF_ERASEBKGND = 0x00000008;
const uint PRF_CHILDREN = 0x00000010;
const uint PRF_OWNED = 0x00000020;
int _err = SendMessage(m_IE.Handle, WM_PRINT, (uint)_memdc, (uint)
(PRF_CLIENT | PRF_NONCLIENT | PRF_OWNED | PRF_CHILDREN | PRF_ERASEBKGND));
// Save image
Bitmap _bitmap2 = Bitmap.FromHbitmap(_hbitmap);
// Cleanup
DeleteObject(_hbitmap);
_graphics.ReleaseHdc(_memdc);
_graphics.Dispose();
_bitmap.Dispose();
return _bitmap2;
}
catch(Exception ex)
{
System.Console.WriteLine("Exception: " + ex.Message + "\n");
System.Console.WriteLine(" source: " + ex.Source + "\n");
System.Console.WriteLine(" stacktrace:" + ex.StackTrace + "\n");
throw;
}
}
#endregion
#region Dispose()
/// <summary>
/// Releases the unmanaged resources used by the Control and its child
controls and optionally releases the managed resources.
/// </summary>
/// <param name="disposing"><b>true</b> to release both managed and
unmanaged resources; <b>false</b> to release only unmanaged resources.
</param>
/// <remarks>
/// This method is called by the public Dispose() method and the Finalize
method. <b>Dispose()</b>
/// invokes the protected <b>Dispose(Boolean)</b> method with
/// the <i>disposing</i> parameter set to <b>true</b>. <b>Finalize</b>
invokes <b>Dispose</b> with <i>disposing</i> set to <b>false</b>.
/// <br/>When the <i>disposing</i> parameter is <b>true</b>, this method
releases all resources held by any managed
/// objects that this Control and its child controls reference. This
method invokes the <b>Dispose()</b>
/// method of each referenced object.
/// <br/><b>Notes to Inheritors:</b> <b>Dispose</b> can be called
multiple times by other objects. When overriding
/// <b>Dispose(Boolean)</b>, be careful not to reference objects that
have been previously disposed of in
/// an earlier call to <b>Dispose</b>.
/// </remarks>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(m_Components != null)
{
m_Components.Dispose();
}
}
base.Dispose( disposing );
}
#endregion
#region InitializeComponent()
private void InitializeComponent()
{
System.Resources.ResourceManager _resources = new
System.Resources.ResourceManager(typeof(Html2Image));
this.m_IE = new AxSHDocVw.AxWebBrowser();
((System.ComponentModel.ISupportInitialize)(this.m_IE)).BeginInit();
this.SuspendLayout();
//
// m_IE
//
this.m_IE.Enabled = true;
this.m_IE.Location = new System.Drawing.Point(0, 0);
//this.m_IE.OcxState =
((System.Windows.Forms.AxHost.State)(resources.GetObject("m_IE.OcxState")));
this.m_IE.Size = new System.Drawing.Size(804, 580);
this.m_IE.TabIndex = 7;
this.m_IE.DocumentComplete += new
AxSHDocVw.DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
//
// Html2Image
//
this.Controls.AddRange(new System.Windows.Forms.Control[] { this.m_IE});
this.Size = new System.Drawing.Size(292, 266);
((System.ComponentModel.ISupportInitialize)(this.m_IE)).EndInit();
this.ResumeLayout(false);
}
#endregion
//IE InterOp
#region IHTMLElement2 GetHtmlBody()
private IHTMLElement2 GetHtmlBody()
{
IWebBrowser2 _wb2 = (IWebBrowser2) m_IE.GetOcx();
Application.DoEvents();
IHTMLDocument2 _htmlDocument2 = (IHTMLDocument2) _wb2.Document;
Application.DoEvents();
return (IHTMLElement2)_htmlDocument2.body;
}
#endregion
//Win32 InterOp
#region extern IntPtr SelectObject()
[DllImport("Gdi32.dll")]
private static extern IntPtr SelectObject(
IntPtr hdc, // handle to DC
IntPtr hgdiobj // handle to object
);
#endregion
#region extern bool DeleteObject()
[DllImport("Gdi32.dll")]
private static extern bool DeleteObject(
IntPtr hObject // handle to graphic object
);
#endregion
#region extern IntPtr CreateCompatibleDC()
[DllImport("Gdi32.dll")]
private static extern IntPtr CreateCompatibleDC(
IntPtr hdc // handle to DC
);
#endregion
#region extern bool DeleteDC()
[DllImport("Gdi32.dll")]
private static extern bool DeleteDC(
IntPtr hdc // handle to DC
);
#endregion
#region extern bool PrintWindow()
[DllImport("User32.dll")]
private static extern bool PrintWindow(
IntPtr hwnd, // Window to copy
IntPtr hdcBlt, // HDC to print into
uint nFlags // Optional flags // must contain
PW_CLIENTONLY
);
#endregion
#region extern int SendMessage()
[DllImport("User32.dll")]
private static extern int SendMessage(
IntPtr hWnd, // handle to destination window
uint Msg, // message
uint wParam, // firstmessage parameter
uint lParam // second message parameter
);
#endregion
}
}
Dave A said:
Sorry - I should have been more clear. I want a thumbnail representation
of what the page will actually look like.
Regards
Dave
Josh Mitts said:
Hi Dave,
If I understand you right, you want to show a preview of the form to
your user, right? How are you rendering the final HTML? Are you using
ASP.NET server controls? Or are you just rendering straight HTML? If you
are just rendering straight HTML, you can update a <div> tag or
<asp:Label> control with your final HTML. You can do this on the
server-side by simply instantiating a HtmlGenericControl for your div
tag and updating its InnerHtml property with your final HTML...i.e.
something like this:
<div ID="PreviewPanel" runat="server">
</div>
And in your server code:
// optional, depending on if you are using ASP.NET 2.0 or not
public HtmlGenericControl PreviewPanel;
[C#]
string finalHtml = "..."; // set this to your application generates
PreviewPanel.InnerHtml = finalHtml;
Voila, you are now rendering the HTML on the page. Just make sure to do
this upon every refresh, i.e. after every time your client updates
something on the page.
If you want to do something more complicated, i.e. render the ASP.NET
server controls, let me know.
--
Joshua Mitts
(e-mail address removed)
I am writing an ASP.NET tool that will allow the client to create their
own online froms. ie the client can add tect boxes, text, drop
downs,etc with absolutely no technical skill what so ever. The form can
then be deployed to their intranet.
The form designer is somewhat WYSIWYG but it contains a heap of 'edit',
'delete' and reordering buttons that are not seen when the form is
acutally being used.
I would love to have a preview image of what the form will actually
look like when it has been rendered in IE and display it in the form
designer. Much like a the print preview in Word.
I figure that my server would need some component that would acutally
render the page in some invisible IE and then take a screen shot of the
web page and then return the image. The designer could then hyperlink
to that image so the use could see a preview.
Another option would be to have an embedded frame but to adjust its
'zoom' to be very small. Unfortunately frames do not support such a
mythical 'zoom' feature.
Does any one have any idea about how I might solve this problem?
The poor mans option is to have a Preview button in the designer that
will lauch a new browser window and display the form but I am trying to
steer away form this.
Regards
Dave A