[MarshalAs(UnmanagedType.U2)]
public short tdDriverNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdDeviceNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdPortNameOffset;
[MarshalAs(UnmanagedType.U2)]
public short tdExtDevmodeOffset;
[StructLayout(LayoutKind.Sequential)]
public class COMRECT
public int left;
public int top;
public int right;
public int bottom;
public COMRECT()
public COMRECT(Rectangle r)
this.left = r.X;
this.top = r.Y;
this.right = r.Right;
this.bottom = r.Bottom;
public COMRECT(int left, int top, int right, int bottom)
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
public static NativeMethods.COMRECT FromXYWH(int x, int y, int width, int height)
return new NativeMethods.COMRECT(x, y, x + width, y + height);
public override string ToString()
return string.Concat(new object[] { "Left = ", this.left, " Top ", this.top, " Right = ", this.right, " Bottom = ", this.bottom });
[StructLayout(LayoutKind.Sequential)]
public sealed class tagLOGPALETTE
[MarshalAs(UnmanagedType.U2)]
public short palVersion;
[MarshalAs(UnmanagedType.U2)]
public short palNumEntries;
UnsafeNativeMethods.cs:
程序代码using System;
using System.Collections.Generic;
using System.Text;
using System.Security;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace WindowsApplication1
///
/// 从 .Net 2.0 的 System.Windows.Forms.Dll 库提取
///
[SuppressUnmanagedCodeSecurity]
internal static class UnsafeNativeMethods
public static Guid IID_IViewObject = new Guid("{0000010d-0000-0000-C000-000000000046}");
[ComImport, Guid("0000010d-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IViewObject
[PreserveSig]
int Draw([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] NativeMethods.tagDVTARGETDEVICE ptd, IntPtr hdcTargetDev, IntPtr hdcDraw, [In] NativeMethods.COMRECT lprcBounds, [In] NativeMethods.COMRECT lprcWBounds, IntPtr pfnContinue, [In] int dwContinue);
[PreserveSig]
int GetColorSet([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [In] NativeMethods.tagDVTARGETDEVICE ptd, IntPtr hicTargetDev, [Out] NativeMethods.tagLOGPALETTE ppColorSet);
[PreserveSig]
int Freeze([In, MarshalAs(UnmanagedType.U4)] int dwDrawAspect, int lindex, IntPtr pvAspect, [Out] IntPtr pdwFreeze);
[PreserveSig]
int Unfreeze([In, MarshalAs(UnmanagedType.U4)] int dwFreeze);
void SetAdvise([In, MarshalAs(UnmanagedType.U4)] int aspects, [In, MarshalAs(UnmanagedType.U4)] int advf, [In, MarshalAs(UnmanagedType.Interface)] IAdviseSink pAdvSink);
void GetAdvise([In, Out, MarshalAs(UnmanagedType.LPArray)] int[] paspects, [In, Out, MarshalAs(UnmanagedType.LPArray)] int[] advf, [In, Out, MarshalAs(UnmanagedType.LPArray)] IAdviseSink[] pAdvSink);
Snapshot.cs:
程序代码using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsApplication1
///
/// ActiveX 组件快照类
/// AcitveX 必须实现 IViewObject 接口
/// 作者:随飞
/// http://chinasf.cnblogs.com
/// chinasf@hotmail.com
///
public class Snapshot
///
/// 取快照
///
///
Com 对象
///
图象大小
///
public Bitmap TakeSnapshot(object pUnknown, Rectangle bmpRect)
if (pUnknown == null)
return null;
//必须为com对象
if (!Marshal.IsComObject(pUnknown))
return null;
//IViewObject 接口
UnsafeNativeMethods.IViewObject ViewObject = null;
IntPtr pViewObject = IntPtr.Zero;
//内存图
Bitmap pPicture = new Bitmap(bmpRect.Width, bmpRect.Height);
Graphics hDrawDC = Graphics.FromImage(pPicture);
//获取接口
object hret = Marshal.QueryInterface(Marshal.GetIUnknownForObject(pUnknown),
ref UnsafeNativeMethods.IID_IViewObject, out pViewObject);
ViewObject = Marshal.GetTypedObjectForIUnknown(pViewObject, typeof(UnsafeNativeMethods.IViewObject)) as UnsafeNativeMethods.IViewObject;
//调用Draw方法
ViewObject.Draw((int)DVASPECT.DVASPECT_CONTENT,
IntPtr.Zero,
null,
IntPtr.Zero,
hDrawDC.GetHdc(),
new NativeMethods.COMRECT(bmpRect),
null,
IntPtr.Zero,
Marshal.Release(pViewObject);
catch (Exception ex)
Console.WriteLine(ex.Message);
throw ex;
hDrawDC.Dispose();
return pPicture;
使用语法如下:
程序代码Snapshot snap = new Snapshot();
using (Bitmap bitmap = snap.TakeSnapshot(webBrowser.ActiveXInstance, new Rectangle(0, 0, picWidth, picHeight)))
bitmap.Save(savepath, picType);
好了,修改下上次的WebCapture类:
WebCapture.cs:
程序代码using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.IO;
namespace WindowsApplication1
public class WebCapture
#region 字段、属性
private int width = 0;
private int height = 0;
private string url;
private WebBrowser browser = new WebBrowser();
///
/// 属性:图片宽
///
public int Width { get { return width; } }
///
/// 属性:图片高
///
public int Height { get { return height; } }
///
/// 属性:Url
///
public string Url { get { return url; } }
#endregion
#region 构造函数
///
/// 构造函数
///
public WebCapture()
this.url = "http://www.mzwu.com/";
///
/// 构造函数
///
///
Url
public WebCapture(string url)
this.url = url;
#endregion
///
/// 保存图片
///
///
保存路径
///
public void Save(string destpath)
Save(this.url, destpath, this.width, this.height);
///
/// 保存图片
///
///
Url
///
保存路径
///
public void Save(string url, string destpath)
Save(url, destpath, this.width, this.height);
///
/// 保存图片
///
///
Url
///
保存路径
///
图片宽
///
图片高
///
///
width,height为0时获取完整大小
public void Save(string url, string destpath, int width, int height)
ImageFormat picType;
//图片格式
switch (Path.GetExtension(destpath).ToLower())
case ".gif":
picType = System.Drawing.Imaging.ImageFormat.Gif;
break;
case ".jpg":
case ".jpeg":
picType = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
case ".png":
picType = System.Drawing.Imaging.ImageFormat.Png;
break;
case ".bmp":
picType = System.Drawing.Imaging.ImageFormat.Bmp;
break;
default:
picType = System.Drawing.Imaging.ImageFormat.Jpeg;
break;
//抓取图片
InitComobject(url);//初始化窗体
int scrollWidth = this.browser.Document.Body.ScrollRectangle.Width;
int scrollHeight = this.browser.Document.Body.ScrollRectangle.Height;
this.browser.Width = scrollWidth;
this.browser.Height = scrollHeight;
if (width == 0) width = scrollWidth;
if (height == 0) height = scrollHeight;
//核心语句
Snapshot snap = new Snapshot();
using (Bitmap bitmap = snap.TakeSnapshot(this.browser.ActiveXInstance, new Rectangle(0, 0, width, height)))
bitmap.Save(destpath, picType);
browser.Dispose();
///
/// 初始化
///
///
protected void InitComobject(string url)
this.browser.ScriptErrorsSuppressed = false;
this.browser.ScrollBarsEnabled = false;
this.browser.Navigate(url);
//因为没有窗体,所以必须如此
while (this.browser.ReadyState != WebBrowserReadyState.Complete)
System.Windows.Forms.Application.DoEvents();
this.browser.Stop();
if (this.browser.ActiveXInstance == null)
throw new Exception("实例不能为空");
使用示例:
程序代码new WebCapture().Save("http://www.531.hk/", @"C:/531.hk.jpg");
先定义三个重要的类NativeMethods、UnsafeNativeMethods和Snapshot:NativeMethods.cs: 程序代码using System;using System.Collections.Generic;using System.Text;using System.Runtime.InteropServices;using System.Drawing;namespace WindowsApplication1{
1.生成
webview
页面的
截图
ImageUtils
mBitmap = mImageUtils.
capture
View(m
WebView
);
public
class
ImageUtils {
public Bitmap
capture
View(View view){
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
// 重新测量一遍View的宽高
view.
第一种方式通过调用
webview
.
capture
Picture(),得到一个picture对象,根据图像的宽和高创建一个Bitmap,再创建一个canvas,绑定bitmap,最后用picture去绘制。//获取Picture对象
Picture picture = wv_
capture
.
capture
Picture();
//得到图片的宽和高(没有reflect图片内容)
int width =
using Microsoft.
Web
.
WebView
2.WinForms;
private
async
void FMTEST_Load
Async
(object sender, EventArgs e)
webView
21.Source = new Uri("https://blog.csdn.net/ccagy");
await
webView
21.Ensu...
Gets the height of the HTML content.
获取到的是 html 内容的高度,但是这个值的单位不是 px,而是 dp,所以不能直接拿来就用,需要先转换成 px,后面再说。
webview
.getWidth()...
public void printPDF() {
String
name =
webView
.getTitle() + ".pdf";
PrintManager printManager = (PrintManager) getActivity().getSystemService(Context.PRINT_SERVICE);
PrintAttributes.Builder builder = new PrintAttributes.Builder();
builder..
在
C#
中,可以使用 Object
类
的 Clone 方法来实现克隆实体
类
。但是,需要注意的是,Object
类
的 Clone 方法只实现了浅拷贝,即对于
类
中的引用
类
型,只是拷贝了引用,而没有拷贝引用指向的对象。如果需要实现深拷贝,需要手动实现 Clone 方法。
以下是一个示例代码,演示了如何实现一个 Employee
类
的克隆方法:
```csharp
public
class
Employee : ICloneable
public
string
Name { get; set; }
public int Age { get; set; }
public Department Department { get; set; }
public object Clone()
Employee clone = (Employee)this.MemberwiseClone();
clone.Department = (Department)this.Department.Clone();
return clone;
public
class
Department : ICloneable
public
string
Name { get; set; }
public object Clone()
return this.MemberwiseClone();
在上面的示例中,Employee
类
实现了 ICloneable 接口,并重写了 Clone 方法。在 Clone 方法中,首先调用了 MemberwiseClone 方法来实现浅拷贝,然后对于 Department 属性,手动调用了其 Clone 方法,实现了深拷贝。这样就可以实现 Employee
类
的克隆操作了。