 |
|
 |
as title, always got the same value which equals the client height and width.
cannot scroll: http://www.google.com/mail http://www.google.com/reader
can be scrolled: http://www.google.com/nwshp?tab=mn http://www.google.com/calendar/render?tab=oc
Do you have any idea? 
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Copy These Lines to Form1.cs ...
/* --------------------------------------------------------------------------- * * Copyright (c) Doug Weems. * * You may use this code for fun and knowledge. * You can compile and use the application as is or copy out what you need. * This code makes for a really useful tool. * * --------------------------------------------------------------------------- */
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; using System.Text; using System.Runtime.InteropServices; using System.Diagnostics; using System.IO; using System.Drawing.Imaging; using SHDocVw; using mshtml;
namespace IEWindowCapture { /// <summary> /// This is the working code for "IE Complete Web Window Image Capture". IECWWIC for short. /// Just kidding. Call it, "WebPageToImage". /// This tool will pick up one open IE window and capture the entire web page to a single jpeg. /// It is best if you only are running the IE instance that you are interested in. /// The quality and size of the image can be adjusted and standard resolution screen sizes and web page name /// can be added to the image. /// Author: Doug Weems /// </summary> public class frmMain : System.Windows.Forms.Form { private System.Windows.Forms.GroupBox grpWebCapture; private System.Windows.Forms.LinkLabel lnkOpenCapture; private System.Windows.Forms.CheckBox chkShowGuides; private System.Windows.Forms.GroupBox groupBox1; private System.Windows.Forms.ComboBox cmbResolution; private System.Windows.Forms.Label lblResolution; private System.Windows.Forms.Label lblQuality; private System.Windows.Forms.ComboBox cmbQuality; private System.Windows.Forms.CheckBox chkWriteURL; private System.Windows.Forms.Button button1; /// <summary> /// Required designer variable. /// </summary> private System.ComponentModel.Container components = null;
public frmMain() { InitializeComponent(); }
/// <summary> /// Clean up any resources being used. /// </summary> protected override void Dispose( bool disposing ) { if( disposing ) { if (components != null) { components.Dispose(); } } base.Dispose( disposing ); }
#region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// </summary> private void InitializeComponent() { System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(frmMain)); this.grpWebCapture = new System.Windows.Forms.GroupBox(); this.lnkOpenCapture = new System.Windows.Forms.LinkLabel(); this.chkShowGuides = new System.Windows.Forms.CheckBox(); this.groupBox1 = new System.Windows.Forms.GroupBox(); this.cmbResolution = new System.Windows.Forms.ComboBox(); this.lblResolution = new System.Windows.Forms.Label(); this.lblQuality = new System.Windows.Forms.Label(); this.cmbQuality = new System.Windows.Forms.ComboBox(); this.chkWriteURL = new System.Windows.Forms.CheckBox(); this.button1 = new System.Windows.Forms.Button(); this.grpWebCapture.SuspendLayout(); this.groupBox1.SuspendLayout(); this.SuspendLayout(); // // grpWebCapture // this.grpWebCapture.Controls.Add(this.lnkOpenCapture); this.grpWebCapture.Controls.Add(this.chkShowGuides); this.grpWebCapture.Controls.Add(this.groupBox1); this.grpWebCapture.Controls.Add(this.chkWriteURL); this.grpWebCapture.Controls.Add(this.button1); this.grpWebCapture.Location = new System.Drawing.Point(28, 12); this.grpWebCapture.Name = "grpWebCapture"; this.grpWebCapture.Size = new System.Drawing.Size(256, 208); this.grpWebCapture.TabIndex = 41; this.grpWebCapture.TabStop = false; this.grpWebCapture.Text = "Capture Web Page"; // // lnkOpenCapture // this.lnkOpenCapture.Location = new System.Drawing.Point(16, 136); this.lnkOpenCapture.Name = "lnkOpenCapture"; this.lnkOpenCapture.Size = new System.Drawing.Size(128, 16); this.lnkOpenCapture.TabIndex = 36; this.lnkOpenCapture.TabStop = true; this.lnkOpenCapture.Text = "Open Capture Directory"; this.lnkOpenCapture.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.lnkOpenCapture_LinkClicked); // // chkShowGuides // this.chkShowGuides.Location = new System.Drawing.Point(16, 112); this.chkShowGuides.Name = "chkShowGuides"; this.chkShowGuides.Size = new System.Drawing.Size(200, 16); this.chkShowGuides.TabIndex = 34; this.chkShowGuides.Text = "draw Standard Resolution Guides"; // // groupBox1 // this.groupBox1.Controls.Add(this.cmbResolution); this.groupBox1.Controls.Add(this.lblResolution); this.groupBox1.Controls.Add(this.lblQuality); this.groupBox1.Controls.Add(this.cmbQuality); this.groupBox1.ForeColor = System.Drawing.Color.Black; this.groupBox1.Location = new System.Drawing.Point(16, 16); this.groupBox1.Name = "groupBox1"; this.groupBox1.Size = new System.Drawing.Size(200, 80); this.groupBox1.TabIndex = 39; this.groupBox1.TabStop = false; this.groupBox1.Text = "Reduce File Size by reducing Quality and/or Resolution"; // // cmbResolution // this.cmbResolution.Items.AddRange(new object[] { "100", "90", "80", "70", "60", "50", "40"}); this.cmbResolution.Location = new System.Drawing.Point(120, 32); this.cmbResolution.Name = "cmbResolution"; this.cmbResolution.Size = new System.Drawing.Size(48, 21); this.cmbResolution.TabIndex = 31; this.cmbResolution.Text = "90"; // // lblResolution // this.lblResolution.Location = new System.Drawing.Point(24, 32); this.lblResolution.Name = "lblResolution"; this.lblResolution.Size = new System.Drawing.Size(88, 16); this.lblResolution.TabIndex = 35; this.lblResolution.Text = "% Capture Size"; this.lblResolution.TextAlign = System.Drawing.ContentAlignment.TopRight; // // lblQuality // this.lblQuality.Location = new System.Drawing.Point(24, 56); this.lblQuality.Name = "lblQuality"; this.lblQuality.Size = new System.Drawing.Size(88, 16); this.lblQuality.TabIndex = 38; this.lblQuality.Text = "Quality"; this.lblQuality.TextAlign = System.Drawing.ContentAlignment.TopRight; // // cmbQuality // this.cmbQuality.Items.AddRange(new object[] { "100", "90", "80", "70", "50", "30", "10"}); this.cmbQuality.Location = new System.Drawing.Point(120, 56); this.cmbQuality.Name = "cmbQuality"; this.cmbQuality.Size = new System.Drawing.Size(48, 21); this.cmbQuality.TabIndex = 37; this.cmbQuality.Text = "70"; // // chkWriteURL // this.chkWriteURL.Location = new System.Drawing.Point(16, 96); this.chkWriteURL.Name = "chkWriteURL"; this.chkWriteURL.Size = new System.Drawing.Size(176, 16); this.chkWriteURL.TabIndex = 32; this.chkWriteURL.Text = "write URL name on Image"; // // button1 // this.button1.Cursor = System.Windows.Forms.Cursors.Hand; this.button1.ForeColor = System.Drawing.Color.White; this.button1.Image = ((System.Drawing.Image)(resources.GetObject("button1.Image"))); this.button1.Location = new System.Drawing.Point(176, 144); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(48, 40); this.button1.TabIndex = 29; this.button1.TextAlign = System.Drawing.ContentAlignment.TopCenter; this.button1.Click += new System.EventHandler(this.button1_Click); // // frmMain // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(304, 238); this.Controls.Add(this.grpWebCapture); this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon"))); this.Name = "frmMain"; this.Text = "Capture"; this.grpWebCapture.ResumeLayout(false); this.groupBox1.ResumeLayout(false); this.ResumeLayout(false);
} #endregion
/// <summary> /// The main entry point for the application. /// </summary> [STAThread] static void Main() { Application.Run(new frmMain()); }
//We need some system dll functions. [DllImport("user32.dll", CharSet=CharSet.Auto)] public static extern IntPtr FindWindowEx(IntPtr parent /*HWND*/, IntPtr next /*HWND*/, string sClassName, IntPtr sWindowTitle); [DllImport("user32.dll", ExactSpelling=true, CharSet=CharSet.Auto)] public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
[DllImport("user32.Dll")] public static extern void GetClassName(int h, StringBuilder s, int nMaxCount);
[DllImport("user32.dll")] private static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, uint nFlags);
public const int GW_CHILD = 5; public const int GW_HWNDNEXT = 2; int heightsize; int widthsize; int screenHeight; int screenWidth; public bool IsDTDDocument(object document) { // XHtml declare flag string string DocTypeContent = @"-//W3C//DTD"; mshtml.IHTMLDocument3 document3 = (mshtml.IHTMLDocument3)document; mshtml.IHTMLDOMChildrenCollection domChilds = (mshtml.IHTMLDOMChildrenCollection)document3.childNodes; mshtml.IHTMLDOMNode domNode = (mshtml.IHTMLDOMNode)domChilds.item(0); return domNode.nodeValue.ToString().Contains(DocTypeContent); }
private void button1_Click(object sender, System.EventArgs e) { //TODO In Next Version: //Add cursor capture //Add file naming option //Add visible screen capture //Make captured image a DDB not a DIB bitmap. Cursor.Current = Cursors.WaitCursor; SHDocVw.WebBrowser m_browser = null;
SHDocVw.ShellWindows shellWindows = new SHDocVw.ShellWindowsClass();
//Find first availble browser window. //Application can easily be modified to loop through and capture all open windows. string filename; foreach (SHDocVw.WebBrowser ie in shellWindows) { filename = Path.GetFileNameWithoutExtension(ie.FullName).ToLower(); if (filename.Equals("iexplore")) { m_browser = ie; break; } } if (m_browser == null) { MessageBox.Show("No Browser Open"); return; }
//Assign Browser Document mshtml.IHTMLDocument2 myDoc = (mshtml.IHTMLDocument2)m_browser.Document; mshtml.IHTMLDocument3 doc3 = (mshtml.IHTMLDocument3)myDoc;
//URL Location string myLocalLink = myDoc.url; int URLExtraHeight = 0; int URLExtraLeft = 0;
//Adjustment variable for capture size. if (chkWriteURL.Checked == true) URLExtraHeight = 25;
//TrimHeight and TrimLeft trims off some captured IE graphics. int trimHeight = 3; int trimLeft = 3;
//Use UrlExtra height to carry trimHeight. URLExtraHeight = URLExtraHeight - trimHeight; URLExtraLeft = URLExtraLeft - trimLeft; if (!IsDTDDocument(myDoc)) { myDoc.body.setAttribute("scroll", "yes", 0);
//Get Browser Window Height heightsize = (int)myDoc.body.getAttribute("scrollHeight", 0); widthsize = (int)myDoc.body.getAttribute("scrollWidth", 0);
//Get Screen Height screenHeight = (int)myDoc.body.getAttribute("clientHeight", 0); screenWidth = (int)myDoc.body.getAttribute("clientWidth", 0); } else { doc3.documentElement.setAttribute("scroll", "Yes", 0);
//Get Browser Window Height heightsize = (int)doc3.documentElement.getAttribute("scrollHeight", 0); widthsize = (int)doc3.documentElement.getAttribute("scrollWidth", 0);
//Get Screen Height screenHeight = (int)doc3.documentElement.getAttribute("clientHeight", 0); screenWidth = (int)doc3.documentElement.getAttribute("clientWidth", 0);
} //Get bitmap to hold screen fragment. Bitmap bm = new Bitmap(screenWidth, screenHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb555);
//Create a target bitmap to draw into. Bitmap bm2 = new Bitmap(widthsize + URLExtraLeft, heightsize + URLExtraHeight - trimHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb555); Graphics g2 = Graphics.FromImage(bm2);
Graphics g = null; IntPtr hdc; Image screenfrag = null; int brwTop = 0; int brwLeft = 0; int myPage = 0; IntPtr myIntptr = (IntPtr)m_browser.HWND; //Get inner browser window. int hwndInt = myIntptr.ToInt32(); IntPtr hwnd = myIntptr; hwnd = GetWindow(hwnd, GW_CHILD); StringBuilder sbc = new StringBuilder(256);
//Get Browser "Document" Handle while (hwndInt != 0) { hwndInt = hwnd.ToInt32(); GetClassName(hwndInt, sbc, 256); if(sbc.ToString().IndexOf("Shell DocObject View", 0) > -1) //IE6 { hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero); break; } if (sbc.ToString().IndexOf("TabWindowClass", 0) > -1) //IE7 { hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero); hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero); break; } if (sbc.ToString().IndexOf("Frame Tab", 0) > -1) // IE8 { hwnd = FindWindowEx(hwnd, IntPtr.Zero, "TabWindowClass", IntPtr.Zero); hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero); hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero); break; } hwnd = GetWindow(hwnd, GW_HWNDNEXT); } //Get Screen Height (for bottom up screen drawing) while ((myPage * screenHeight) < heightsize) { if (!IsDTDDocument(myDoc)) myDoc.body.setAttribute("scrollTop", (screenHeight - 5) * myPage, 0); else doc3.documentElement.setAttribute("scrollTop", (screenHeight - 5) * myPage, 0); ++myPage; } //Rollback the page count by one --myPage; int myPageWidth = 0;
while ((myPageWidth * screenWidth) < widthsize) { if (!IsDTDDocument(myDoc)) myDoc.body.setAttribute("scrollLeft", (screenWidth - 5) * myPageWidth, 0); else doc3.documentElement.setAttribute("scrollLeft", (screenWidth - 5) * myPageWidth, 0); if (!IsDTDDocument(myDoc)) brwLeft = (int)myDoc.body.getAttribute("scrollLeft", 0); else brwLeft = (int)doc3.documentElement.getAttribute("scrollLeft", 0); for (int i = myPage; i >= 0; --i) { //Shoot visible window g = Graphics.FromImage(bm); hdc = g.GetHdc(); if (!IsDTDDocument(myDoc)) myDoc.body.setAttribute("scrollTop", (screenHeight - 5) * i, 0); else doc3.documentElement.setAttribute("scrollTop", (screenHeight - 5) * i, 0);
if (!IsDTDDocument(myDoc)) brwTop = (int)myDoc.body.getAttribute("scrollTop", 0); else brwTop = (int)doc3.documentElement.getAttribute("scrollTop", 0); PrintWindow(hwnd, hdc, 0); g.ReleaseHdc(hdc); g.Flush(); screenfrag = Image.FromHbitmap(bm.GetHbitmap()); g2.DrawImage(screenfrag, brwLeft + URLExtraLeft, brwTop + URLExtraHeight); } ++myPageWidth; }
//Draw Standard Resolution Guides if(chkShowGuides.Checked == true) { // Create pen. int myWidth = 1; Pen myPen = new Pen(Color.Navy, myWidth); Pen myShadowPen = new Pen(Color.NavajoWhite, myWidth); // Create coordinates of points that define line. float x1 = -(float)myWidth - 1 + URLExtraLeft; float y1 = -(float)myWidth - 1 + URLExtraHeight;
float x600 = 600.0F + (float)myWidth+1; float y480 = 480.0F + (float)myWidth+1;
float x2 = 800.0F + (float)myWidth+1; float y2 = 600.0F + (float)myWidth+1;
float x3 = 1024.0F + (float)myWidth+1; float y3 = 768.0F + (float)myWidth+1;
float x1280 = 1280.0F + (float)myWidth+1; float y1024 = 1024.0F + (float)myWidth+1;
// Draw line to screen. g2.DrawRectangle(myPen, x1, y1, x600+myWidth, y480+myWidth); g2.DrawRectangle(myPen, x1, y1, x2+myWidth, y2+myWidth); g2.DrawRectangle(myPen, x1, y1, x3+myWidth, y3+myWidth); g2.DrawRectangle(myPen, x1, y1, x1280+myWidth, y1024+myWidth);
// Create font and brush. Font drawFont = new Font("Arial", 12); SolidBrush drawBrush = new SolidBrush(Color.Navy); SolidBrush drawBrush2 = new SolidBrush(Color.NavajoWhite); // Set format of string. StringFormat drawFormat = new StringFormat(); drawFormat.FormatFlags = StringFormatFlags.FitBlackBox; // Draw string to screen. g2.DrawString("600 x 480", drawFont, drawBrush, 5, y480 - 20 + URLExtraHeight, drawFormat); g2.DrawString("800 x 600", drawFont, drawBrush, 5, y2 - 20 + URLExtraHeight, drawFormat); g2.DrawString("1024 x 768", drawFont, drawBrush, 5, y3 - 20 + URLExtraHeight, drawFormat); g2.DrawString("1280 x 1024", drawFont, drawBrush, 5, y1024 - 20 + URLExtraHeight, drawFormat); }
//Write URL if (chkWriteURL.Checked == true) { //Backfill URL paint location SolidBrush whiteBrush = new SolidBrush(Color.White); Rectangle fillRect = new Rectangle(0, 0, widthsize, URLExtraHeight+2); Region fillRegion = new Region(fillRect); g2.FillRegion(whiteBrush, fillRegion);
SolidBrush drawBrushURL = new SolidBrush(Color.Black); Font drawFont = new Font("Arial", 12); StringFormat drawFormat = new StringFormat(); drawFormat.FormatFlags = StringFormatFlags.FitBlackBox;
g2.DrawString(myLocalLink, drawFont, drawBrushURL, 0, 0, drawFormat); } //Reduce Resolution Size double myResolution = Convert.ToDouble(cmbResolution.Text) * 0.01; int finalWidth = (int)((widthsize + URLExtraLeft) * myResolution); int finalHeight = (int)((heightsize + URLExtraHeight) * myResolution); Bitmap finalImage = new Bitmap(finalWidth, finalHeight, System.Drawing.Imaging.PixelFormat.Format16bppRgb555); Graphics gFinal = Graphics.FromImage((Image)finalImage); gFinal.DrawImage( bm2, 0, 0, finalWidth, finalHeight); //Get Time Stamp DateTime myTime = DateTime.Now; String format = "MM.dd.hh.mm.ss";
//Create Directory to save image to. Directory.CreateDirectory("C:\\IECapture");
//Write Image. EncoderParameters eps = new EncoderParameters(1); long myQuality = Convert.ToInt64(cmbQuality.Text); eps.Param[0] = new EncoderParameter( System.Drawing.Imaging.Encoder.Quality, myQuality); ImageCodecInfo ici = GetEncoderInfo("image/jpeg"); finalImage.Save(@"c:\\IECapture\Captured_" + myTime.ToString(format) + ".jpg", ici, eps);
//Clean Up. myDoc = null; g.Dispose(); g2.Dispose(); gFinal.Dispose(); bm.Dispose(); bm2.Dispose(); finalImage.Dispose();
Cursor.Current = Cursors.Default; }
private static ImageCodecInfo GetEncoderInfo(String mimeType) { int j; ImageCodecInfo[] encoders; encoders = ImageCodecInfo.GetImageEncoders(); for(j = 0; j < encoders.Length; ++j) { if(encoders[j].MimeType == mimeType) return encoders[j]; } return null; }
private void lnkOpenCapture_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) { Process.Start("explorer.exe", "C:\\IECapture"); }
} }
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
 |
