private static Bitmap capture(WebBrowser source, IntPtr hwnd) { HtmlDocument htmlDocument = source.Document; HtmlElement htmlElement = htmlDocument.Body; Rectangle rectangle = new Rectangle(new Point(0, 0), htmlElement.ScrollRectangle.Size); Bitmap image = new Bitmap(rectangle.Size.Width, rectangle.Size.Height, Graphics.FromHwnd(hwnd)); using (Graphics graphics = Graphics.FromImage(image)) { IOleObject oleObject = (IOleObject)htmlDocument.DomDocument; if (oleObject != null) { IntPtr imageDC = graphics.GetHdc(); IntPtr pUnk = Marshal.GetIUnknownForObject(source.ActiveXInstance); try { Size currentSize = new Size(); oleObject.GetExtent(DVASPECT.DVASPECT_CONTENT, out currentSize); Size drawingSize = convertPixelToHIMETRIC(rectangle.Size, imageDC); oleObject.SetExtent(DVASPECT.DVASPECT_CONTENT, ref drawingSize); OleDraw(pUnk, DVASPECT.DVASPECT_CONTENT, imageDC, ref rectangle); oleObject.SetExtent(DVASPECT.DVASPECT_CONTENT, ref currentSize); } finally { Marshal.Release(pUnk); graphics.ReleaseHdc(imageDC); } } graphics.Dispose(); } return(image); }
/// <summary> /// コンテンツサイズを調整する /// スクロールバーを非表示にするとスクロールしなくなるので表示域の外に追い出す /// </summary> /// <param name="isShowBar">スクロールバー有無</param> private void SetContentsSize(bool isShowBar) { if (this.FindForm() == null) { return; } if (this.FindForm().WindowState == FormWindowState.Minimized) { return; } if (isSetScrollBar != isShowBar || isZoomUpdate) { isSetScrollBar = isShowBar; try { // ボディー部を取得 HtmlDocument htmlDoc = Document; if (htmlDoc == null) { throw new NullReferenceException(); } HtmlElement element = htmlDoc.Body; if (element == null) { throw new NullReferenceException(); } IOleObject oleObj = (IOleObject)htmlDoc.DomDocument; if (oleObj == null) { throw new NullReferenceException(); } // スクロール位置を記憶 Point scrOrg = new Point(); scrOrg.X = element.Parent.ScrollLeft; scrOrg.Y = element.Parent.ScrollTop; Graphics g = CreateGraphics(); IntPtr dc = g.GetHdc(); double z = zoomRate; if (zoomAdjustment) { z = (double)(int)((z + 12.5) / 25) * 25; if (z < 25) { z = 25; } } Size ctlSize = new Size((int)(((double)(this.Size.Width * 100)) / zoomRate), (int)(((double)(this.Size.Height * 100)) / zoomRate)); Size curSize = PixelToHIMETRIC(ctlSize, dc); Size barSize = new Size((int)(((double)(SystemInformation.VerticalScrollBarWidth * 1.5) * 100) / zoomRate), (int)(((double)(SystemInformation.HorizontalScrollBarHeight * 1.5) * 100) / zoomRate)); Size ofsSize = PixelToHIMETRIC(barSize, dc); if (!scrollBarsEnabled) { curSize.Width += ofsSize.Width; curSize.Height += ofsSize.Height; } g.ReleaseHdc(dc); g.Dispose(); try { // コンテンツサイズ設定 oleObj.SetExtent(DVASPECT.DVASPECT_CONTENT, ref curSize); // スクロール位置を戻す SetPosition(scrOrg); } catch (System.Runtime.InteropServices.COMException) { // 失敗 - 何もしない } } catch (NullReferenceException) { // OK } catch (Exception es) { ThreadExceptionDialog ed = new ThreadExceptionDialog(es); ed.ShowDialog(); } } }
/// <summary> /// コンテンツキャプチャ /// </summary> private void GetCaptureImageInternal() { if (InvokeRequired) { // 別スレッドから呼び出された場合 Invoke(new GetCaptureImageInternalDelegate(GetCaptureImageInternal)); return; } Bitmap rt = null; Size curSize; try { #region コンテンツのボディー部を取得 HtmlDocument htmlDoc = Document; if (htmlDoc == null) { throw new NullReferenceException(); } HtmlElement element = htmlDoc.Body; if (element == null) { throw new NullReferenceException(); } IOleObject oleObj = (IOleObject)htmlDoc.DomDocument; if (oleObj == null) { throw new NullReferenceException(); } #endregion #region コンテンツの情報を記憶 // スクロール位置を記憶 Point scrOrg = new Point(); scrOrg.X = element.Parent.ScrollLeft; scrOrg.Y = element.Parent.ScrollTop; #endregion #region コンテンツをキャプチャ用に調整 // 一時的に拡大率を変更する if (zoomNowRate != captureZoomRate) { SHDocVw.IWebBrowser2 browser = (SHDocVw.IWebBrowser2)ActiveXInstance; object izoom = (Int32)captureZoomRate; object ozoom = (Int32)0; browser.ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref izoom, ref ozoom); } // コンテンツサイズ計算(スクロールバー分大きくする) oleObj.GetExtent(DVASPECT.DVASPECT_CONTENT, out curSize); Rectangle conRect = new Rectangle(0, 0, (int)(element.ScrollRectangle.Size.Width * captureZoomRate / 100 + 0.5), (int)(element.ScrollRectangle.Size.Height * captureZoomRate / 100 + 0.5) ); conRect.Width += SystemInformation.VerticalScrollBarWidth; conRect.Height += SystemInformation.HorizontalScrollBarHeight; #endregion if (captureDrawMode == CaptureDrawModes.OleDraw) { rt = new Bitmap(conRect.Width, conRect.Height); } else { rt = new Bitmap(this.Size.Width, this.Size.Height); } Graphics g = Graphics.FromImage(rt); IntPtr dc = g.GetHdc(); try { #region コンテンツ全体をキャプチャ switch (captureDrawMode) { case CaptureDrawModes.OleDraw: #region OleDrawによるキャプチャ { IntPtr pUnk = Marshal.GetIUnknownForObject(ActiveXInstance); try { // コンテンツ描画範囲をコンテンツサイズに設定 Size drawSize = PixelToHIMETRIC(conRect.Size, dc); oleObj.SetExtent(DVASPECT.DVASPECT_CONTENT, ref drawSize); // 描画 OleDraw(pUnk, DVASPECT.DVASPECT_CONTENT, dc, ref conRect); } catch (Exception es) { ThreadExceptionDialog ed = new ThreadExceptionDialog(es); ed.ShowDialog(); } finally { Marshal.Release(pUnk); } } #endregion break; case CaptureDrawModes.PrintWindow: #region PrintWindowによるキャプチャ { // 表示サイズで取得 PrintWindow(Handle, dc, 0); } #endregion break; } #endregion } catch (Exception es) { ThreadExceptionDialog ed = new ThreadExceptionDialog(es); ed.ShowDialog(); } finally { g.ReleaseHdc(dc); g.Dispose(); } #region コンテンツを元に戻す // 拡大率とコンテンツサイズを戻す if (zoomNowRate != captureZoomRate) { SHDocVw.IWebBrowser2 browser = (SHDocVw.IWebBrowser2)ActiveXInstance; object izoom = (Int32)zoomNowRate; object ozoom = (Int32)0; browser.ExecWB(SHDocVw.OLECMDID.OLECMDID_OPTICAL_ZOOM, SHDocVw.OLECMDEXECOPT.OLECMDEXECOPT_DODEFAULT, ref izoom, ref ozoom); } oleObj.SetExtent(DVASPECT.DVASPECT_CONTENT, ref curSize); // スクロール位置を戻す SetPosition(scrOrg); #endregion } catch (NullReferenceException) { if (rt == null) { rt = new Bitmap(1, 1); } } catch (Exception es) { ThreadExceptionDialog ed = new ThreadExceptionDialog(es); ed.ShowDialog(); } imageOrigin = rt; }