It works fine in some cases but it also failed sometimes. I am still finding th root cause. Failed Url: http://www.mobile01.com/newsdetail.php?id=7299 Please check!
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
//Get Browser Window Height int heightsize = getAttribute("scrollHeight", myDoc, doc3); int widthsize = getAttribute("scrollWidth", myDoc, doc3); //Get Screen Height int screenHeight = getAttribute("clientHeight", myDoc, doc3); int screenWidth = getAttribute("clientWidth", myDoc, doc3);
the heightsize and screenHeight returns the same value the widthsize and screenWidth returns the same value
so the loop does not count the number of pages
//Get Screen Height (for bottom up screen drawing) while ((myPage * screenHeight) < heightsize) { setAttribute("scrollTop", (screenHeight - 5) * myPage, myDoc, doc3); ++myPage; } //Rollback the page count by one --myPage;
Please let us know the problem ASAP
ff
|
| Sign In·View Thread·PermaLink | 2.00/5 (1 vote) |
|
|
|
 |
|
 |
You cannot have the browser window minimized when taking the screenshot. Just thought I would share this in case someone else is making the same mistake.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
 |
Building on an earlier comment by Daniel Landers, I was able to make this app run with with IE versions 6,7, and 8. Here is the modification to the code to make it work. Find the comment to Get browser "Document" handle and replace the code between that and the "Get Screen Height (for bottom up screen drawing)" comment with the code below.
//Get Browser "Document" Handle while (hwndInt != 0) { hwndInt = hwnd.ToInt32(); GetClassName(hwndInt, sbc, 256); if(sbc.ToString().IndexOf("Shell DocObject View", 0) > -1) //IE6 { hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero); break; } if (sbc.ToString().IndexOf("TabWindowClass", 0) > -1) //IE7 { hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero); hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero); break; } if (sbc.ToString().IndexOf("Frame Tab", 0) > -1) // IE8 { hwnd = FindWindowEx(hwnd, IntPtr.Zero, "TabWindowClass", IntPtr.Zero); hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Shell DocObject View", IntPtr.Zero); hwnd = FindWindowEx(hwnd, IntPtr.Zero, "Internet Explorer_Server", IntPtr.Zero); break; }
hwnd = GetWindow(hwnd, GW_HWNDNEXT); }
|
| Sign In·View Thread·PermaLink | 5.00/5 (1 vote) |
|
|
|
 |
|
 |
This works better than the previous code, but does not solve all. Some pages now work fine in IE8 and some are still black.
For instance: www.alpakka.org works kinda ok. Most of the page is rendered just fine www.alpakkanorge.no is all black www.vg.no is fine www.abb.com mostly renders ok, but a part at the bottom is gone (blackened) like www.alpakka.org
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This is really fits more in line with the black images comment below, but another user sent me a new function to replace my isDTDDocument function. This one seems to work a bit more reliably and reslved the problem on the pages you listed.
public bool IsDTDDocument(object document) { bool retVal = false; IHTMLDocument5 doc5 = (IHTMLDocument5)document; IHTMLDocument3 doc3 = (IHTMLDocument3)document; //compatibility mode affects how height is computed if ((doc3.documentElement != null) && (!doc5.compatMode.Equals("BackCompat"))) { retVal = true; } return retVal; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Navid Akhtar showed a solution for the Black Image problem in his comment titled "Capturing entire web page like msn.com" unfortunately he ended his comment with "Similarly update other location where we are trying to get/set attributes." This may have left some people with the code still not working for pages that have a Strict DTD set.
So to Recap what Navid said, the problem with Black images is that pages with a Strict DTD set have a different structure for accessing the document attributes. Instead of myDoc.body.getAttribute("attributeName") you have to create an object as an IHTMLDocument3 object and access the attributes with thes new object named "doc3" in the example as doc3.documentElement.getAttribute("attributeName").
So Here's a more complete set of code for performing this:
Step 1: This code corresponds to the bottom of the third code section in the article or line 289 of Form1.cs in the provided source code.
//Assign Browser Document mshtml.IHTMLDocument2 myDoc = (mshtml.IHTMLDocument2)m_browser.Document; mshtml.IHTMLDocument3 doc3 = (mshtml.IHTMLDocument3)myDoc ;
Step 2: Add the following Function to your code. I'm adding it to the bottom to not interfere with the line numbers I'll be mentioning later. This code is from Navid Akhtar's comment. I adjusted ths function to return false for documents with a Transitional DTD. Pages with a Transitional DTD work the same as those without a DTD.
public bool IsDTDDocument(object document) { bool retVal = false; // XHtml declare flag string string DocTypeContent = @"-//W3C//DTD"; mshtml.IHTMLDocument3 document3 = (mshtml.IHTMLDocument3)document; mshtml.IHTMLDOMChildrenCollection domChilds = (mshtml.IHTMLDOMChildrenCollection)document3.childNodes; mshtml.IHTMLDOMNode domNode = (mshtml.IHTMLDOMNode)domChilds.item(0); if (domNode.nodeValue.ToString().Contains(DocTypeContent) && !domNode.nodeValue.ToString().Contains("Transitional")) retVal = true; return retVal; }
Step 3: I've created two more Functions to handle getting and setting attributes so we don't have to have a bunch of if ... else statements throughout the code. Again, I've added these to the end of the class.
public void setAttribute(string attribute, int value, mshtml.IHTMLDocument2 myDoc, mshtml.IHTMLDocument3 doc3) { if (!IsDTDDocument(myDoc)) myDoc.body.setAttribute(attribute, value, 0); else doc3.documentElement.setAttribute(attribute, value, 0); }
public int getAttribute(string attribute, mshtml.IHTMLDocument2 myDoc, mshtml.IHTMLDocument3 doc3) { int retVal = 0; if (!IsDTDDocument(myDoc)) retVal = (int)myDoc.body.getAttribute(attribute, 0); else retVal = (int)doc3.documentElement.getAttribute(attribute, 0); return retVal; }
Step 4. We go in and change all of the calls to get or set attributes to use the new functions. change Line 310 - 318 From: myDoc.body.setAttribute("scroll", "yes", 0);
//Get Browser Window Height int heightsize = (int)myDoc.body.getAttribute("scrollHeight", 0); int widthsize = (int)myDoc.body.getAttribute("scrollWidth", 0); //Get Screen Height int screenHeight = (int)myDoc.body.getAttribute("clientHeight", 0); int screenWidth = (int)myDoc.body.getAttribute("clientWidth", 0); To: setAttribute("scroll", 1, myDoc, doc3);
//Get Browser Window Height int heightsize = getAttribute("scrollHeight", myDoc, doc3); int widthsize = getAttribute("scrollWidth", myDoc, doc3); //Get Screen Height int screenHeight = getAttribute("clientHeight", myDoc, doc3); int screenWidth = getAttribute("clientWidth", myDoc, doc3);
Change Line 357 From: myDoc.body.setAttribute("scrollTop", (screenHeight - 5) * myPage, 0); To: setAttribute("scrollTop", (screenHeight - 5) * myPage, myDoc, doc3);
Change Lines 367 - 381 From: myDoc.body.setAttribute("scrollLeft", (screenWidth - 5) * myPageWidth, 0); brwLeft = (int)myDoc.body.getAttribute("scrollLeft", 0); for (int i = myPage; i >= 0; --i) { //Shoot visible window g = Graphics.FromImage(bm); hdc = g.GetHdc(); myDoc.body.setAttribute("scrollTop", (screenHeight - 5) * i, 0); brwTop = (int)myDoc.body.getAttribute("scrollTop", 0); PrintWindow(hwnd, hdc, 0); g.ReleaseHdc(hdc); g.Flush(); screenfrag = Image.FromHbitmap(bm.GetHbitmap()); g2.DrawImage(screenfrag, brwLeft + URLExtraLeft, brwTop + URLExtraHeight); } To: setAttribute("scrollLeft", (screenWidth - 5) * myPageWidth, myDoc, doc3); brwLeft = getAttribute("scrollLeft", myDoc, doc3); for (int i = myPage; i >= 0; --i) { //Shoot visible window g = Graphics.FromImage(bm); hdc = g.GetHdc(); setAttribute("scrollTop", (screenHeight - 5) * i, myDoc, doc3); brwTop = getAttribute("scrollTop", myDoc, Doc3); PrintWindow(hwnd, hdc, 0); g.ReleaseHdc(hdc); g.Flush(); screenfrag = Image.FromHbitmap(bm.GetHbitmap()); g2.DrawImage(screenfrag, brwLeft + URLExtraLeft, brwTop + URLExtraHeight); }
This should make the code in this article work for all pages whether Strict DTD or not.
modified on Thursday, March 19, 2009 1:24 PM
|
| Sign In·View Thread·PermaLink | 5.00/5 (2 votes) |
|
|
|
 |
|
 |
Hi, I tried to follow your instruction step by step, but it still not work for me, the tool always return black image to me I'm sure the targe window(IE7) are not minize in taskbar.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
Try replacing the isDTDDocument function with the following. It seems to be more reliable at determining which pages need to use which method for calculating page size.
public bool IsDTDDocument(object document) { bool retVal = false; IHTMLDocument5 doc5 = (IHTMLDocument5)document; IHTMLDocument3 doc3 = (IHTMLDocument3)document; //compatibility mode affects how height is computed if ((doc3.documentElement != null) && (!doc5.compatMode.Equals("BackCompat"))) { retVal = true; } return retVal; }
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
I am able to get the image for the very first instance(First Tab) in IE7, but for the next instances(Tab) in IE7 it creates only Black images.
Is there any work around for this problem?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I worked with code and its working fine in XP/sp2. but its giving problem with Vista may be due to use of shellWindows class . We cannot use shell windows class in vista in protected mode. If I disable UAC then its works fine.
Anyone tell me how it can be it work for Vista.
Best Regards Bishwajeet
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
|
 |
|
 |
In your code you are using the same color depth any time. But the screenshots will be not perfekt, if there is i.e. an colour-gradient on the screen.
Add to following code to adjust the color depth:
int colourDepth = Screen.PrimaryScreen.BitsPerPixel; PixelFormat format; switch (colourDepth) { case 8: case 16: format = PixelFormat.Format16bppRgb565; break;
case 24: format = PixelFormat.Format24bppRgb; break;
case 32: format = PixelFormat.Format32bppArgb; break;
default: format = PixelFormat.Format32bppArgb; break; } Bitmap bm = new Bitmap(captureWidth, captureHeight, format);
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
CRect rect; GetClientRect(rect);
rect.NormalizeRect(); if(rect.IsRectEmpty() || rect.IsRectNull()) return;
CClientDC dcScrn(this); CDC memDc; if(!memDc.CreateCompatibleDC(&dcScrn)) return; CBitmap bitmap; if( !bitmap.CreateCompatibleBitmap(&dcScrn,rect.Width(), rect.Height())) return; CBitmap* pOldBitmap = memDc.SelectObject(&bitmap); memDc.BitBlt(0,0,rect.Width(),rect.Height(),&dcScrn,rect.left , rect.top ,SRCCOPY ); if(OpenClipboard()) { EmptyClipboard(); SetClipboardData(CF_BITMAP,bitmap.GetSafeHandle()); CloseClipboard(); } memDc.SelectObject(pOldBitmap);
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi i got a problem in using the code. I put in inside a loop where it will open and close the page to get the pages but in the long time run the open and closing of the page will become slow. and a message will say that it close because of out of memory. how can i fix this one?
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
This does EXACTLY what I needed it to do!
I would ask one little favor: Can it be updated to not dither (or antialias) the images? Some of the fine details are lost by the dithering process and they end up fuzzy, especially small-font text. (I've tried all supplied resolutions and sizes, but to no avail.) ---------------------------------------------------------------------- Also: For those of you who are experiencing black images, I simply solved it by first running the image capture, then bring IE to the foreground, and then run the web page capture from the taskbar.
|
| Sign In·View Thread·PermaLink | 1.00/5 (1 vote) |
|
|
|
 |
|
 |
I was able to clean up dithering/aliasing quite a bit making the default bmp transparent adding bm.MakeTransparent(); to the innermost for loop.
So including some modifications mentioned elsewhere in the forum for the memory leak, the inner loop now looks like this:
for (int i = myPage; i >= 0; --i) {
//Shoot visible window g = Graphics.FromImage(bm); hdc = g.GetHdc(); setDocumentAttribute(myDoc, "scrollTop", (screenHeight - 5) * i); brwTop = (int)getDocumentAttribute(myDoc, "scrollTop"); PrintWindow(hwnd, hdc, 0); g.ReleaseHdc(hdc); g.Flush(); IntPtr hBitmap = bm.GetHbitmap(); bm.MakeTransparent();
screenfrag = Image.FromHbitmap(hBitmap); DeleteObject(hBitmap); g2.DrawImage(screenfrag, brwLeft + URLExtraLeft, brwTop + URLExtraHeight);
}
Also, at the end I skipped all the encoding part and just saved (per another recommendation) with bm2.Save("c:\\mypage.bmp", ImageFormat.Bmp); and that accomplished my goal.
Good luck!
Omar
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Hi,
We are getting images in IE7.0 but getting black images in IE6.0. If you have any work around for this it would be appreciated. (we have to get images in both IE6 and IE7)
Thanks, Kris.
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|