<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html"><![CDATA[51海派软件]]></title>
  <subtitle type="html"><![CDATA[C# .NET  技术论文 源码 控件 程序 软件发布]]></subtitle>
  <id>http://blog.51haipai.com/</id>
  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/" /> 
  <link rel="self" type="application/atom+xml" href="http://blog.51haipai.com/atom.asp" /> 
  <generator uri="http://www.pjhome.net/" version="2.8">PJBlog3</generator> 
  <updated>2010-01-25T14:28:08+08:00</updated>

  <entry>
	  <title type="html"><![CDATA[[.NET开发]C# WinForm制作异形窗体/控件 ]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2010-01-25T14:28:08+08:00</updated>
	  <published>2010-01-25T14:28:08+08:00</published>
		  <summary type="html"><![CDATA[制作异形窗体或控件的思路一般都是想办法生成一个region，然后设置给指定的窗口或控件。生成region的方法有很多，最常用的就是从一幅图片生成，把该图片中的透明色部分“抠”掉，剩下的部分作为一个region。设置窗口或控件的region可以用SetWindowRgn API，不过.NET framework封装了这个操作，在C#中只要对窗口或控件的Region属性赋值就可以了。下面我就把我在C#中实现异形窗体的核心代码贴出来给大家看看，有什么意见尽管提，别客气哦J<br/><br/> <br/><br/>首先，是一个根据Bitmap对象生成Region的方法：<br/><br/>/// &lt;summary&gt;<br/><br/>/// 取得一个图片中非透明色部分的区域。<br/><br/>/// &lt;/summary&gt;<br/><br/>/// &lt;param name=&#34;Picture&#34;&gt;取其区域的图片。&lt;/param&gt;<br/><br/>/// &lt;param name=&#34;TransparentColor&#34;&gt;透明色。&lt;/param&gt;<br/><br/>/// &lt;returns&gt;图片中非透明色部分的区域&lt;/returns&gt;<br/><br/>private Region BmpRgn(Bitmap Picture, Color TransparentColor)<br/><br/>{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; int nWidth = Picture.Width;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; int nHeight = Picture.Height;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; Region rgn = new Region();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; rgn.MakeEmpty();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; bool isTransRgn;//前一个点是否在透明区<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; Color curColor;//当前点的颜色<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; Rectangle curRect = new Rectangle();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; curRect.Height = 1;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; int x = 0, y = 0;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; //逐像素扫描这个图片，找出非透明色部分区域并合并起来。<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; for(y = 0; y &lt; nHeight; ++y)<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; {<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isTransRgn = true;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (x = 0; x &lt; nWidth; ++x)<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curColor = Picture.GetPixel(x,y);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(curColor == TransparentColor || x == nWidth - 1)//如果遇到透明色或行尾<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(isTransRgn == false)//退出有效区<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curRect.Width = x - curRect.X;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rgn.Union(curRect);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else//非透明色<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(isTransRgn == true)//进入有效区<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curRect.X = x;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;curRect.Y = y;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//if curColor<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; isTransRgn = curColor == TransparentColor;&nbsp;&nbsp;&nbsp;&nbsp; <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}//for x<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }//for y<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return rgn;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp; }<br/><br/> <br/><br/>原理很简单，就是对该图片逐行扫描，在每一行中把那些非透明色的矩形（只有一个像素高）合并（union）到一个Region对象中，当扫描完整个图片，得到的也就是我们想要的Region了。这种算法在很多文章里都有介绍的。<br/><br/> <br/><br/>有了region，下面就简单了：<br/><br/>this.Region = BmpRgn(new Bitmap(&#34;d:\\a.bmp&#34;), Color.FromArgb(0, 0, 0));<br/><br/>上面的代码就是把d:\a.bmp的轮廓作为主窗口的region的，假设该图片的背景黑色（Color.FromArgb(0, 0, 0）)。<br/><br/>其实不光是Form，任何控件都可以用这个方法设置Region，制作出异形控件。<br/><br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=40" /> 
	  <id>http://blog.51haipai.com/default.asp?id=40</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[在程序中加载解析3DS文件，显示三维模型（c# MDX）， ]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2010-01-22T13:23:46+08:00</updated>
	  <published>2010-01-22T13:23:46+08:00</published>
		  <summary type="html"><![CDATA[在程序中加载解析3DS文件，显示三维模型（c# MDX），<br/><br/>把3ds转化为x文件后有很多问题（试了好多转换工具都不行，如果你有好工具别忘了告诉我），因此决心直接解析3DS文件然后用mesh显示。 <br/>解析3DS文件网上有好多代码，但我就只找到一个是C#写的，C#的太多资源仍然稀缺啊<br/><a href="http://www.nabble.com/3DS-File-loader-t1663534.html" target="_blank" rel="external">http://www.nabble.com/3DS-File-loader-t1663534.html</a><br/><br/>它是用OpenGL显示的，我还得把它移植到MDX上来。<br/>（C++写的解析显示3DS的代码，目前我只找到了几个opengl的，没找到directx的，如果你知道不要忘了告诉我啊）<br/>还有许多细节上的问题…………<br/><br/>全部的源代码：<a href="http://bbs.gameres.com/showthread.asp?page=end" target="_blank" rel="external">http://bbs.gameres.com/showthread.asp?page=end</a>&amp;threadid=83967<br/><br/>代码仅Form1.cs是我写的，其他的是来自（<a href="http://www.nabble.com/3DS-File-loader-t1663534.html" target="_blank" rel="external">http://www.nabble.com/3DS-File-loader-t1663534.html</a>），仅有少许修改。<br/><br/>当前的显示还有一些问题，有一些三角形显示不出来，又有一些三角形是多余的，可是我的顶点和索引解析不会有问题呀，郁闷，期待大家一起帮忙完善。<br/><br/><span style="color:Red"><strong>源码下载地址</strong></span>：<a target="_blank" href="http://down.qiannao.com/space/file/ufo1199078/share/2010/1/22/sf_2007523161027.rar/.page" rel="external">下载</a><br/><br/>Form1.cs<br/><br/>using System;<br/>using System.Drawing;<br/>using System.Collections;<br/>using System.ComponentModel;<br/>using System.Windows.Forms;<br/>using System.Data;<br/>using Microsoft.DirectX;<br/>using Microsoft.DirectX.Direct3D;<br/><br/>namespace ThreeD<br/>{<br/>/// &lt;summary&gt;<br/>/// Summary description for Form1.<br/>/// &lt;/summary&gt;<br/>public class Form1 : System.Windows.Forms.Form<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private Device device = null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private Mesh mesh = null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private Material[] meshMaterials;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private Texture[] meshTextures;<br/><br/>/// &lt;summary&gt;<br/>/// Required designer variable.<br/>/// &lt;/summary&gt;<br/>private System.ComponentModel.Container components = null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private float angle = 0.0f;<br/><br/>public Form1()<br/>{<br/>//<br/>// Required for Windows Form Designer support<br/>//<br/>InitializeComponent();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.Opaque, true);<br/>}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// We will initialize our graphics device here<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void InitializeGraphics()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Set our presentation parameters<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PresentParameters presentParams = new PresentParameters();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;presentParams.Windowed = true;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;presentParams.SwapEffect = SwapEffect.Discard;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;presentParams.AutoDepthStencilFormat = DepthFormat.D16;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;presentParams.EnableAutoDepthStencil = true;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Cr&#101;ate our device<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device = new Device(0, DeviceType.Hardware, this, Cr&#101;ateFlags.SoftwareVertexProcessing, presentParams);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load our mesh<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//LoadMesh(@&#34;..\..\tiny.x&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//LoadD3S(@&#34;E:\myprog\MeshFile\tpot.3ds&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LoadD3S(@&#34;E:\myprog\box.3ds&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private void LoadMesh(string file)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExtendedMaterial[] mtrl;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load our mesh<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// If we have any materials, store them<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((mtrl != null) &amp;&amp; (mtrl.Length &gt; 0))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials = new Material[mtrl.Length];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshTextures = new Texture[mtrl.Length];<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Store each material and texture<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; mtrl.Length; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials[i] = mtrl[i].Material3D;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((mtrl[i].TextureFilename != null) &amp;&amp; (mtrl[i].TextureFilename != string.Empty))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// We have a texture, try to load it<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshTextures[i] = TextureLoader.FromFile(device, @&#34;..\..\&#34; + mtrl[i].TextureFilename);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private void LoadD3S(string file)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * mesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// If we have any materials, store them<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((mtrl != null) &amp;&amp; (mtrl.Length &gt; 0))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials = new Material[mtrl.Length];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshTextures = new Texture[mtrl.Length];<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Store each material and texture<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; mtrl.Length; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials[i] = mtrl[i].Material3D;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((mtrl[i].TextureFilename != null) &amp;&amp; (mtrl[i].TextureFilename != string.Empty))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// We have a texture, try to load it<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshTextures[i] = TextureLoader.FromFile(device, @&#34;..\..\&#34; + mtrl[i].TextureFilename);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}*/<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ExtendedMaterial[] mtrl;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Model model = new ThreeDSFile(file).ThreeDSModel;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Entity e = model.Entities[0];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int numberVerts = e.vertices.Length;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mesh = new Mesh(numberVerts * 3, numberVerts, MeshFlags.Managed,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CustomVertex.PositionNormal.Format, device);<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using (IndexBuffer ib = mesh.IndexBuffer)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ib.SetData(e.indices, 0, LockFlags.None);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using (VertexBuffer vb = mesh.VertexBuffer)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GraphicsStream data = vb.Lock(0, 0, LockFlags.None);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//for(int i2=0;i2&lt;e.vertices.Length;i2++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int i2=0;i2&lt;numberVerts;i2++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;data.Write<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(new CustomVertex.PositionNormal<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(float)e.vertices[i2].X,(float)e.vertices[i2].Y, (float)e.vertices[i2].Z,<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(float)e.normals[i2].X, (float)e.normals[i2].Y, (float)e.normals[i2].Z<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;vb.Unlock();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials = new Material[1];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshTextures = new Texture[1];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*meshMaterials[0].Ambient = e.material.Ambient;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials[0].Diffuse = e.material.Diffuse;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials[0].Emissive = e.material.Shininess;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials[0].Specular = e.material.Specular;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials[0].Ambient = Color.FromArgb((int)e.material.Ambient[0], (int)e.material.Ambient[1], (int)e.material.Ambient[2]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials[0].Diffuse = Color.FromArgb((int)e.material.Diffuse[0], (int)e.material.Diffuse[1], (int)e.material.Diffuse[2]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//meshMaterials[0].Emissive = e.material.Shininess;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;meshMaterials[0].Specular = Color.FromArgb((int)e.material.Specular[0], (int)e.material.Specular[1], (int)e.material.Specular[2]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Load our mesh<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/*Model model = new ThreeDSFile(file).ThreeDSModel;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; model.Entities.Count; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Entity e = model.Entities[i];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for(int i2=0;i2&lt;e.indices.Length;i2++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;e.indices[i2].vertex1;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;model.Entities.<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * */<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private void SetupCamera()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.RenderState.CullMode = Cull.None;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Transform.Projection = Matrix.PerspectiveFovLH((float)Math.PI / 4, this.Width / this.Height, 1.0f, 10000.0f);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Transform.View = Matrix.LookAtLH(new Vector3(0,0, 580.0f), new Vector3(), new Vector3(0,1,0));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//device.RenderState.Ambient = Color.DarkBlue;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Lights[0].Type = LightType.Directional;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Lights[0].Diffuse = Color.White;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Lights[0].Direction = new Vector3(0, -1, -1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//device.Lights[0].Commit();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Lights[0].Enabled = true;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;protected override void OnPaint(System.Windows.Forms.PaintEventArgs e)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.CornflowerBlue, 1.0f, 0);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetupCamera();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.BeginScene();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Draw our Mesh<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DrawMesh(angle / (float)Math.PI, angle / (float)Math.PI * 2.0f, angle / (float)Math.PI / 4.0f, 0.0f, 0.0f, 0.0f);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.EndScene();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Present();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Invalidate();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private void DrawMesh(float yaw, float pitch, float roll, float x, float y, float z)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;angle += 0.1f;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Transform.World = Matrix.RotationYawPitchRoll(yaw, pitch, roll) * Matrix.Translation(x, y, z);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; meshMaterials.Length; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Material boxMaterial = new Material();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boxMaterial.Ambient = Color.White;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;boxMaterial.Diffuse = Color.White;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;device.Material = boxMaterial;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//device.Material = meshMaterials[i];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//device.SetTexture(0, meshTextures[i]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mesh.DrawSubset(i);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>/// Clean up any resources being used.<br/>/// &lt;/summary&gt;<br/>protected override void Dispose( bool disposing )<br/>{<br/>if( disposing )<br/>{<br/>if (components != null) <br/>{<br/>components.Dispose();<br/>}<br/>}<br/>base.Dispose( disposing );<br/>}<br/><br/>#region Windows Form Designer generated code<br/>/// &lt;summary&gt;<br/>/// Required method for Designer support - do not modify<br/>/// the contents of this method with the code editor.<br/>/// &lt;/summary&gt;<br/>private void InitializeComponent()<br/>{<br/>this.components = new System.ComponentModel.Container();<br/>this.Size = new Size(800,600);<br/>this.Text = &#34;Form1&#34;;<br/>}<br/>#endregion<br/><br/>/// &lt;summary&gt;<br/>/// The main entry point for the application.<br/>/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main() <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using (Form1 frm = new Form1())<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Show our form and initialize our graphics engine<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frm.Show();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;frm.InitializeGraphics();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Application.Run(frm);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/>}<br/><br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=39" /> 
	  <id>http://blog.51haipai.com/default.asp?id=39</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[AES加密解密 Web版及程序版]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2010-01-12T16:24:34+08:00</updated>
	  <published>2010-01-12T16:24:34+08:00</published>
		  <summary type="html"><![CDATA[<br/><img src="http://www.yongfa365.com/software/Projects/AES加密解密工具.gif" border="0" alt=""/><br/><br/>软件功能：可用来加密任何文本，只要别人不知道你的密码，基本上他是暴力破解不了的，所以呀，机器上那些想保密的东西都用来加密吧，嘎嘎<br/><br/>Web版地址：<a href="http://www.yongfa365.com/Tools/AES/Default.aspx" target="_blank" rel="external">http://www.yongfa365.com/Tools/AES/Default.aspx</a><br/><br/>AES高级加密标准　密码学中的高级加密标准，是美国联邦政府采用的一种区块加密标准。<br/><br/> <br/><br/>主要代码：<br/><br/>view plaincopy to clipboardprint?<br/>using System;&nbsp;&nbsp; <br/>using System.Text;&nbsp;&nbsp; <br/>using System.Security.Cryptography;&nbsp;&nbsp; <br/>using System.IO;&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>namespace YongFa365.Security&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;SUMMARY&gt;&lt;/SUMMARY&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;/// AES加密解密&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;///&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;public class AES&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static string Encrypt(string strEncrypt, string strKey)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] keyArray = UTF8Encoding.UTF8.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strKey, &#34;md5&#34;));&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] strEncryptArray = UTF8Encoding.UTF8.GetBytes(strEncrypt);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] resultArray = null;&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using (RijndaelManaged rDel = new RijndaelManaged())&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Key = keyArray;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Mode = CipherMode.ECB;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Padding = PaddingMode.PKCS7;&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ICryptoTransform cTransform = rDel.Cr&#101;ateEncryptor();&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resultArray = cTransform.TransformFinalBlock(strEncryptArray, 0, strEncryptArray.Length);&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Convert.ToBase64String(resultArray, 0, resultArray.Length);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static string Decrypt(string strDecrypt, string strKey)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] keyArray = UTF8Encoding.UTF8.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strKey, &#34;md5&#34;));&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] strDecryptArray = Convert.FromBase64String(strDecrypt);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] resultArray = null;&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using (RijndaelManaged rDel = new RijndaelManaged())&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Key = keyArray;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Mode = CipherMode.ECB;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Padding = PaddingMode.PKCS7;&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ICryptoTransform cTransform = rDel.Cr&#101;ateDecryptor();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resultArray = cTransform.TransformFinalBlock(strDecryptArray, 0, strDecryptArray.Length);&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return UTF8Encoding.UTF8.GetString(resultArray);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>}&nbsp;&nbsp;<br/><br/>using System;<br/>using System.Text;<br/>using System.Security.Cryptography;<br/>using System.IO;<br/><br/>namespace YongFa365.Security<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// <br/>&nbsp;&nbsp;&nbsp;&nbsp;/// AES加密解密<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// <br/>&nbsp;&nbsp;&nbsp;&nbsp;public class AES<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static string Encrypt(string strEncrypt, string strKey)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] keyArray = UTF8Encoding.UTF8.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strKey, &#34;md5&#34;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] strEncryptArray = UTF8Encoding.UTF8.GetBytes(strEncrypt);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] resultArray = null;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using (RijndaelManaged rDel = new RijndaelManaged())<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Key = keyArray;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Mode = CipherMode.ECB;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Padding = PaddingMode.PKCS7;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ICryptoTransform cTransform = rDel.Cr&#101;ateEncryptor();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resultArray = cTransform.TransformFinalBlock(strEncryptArray, 0, strEncryptArray.Length);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return Convert.ToBase64String(resultArray, 0, resultArray.Length);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static string Decrypt(string strDecrypt, string strKey)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] keyArray = UTF8Encoding.UTF8.GetBytes(System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(strKey, &#34;md5&#34;));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] strDecryptArray = Convert.FromBase64String(strDecrypt);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;byte[] resultArray = null;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;using (RijndaelManaged rDel = new RijndaelManaged())<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Key = keyArray;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Mode = CipherMode.ECB;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rDel.Padding = PaddingMode.PKCS7;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ICryptoTransform cTransform = rDel.Cr&#101;ateDecryptor();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;resultArray = cTransform.TransformFinalBlock(strDecryptArray, 0, strDecryptArray.Length);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return UTF8Encoding.UTF8.GetString(resultArray);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/>相关类及Demo下载地址：AES加密解密.rar<br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=38" /> 
	  <id>http://blog.51haipai.com/default.asp?id=38</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[共享软件加密的一些误区及防破解的实用招法]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2010-01-12T15:35:51+08:00</updated>
	  <published>2010-01-12T15:35:51+08:00</published>
		  <summary type="html"><![CDATA[先总结一下：<br/><br/>不要太相信注册表所以把注册码之类的敏感信息放在里边 <br/>不要调用系统时间看是不是试用期已过，可以调用一些系统文件的创建时间 <br/>不要将敏感信息以明文的形式写在程序中，防止直接十六进制查看 <br/>加密或验证部分与软件主体部分耦合度要高（虽然不便维护） <br/>不要对注册码进行明文比较，防内存补丁，至少md5后比较 <br/>不要将出错提示信息紧跟在加密判断之后，防直接查找字符串，快速定位破解 <br/>检查自己的进程的父进程是否为Explorer.exe，不是就Kill掉，甚至Kill自己 <br/>.net winform程序，最好先混淆，或加密，不然被轻易破解机率为100% <br/><br/>--------------------------------------------------------------------------------<br/><br/><br/> <br/><br/>共享软件加密的一些误区<br/>&nbsp;&nbsp;本文发表于《电脑软件编程与维护》 2005年12期<br/>&nbsp;&nbsp;作者：星轨（oRbIt）<br/>&nbsp;&nbsp;E_Mail ：inte2000@163.com&nbsp;&nbsp; <br/><br/>　　共享软件通常是指那种采用“先使用，后付款”的方式发布的软件，这类软件通常有两个（或多个）不同的版本，公开发布的是一个功能受限制或使用时间和次数受限制的共享版本，只有当用户购买（或注册）之后才可以使用没有限制的正式版本。共享软件从出现的那一天起就深受破解者（Cracker）的“喜爱”，因为相对于防范较为严密或使用硬件加密的商业软件来说，共享软件是比较容易破解的。虽然许多共享软件的作者也采用了时间限制或注册码校验等方法保护自己的软件，但是多数共享软件的作者对软件加密与解密技术不了解，对加密方法的应用和代码编写过程中存在许多漏洞，从而使看似很可靠的加密方法形同虚设。软件破解者（甚至是一些菜鸟级的Cracker）只需要参照网络上的破解教程，按图索骥，就能够去掉一些软件的使用限制，或从内存中抓出正确的注册码，破解高手甚至能够写出注册机，这无疑是宣告了这个软件的死刑。<br/><br/>　　本人也发布过共享软件，经历过软件刚刚发布就被破解的尴尬，痛定思痛之后，开始研究软件加密与解密之道。思之靡多，终有所悟，其实软件加密与解密之间的斗争，道高一尺则魔高一丈，但是最终往往不是技术致胜，而是心态致胜，从软件破解者的心态考虑加密问题，常常能够兵出奇处，以奇致胜。从软件破解者的角度考虑，以下是一些软件作者常犯的一些错误，本人把它们列举出来，希望对广大软件作者能有所帮助：<br/><br/>过分相信Windows注册表的复杂性<br/> <br/>　　注册表是Windows系统存储关于计算机配置信息的数据库，所有的数据都是通过一种树状结构以键和子键的方式组织起来，每个键都包含了一组特定的信息，通过键的名称和路径可以查询和修改这些信息。许多共享软件地作者都将一些比较重要的信息，比如注册信息或时间、次数限制存放在注册表中，以为注册表结构复杂，藏一些数据别人找不到。其实这是一个错误的认识，破解者利用一些注册表操作工具很容易就能获得数据在注册表中的存放位置。RegMon就是一款注册表监视软件，它能够监视系统中运行的程序对注册表的读写操作，一切诡秘在它面前都将大白于天下。还有一个名为RegSnap的软件，它的工作原理就是通过比较程序运行前后注册表的变化确定程序在注册表中的读写位置。由此可见，在注册表中存放信息是不安全的，至少要对存储的信息数据进行加密处理。<br/><br/>信息以明文的形式写在程序中<br/>　　C/C++语言的编译程序对代码中出现的字符串通常不作特殊地处理，直接将其按照数据出现的顺序排放在数据段中。一些软件作者没有注意到这一点，导致程序中使用的一些敏感信息以明文的形式出现在可执行程序中，比如注册表某个键的路径、某个文件路径以及加载的外部动态库名字等等。破解者使用WinHex之类的十六进制编辑软件打开程序文件就可以看到这些信息。图（1）就是用十六进制编辑器打开某软件的截图，从中可以看到这个软件可能动态加载了RegKey.dll这个动态库，可能还操作了注册表Software\Microsoft\Windows\ArtComp\RegInfo位置下的某些键。 <br/><br/><br/>图（1） 可执行文件中的字符串<br/> C/C++程序的设计者稍微修改一下代码就可以避免这种简单的信息泄露，比如字符串“RegKey”，可以在程序中这样声明字符串数据：<br/>static LPCTSTR lpszKey = _T(&#34;SfhLfz&#34;);<br/>其实就是将每个字母向后移了一位（数值上增加1），使用前稍作处理：<br/>TCHAR szBuffer{32};<br/>lstrcpy(szBuffer,lpszKey);<br/>for(int i = 0; i &lt; lstrlen(lpszKey); i++)<br/>&nbsp;&nbsp;szBuffer[i]--; <br/>//此时szBuffer中就是“RegKey”的原文<br/> <br/><br/>加密或验证部分与软件主体部分耦合度太低<br/>　　基于软件工程思想考虑，应该尽量降低软件模块之间的耦合度，但是对于软件加密来说，耦合度越高则加密强度越高，对注册码的验证最好不要封装到独立的函数或模块中。许多软件作者喜欢将加密或注册信息验证部分的代码封装到一个函数中，在程序中这样使用：<br/>if(CheckRegCode(szRegCode) == TRUE)<br/>{<br/>&nbsp;&nbsp;//注册信息正确，执行正常的功能 <br/>}<br/>else<br/>{<br/>&nbsp;&nbsp;//注册信息不正确，提示错误 <br/>}<br/><br/>这种封装看起来使程序代码结构良好，便于代码的组织与维护，但是也为破解者提供了良机。这样的程序通过反汇编之后通常有以下结构：<br/>push 00406070 &#39;字符串szRegCode参数入栈<br/>call 00401050 &#39;调用CheckRegCode函数<br/>test eax,eax &#39;判断CheckRegCode返回值<br/>je 00401029 &#39;跳转到出错位置<br/>&#39; 注册信息正确，顺序执行<br/><br/>从上面的汇编代码可以看到，只需将执行跳转的je指令（机器码是740B）改成两个NOP（CPU空操作指令，机器码是90）就等于忽略了对CheckRegCode函数返回值的判断，也就是说，无论这个函数返回TRUE还是FALSE，真正的功能代码都会执行，对注册码的校验就形同虚设。破解者根据指令的内存偏移地址计算出在可执行程序文件中的文件偏移位置，直接修改可执行文件就达到了破解这个功能的目的。此外，破解者还知道校验函数的位置是00401050，也就可以直接修改这个函数的代码，将函数开始部分的代码改成：<br/>mov eax,1 &#39; 机器码是B801<br/>ret &#39; 机器码是C3<br/>也就是说根本不判断注册码，直接返回1（校验成功的标志），就能够使整个软件的注册码校验功能失效，软件被彻底的破解。<br/><br/>　　还有一些软件作者为了软件开发的便利，将注册码的计算和校验功能封装到一个单独的动态链接库中，在软件安装过程中将其安装在系统目录中，以为这样就可以神不知鬼不觉了，其实不然，破解者利用SoftICE之类的系统级调试工具在系统的LoadLibrary（根据编码的不同可能有LoadLibraryA和LoadLibraryW两个版本）API上下断点，就可以获知程序所有的动态库加载动作，对注册码进行校验的动态库也不例外。知道这些信息之后，破解就变得简单了，无需修改主程序文件，只要将这个动态库替换掉就可以破解这个软件。比如，某软件使用名为“SysSec.dll”的动态库完成注册码校验功能，这个动态库有一个导出函数，函数原型为： <br/>BOOL WINAPI CheckRegCode(LPCTSTR lpszCode);<br/>破解者只需编写一个同名的动态库，也实现一个同名且同类型的导出函数，函数内容仅仅是返回TRUE：<br/>BOOL WINAPI CheckRegCode(LPCTSTR lpszCode)<br/>{<br/>&nbsp;&nbsp;return TRUE; <br/>}<br/>然后编译这个动态库，将其复制到系统目录覆盖原来的动态库，这样软件运行过程中会调用破解者的动态库，结果可想而知。网上有很多免费或收费的加密算法库，这些库往往不提供源代码，软件作者在使用这些库的时候一定要慎重，原因很简单：首先，这种用法导致加密模块与主程序耦合度不高，很容易被破解者“切开”；其次，这些公开的库就是软件破解者的众失之的，一旦某个破解组织推出了针对这个加密算法库的破解补丁，那么所有基于这个加密算法库的软件就都被破解了。<br/><br/>　　可见，对于软件加密来说，应该尽量增加加密模块与主程序的耦合度，将加密或校验代码嵌入到程序代码中，虽然给代码的组织和维护带来了困难，但是提高了软件的安全性，正所谓有得即有失，鱼和熊掌不可兼得。<br/><br/>对注册码进行明文比较<br/>　　现在网上流行的大部分共享软件都是采用“用户信息/注册码”方式进行加密的，它的使用过程一般是用户把自己的用户信息（用户名、机器特征码等）通过网络或其他方式发送给软件作者，软件作者根据用户信息利用预先设计好的算法计算出一个注册码，然后将此注册码发送给用户，用户得到注册码后按照软件说明的注册步骤在软件中输入用户信息和从软件供应者那里得到的注册码，如果注册码正确就取消时间或功能的限制，成为正式版本。这种保护方法实现起来简单，不需要额外的成本，用户不仅购买方便，还可以根据自己的注册信息得到售后服务。<br/>　　“用户信息/注册码”方式的验证过程其实就是验证用户信息到注册码之间的数学映射关系，这个映射关系通常是由软件开发者制定的，而且映射关系越复杂就越不容易被破解。以用户信息做自变量，E表示映射函数，则该映射关系可被表示为以下映射函数：<br/><br/>&nbsp;&nbsp;注册码 ＝ E（用户信息）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;映射函数（1）<br/><br/>应该说，只要映射函数E足够复杂，这个映射就是安全的，但是问题往往出在映射函数的两端，也就是作为自变量的用户信息和作为结果的注册码，这两部分都是以明文的形式传递的，如果处理不当就会露出破绽，正所谓良玉其内，败絮其外。以下是软件作者常用的注册信息校验方式：<br/>TCHAR szUserName[32];//存放破解者输入的用户信息（假设是Cracker）<br/>TCHAR szRegCode[64]; //存放破解者输入的注册码（假的，假设是ababababab）<br/>TCHAR szRealRegCode[64];<br/>CalculateRegCode(szUserName,szRealRegCode);//szRealRegCode得到了内部计算的正确注册码<br/>if(lstrcmp(szRegCode,szRealRegCode) == 0)<br/>{<br/>&nbsp;&nbsp;//输入的注册信息正确 <br/>}<br/>else<br/>{<br/>&nbsp;&nbsp;//输入的注册信息不正确 <br/>}<br/><br/>这段代码的问题在于CalculateRegCode函数调用之后，内存中就存在了正确的注册码的明文，保存在内存地址szRealRegCode处，通常情况下破解者不知道这个内存位置，但是借助SoftICE之类的调试软件就很容易跟踪到这个位置。比如，程序为了验证注册信息是否正确需要从注册窗口界面得到用户信息和用户输入的注册码，这些操作最终是通过调用Windows的API GetWindowText（根据编码的不同可能有GetWindowTextA和GetWindowTextW两个版本）或GetDlgItemText（根据编码的不同可能有GetDlgItemTextA和GetDlgItemTextW两个版本）完成的，破解者利用调试软件在这些函数上下断点就可以跟踪到szRegCode（存放破解者输入的假注册码）的内存地址。当然，破解者还可以利用内存搜索得到szRegCode的内存地址，在SoftICE中可以使用以下命令得到szRegCode的内存地址：<br/>s 30: 0 1 FFFFFFFF &#34;ababababab&#34;<br/>在内存地址szRegCode处下内存断点，当有对szRegCode地址进行操作时SoftICE就会中断，以上面的程序为例，就会在lstrcmp调用的时候中断，分析lstrcmp调用前后的代码（通常有以下类似的结构）：<br/>push 00408580 &#39;szRealRegCode地址入栈<br/>push 00408560 &#39;szUserName地址入栈<br/>call 00401080 &#39;调用CalculateRegCode计算正确的注册码，存放在szRealRegCode地址00408580处<br/>push 00408580 &#39;szRealRegCode地址入栈（已经得到正确的注册码）<br/>push 00408520 &#39;szRegCode地址入栈（假的注册码）<br/>call dword ptr [00405050] &#39;调用KERNEL32.lstrcmpA比较<br/>test eax, eax &#39;判断结果<br/>jne 0040104E &#39;注册码比较不正确，跳转到出错位置<br/>&#39;信息正确，顺序执行正常的功能<br/><br/>由此可知，在调用lstrcmp中断时，CalculateRegCode已经计算出来正确的注册码，存放在内存地址00408580处，使用SoftICE的D命令查看内存就可以看到注册码，结果如图（2）所示：<br/><br/><br/><br/>图（2） 内存中的注册码<br/> <br/><br/>“A12B-457C-120F”就是CalculateRegCode函数根据用户信息计算出来的正确的注册码，破解者绕开CalculateRegCode函数的算法，利用代码中的逻辑漏洞“兵不血刃”就得到了“Cracker”的注册码，重复这个过程就可以得到“张三”或“李四”的注册码，而且这些注册码都是CalculateRegCode函数计算出来的，可谓是“正宗”加“原创”。<br/>&nbsp;&nbsp;防止这种情况出现的关键是避免注册码以明文的形式出现在内存中，考察映射函数（1），其实只要修改映射函数的输入和输出设计，不返回计算出的正确注册码明文，而是返回一个注册码经过散列（hash）计算之后得到的散列值，就可以避免出现这种情况。例如：<br/><br/>散列值1 ＝ E1（用户信息）&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 映射函数（2）<br/>散列值2 ＝ MD5（用户注册码）<br/><br/>　　整个注册信息校验过程首先使用映射函数E1根据用户信息在内部计算正确的注册码，但是不直接输出这个注册码，而是利用MD5或CRC32之类的不可逆散列函数计算出注册码的散列值并输出这个散列值1，然后用MD5或CRC32直接计算用户输入的注册码得到散列值2，最后通过比较散列值1和散列值2来判断注册码是否正确。整个过程中正确的注册码只是短暂存在于CalculateRegCode内部，破解者即使通过汇编代码调试跟踪到了比较散列值的地方，也无法得到正确的注册码，只能通过分析CalculateRegCode函数的内部映射方式获得注册码，只要软件设计的映射方式足够复杂就能够让大多数破解者知难而退。&nbsp;&nbsp;共享软件中负责注册码校验的代码是软件中最关键的代码，也是软件破解者首先要找的地方。通过对校验代码的分析，破解者不仅能够利用前面介绍的方法从内存中抓取正确的注册码，还能了解软件的整个加密策略，甚至写出注册机。所以，尽量隐藏这部分代码，让破解者无法确定它们的位置也就能够极大地提高软件的安全性。<br/> <br/><br/>出错提示信息紧跟在加密判断之后出现<br/>　　为了方便软件的版本控制，多数共享软件都将共享版和正式版整合在一起发布，只是通过对使用时间或功能进行限制来区分是共享版还是正式版。这样的软件通常都有一个界面让用户输入注册码，通过验证注册码完成从共享版到注册版的转变。比如在软件界面上添加一个“注册”菜单或在关于对话框中添加一个“注册”按钮，通过用户的点击引导用户完成注册过程。这种策略并无不妥，破解者不大可能根据软件界面元素推测出校验代码的位置，但是许多软件作者对编译原理不了解，往往在得到注册校验结果后立即弹出消息窗口提示注册成功或注册码不正确之类的信息，这就给破解者提供了定位注册码校验代码的线索。就以下面的演示代码为例：<br/>BOOL bCheckValid = CheckValue(注册码...);<br/>if(bCheckValid)<br/>{<br/>&nbsp;&nbsp;MessageBox(... &#34;注册成功！&#34;...);<br/>}<br/>else<br/>{<br/>&nbsp;&nbsp;MessageBox(... &#34;注册信息不正确！&#34;...);<br/>}<br/>C/C++的编译器在生成这段代码时，两个提示信息字符串作为静态变量被放置在程序的数据段中，在代码段的MessageBox函数调用的地方会引用这两个地址，这两个地址就能够成为破解者的线索。本文前面已经介绍过，C/C++的编译器对代码中出现的字符串不作任何处理，按照顺序连续排放在数据段的某个位置，用16进制编辑器打开编译过的可执行文件，通常可以在数据段看到这些提示信息的明文。破解者使用字符串搜索（很多16进制编辑器都提供强大的搜索功能）功能在编译过的可执行文件中搜索MessageBox弹出的提示信息，就能定位到这些信息的偏移位置（相对地址），搜索相对地址可以进一步找到引用这些信息的位置，通常就是MessageBox函数的调用位置，这就离CheckValue函数的位置很近了，稍有经验的破解者都可以很容易找到它。将提示信息加密存放就可以避免程序在这些16进制编辑器中泄漏天机，不过最好的方法就是让注册提示信息远离关键的加密校验代码。在很多情况下不必在用户输入注册码后立刻提示成功与否，可以在某个位置设置一个标志，然后在软件的关键功能或核心功能执行之前取出这个标志判断，如果不是有效的注册用户就拒绝执行该功能。此外，对于标志存放也要妥善保护，最简单的方法就是使用定时器或辅助线程，每隔一定的时间就对注册码校验一次，重新设置一次标志的状态，以免被内存补丁程序破解。&nbsp;&nbsp;&nbsp;&nbsp; <br/><br/>其他常见问题<br/>　　使用时间限制功能的共享软件，用该避免使用GetSystemTime或GetLocalTime获得时间，因为破解者通常会在这些众所周知的API上下断点来捕捉程序中的破绽，不仅如此，这两个函数还很容易被“欺骗”，用户只需要修改Windows系统的时间就可以控制这两个API函数返回在“有效期内的”时间，从而使软件永不过期。其实有很多种获取时间的方法，Windows系统的一些关键文件通常只是在安装时创建一次，获得这些文件的创建时间就是一个很好的获取时间的方法。<br/>　　有些软件作者发布的试用版其实就是完整的正式版，只是修改资源将软件界面上的一些功能菜单或按钮禁止，这样做很省事，但是很不安全，破解者只需将被禁止的菜单或按钮重新改成可用就可以将试用版变成正式版，这样的资源修改工具有很多，很多国外软件的汉化版本就是通过修改程序资源实现的，软件作者应该避免采用这种方式加密软件。&nbsp;&nbsp;&nbsp;&nbsp; <br/><br/>总结<br/>　　很多网友向我询问软件加密的问题，但是他们通常觉得我给出的方案过于复杂（换句话说就是没有必要）。有网友问我，我的软件是面向计算机初级用户的，他们连注册表是怎么回事都不知道，怎么会破解我的软件？我的回答是永远不要小看别人，就算别人是菜鸟，但是菜鸟的“朋友”呢？即使一个功能简单的软件，也需要开发者付出很多的心血，但是破解只需要几分钟到几天的时间，这对于软件作者来说是非常不公平的。软件的加密与解密技术并不是什么特别难的技术，希望共享软件的作者能够多了解一些常见的加密与解密方法，更好地保护自己的软件。好的加密方法不一定就是什么高级技术，一个简单的方法如果用的巧妙往往也能起到出其不意的效果。希望本文列举出的常见问题以及相应的对策能够对广大共享软件作者有所帮助。<br/><br/>参考文献<br/>[1] 冉林仓．Win32汇编语言实用教程．北京：清华大学出版社，2004．<br/>[2] Matt Pietrek．An In-Depth Look into the Win32 Portable Executable File Format．MSDN Magazine，2002<br/>[3] 段刚．软件加密技术内幕．北京：电子工业出版社，2004．<br/><br/><br/>--------------------------------------------------------------------------------<br/><br/>共享软件防破解的实用招法<br/>1、检测主程序大小，防止破解补丁之类：<br/> <br/><br/>Function TForm1.GesSelfSf: integer;<br/>var<br/>F: file of byte;<br/>begin<br/>Filemode:=0;<br/>Assignfile(F,&#39;.\FileName.exe&#39;);<br/>Reset(f);<br/>Result:=Filesize(F);<br/>Closefile(F);<br/>end;<br/><br/><br/>2、检测创建日期和时间，让破解补丁实效：<br/><br/>Function TForm1.FinDate:String;<br/>var<br/>t:TDate;<br/>begin<br/>ShortDateFormat:=&#39;yyyy-mm-dd&#39;;<br/>t:=FileDateToDateTime(FileAge(&#39;FileName.exe&#39;));<br/>Result:=DateToStr(t);<br/>end;<br/><br/><br/>3、注册码加密函数嵌入数学函数，增加破解难度：<br/>（略）<br/><br/><br/><br/>4、必要时自己删除自己（主程序）：<br/> <br/><br/>procedure TForm1.Funll;<br/>var<br/>hModule:THandle;<br/>buff:array[0..255]of Char;<br/>hKernel32:THandle;<br/>pExitProcess,pDel&#101;teFileA,pUnmapViewOfFile:Pointer;<br/>begin<br/>hModule:=GetModuleHandle(nil);<br/>GetModuleFileName(hModule, buff, sizeof(buff));<br/>CloseHandle(THandle(4));<br/>hKernel32:=GetModuleHandle(&#39;KERNEL32&#39;);<br/>pExitProcess:=GetProcAddress(hKernel32, &#39;ExitProcess&#39;);<br/>pDel&#101;teFileA:=GetProcAddress(hKernel32, &#39;Del&#101;teFileA&#39;);<br/>pUnmapViewOfFile:=GetProcAddress(hKernel32, &#39;UnmapViewOfFile&#39;);<br/>asm<br/>LEA EAX, buff<br/>PUSH 0<br/>PUSH 0<br/>PUSH EAX<br/>PUSH pExitProcess<br/>PUSH hModule<br/>PUSH pDel&#101;teFileA<br/>PUSH pUnmapViewOfFile<br/>RET<br/>end;<br/>begin<br/>Funll;<br/>end;<br/>end;<br/><br/><br/>附：注册机破解法的原理以及应对方法<br/><br/>认识注册机破解法 <br/>　　顾名思义，写注册机来破解软件注册的方法，就是模仿你的注册码生成算法或者逆向注 册码验证算法而写出来的和你一模一样的注册机。如果被写出注册机，你的软件只好免费了。或者你必须更换算法，但以前注过册的合法用户都得被迫更换注册码了。<br/><br/>　　Cracker要写注册机必须详细研究你软件的验证模块，这必须先将你的软件脱壳，再反汇编或者用调试器跟踪。市面上许多加壳和保护软件都吹嘘不可能被脱壳，但到目前为止没有一个软件兑现了自己的诺言。由于CPU最终执行的都是有效指令，所以等你的程序自解压完成后再从内存中Dump出来就可以实现脱壳。因此不要在壳上面花很多功夫，因为没有这个必要。 <br/><br/>第一招：制造假相 <br/><br/>　　反汇编和调试器跟踪都是不可能防止的，因为所有的Win32程序都必须通过API来调用Windows系统中的关键DLL的（如Kernel32.dll、GDI32.dll等），然而API是可以Hook的。我们只能从自己的代码着手来保护我们的劳动果实了。 <br/><br/>　　为了自己调试和以后维护的方便，我们一般采用有意义的名字给我们的函数命名，可这给了Cracker可乘之机。例如这样的函数是什么意思大家应该一目了然吧?IsRegistered（），IsLicensed（），LicenseVerify（），CheckReg（）……这样Cracker就可以轻松地从数千个函数中找到他的目标——你的注册码校验函数!而且破解Delphi编写的软件还有一件TMG小组的破解利器——DeDe。它可以轻松地看到你软件里的Form、Unit和函数名，还可以反汇编一部分代码，更可以和Win32DASM合作反汇编更多的代码，对Delphi编出的程序威胁极大。 <br/><br/>　　为了不给Cracker创造温馨舒适的破解环境，要故意混乱（Obfuscate）我们的代码，将软件中所有的函数名全部替换成随机生成的函数名。例如Func_3dfsa_fs32zlfv这个函数是什么意思?恐怕只有天知道了。网上有现成的代码混乱器，按你使用的编程语言的种类可以找到一些。但要注意，只有当你要发布软件时才使用它，而且一定注意备份源代码。否则，当你看不懂你自己的代码时就着急了：） <br/><br/>第二招：用公匙，并改名 <br/><br/>　　另外，一定要使用公开密匙算法保护你的软件。RSA、DSA和El Gamal之类的算法都可以从网上找到。但注意：将你算法单元中所有涉及到算法名称的字符串全部改名。避免被Cracker发现你用的算法而模仿写出注册机来!你还可以张冠李戴，明明用的DSA，将名字全部替换成RSA。 <br/><br/>　　其它算法，如对称算法和Hash算法也要注意改名，否则这样： <br/> <br/><br/>　　EncryptedCode = Blowfish（MD5（UserName），MD5（Key））；<br/><br/><br/>　　 //你的加密算法，使用了Blowfish（对称算法）和MD5（Hash算法） <br/><br/>　　虽然那些Cracker不了解Blowfish和MD5算法的原理，也不会逆向推测它们，但他们了解你的校验算法的流程和算法名，便可马上从网上找到类似的Blowfish和MD5算法包，从而模拟你的软件仿造出注册机。 <br/><br/>　　如果你用不常见的，算法如Skipjack（NASA美国航天局标准算法）、LOKI、3-WAY、Safer之类不出名但保密程度很高的算法，并且全部改名，这样就会伤透他们脑筋了。 <br/><br/>　　当然，最好把Hash算法也全部改名，会给他们制造更多的困难。但注意，MD5和SHA之类的Hash初始值会被Cracker从内存中找到，这样他就知道你用的Hash了。所以建议同时使用MD5的变形算法Ripe-MD（RMD）128或160或其它的Hash，如Tiger、Haval等算法。 <br/><br/>第三招：阻止别人调试 <br/><br/>　　还有一点，调试器对我们的威胁很大，我们不会让Cracker们舒舒服服地使用SoftICE、TRW或OllyDbg来调试我们的程序。除了常用的MeItICE方法外，这里我给一个笔者写的方法： <br/><br/>　　 {检查自己的进程的父进程是否为Explorer.exe，否则是被调试器加载了} <br/> <br/>　　 {不过注意，控制台程序的父进程在WinNT下是Cmd.exe!} <br/><br/>　　 {注意加载TlHelp32.pas单元} <br/> <br/><br/>　　procedure CheckParentProc； <br/>　　 var //检查自己的进程的父进程 <br/>　　 Pn: TProcesseNtry32；&nbsp;&nbsp;<br/>　　 sHandle:THandle；&nbsp;&nbsp;<br/>　　 H，ExplProc，ParentProc:Hwnd；&nbsp;&nbsp;<br/>　　 Found:Boolean；&nbsp;&nbsp;<br/>　　 Buffer:array[0..1023]of Char；&nbsp;&nbsp;<br/>　　　 Path:string；&nbsp;&nbsp;<br/>　　 begin&nbsp;&nbsp;<br/>　　 H:= 0；&nbsp;&nbsp;<br/>　　 ExplProc:= 0；&nbsp;&nbsp;<br/>　　 ParentProc:= 0；&nbsp;&nbsp;<br/>　　 //得到Windows的目录&nbsp;&nbsp;<br/>　　 SetString（Path，Buffer）&nbsp;&nbsp;<br/>　　 GetWindowsDirectory（Buffer，Sizeof（Buffer）- 1））；&nbsp;&nbsp;<br/>　　 Path:= UpperCase（Path）+ &#39;\EX PLORER.EXE&#39;；//得到Explorer的路径&nbsp;&nbsp;<br/>　　 //得到所有进程的列表快照&nbsp;&nbsp;<br/>　　 sHandle:= Cr&#101;ateToolHelp32Snap Shot（TH32CS_SNAPALL，0）；&nbsp;&nbsp;<br/>　　 Found:= Process32First（sHandle，Pn）；//查找进程&nbsp;&nbsp;<br/>　　 while Found do //遍历所有进程&nbsp;&nbsp;<br/>　　 begin&nbsp;&nbsp;<br/>　　 if Pn.szExeFile = ParamStr（0）then //自己的进程&nbsp;&nbsp;<br/>　　 begin&nbsp;&nbsp;<br/>　　 ParentProc:= Pn.th32ParentProcessID://得到父进程的进程ID&nbsp;&nbsp;<br/>　　 //父进程的句柄&nbsp;&nbsp;<br/>　　 H:= OpenProcess（PRO CESS_ALL_ACCESS，True，Pn.th32Parent ProcessID）；&nbsp;&nbsp;<br/>　　 end&nbsp;&nbsp;<br/>　　 else if UpperCase（Pn.szExeFile）= Path then&nbsp;&nbsp;<br/>　　 ExplProc:= Pn.th32ProcessID；//Ex plorer的PID&nbsp;&nbsp;<br/>　　 Found:= Process32Next（sHandle，Pn）；//查找下一个&nbsp;&nbsp;<br/>　　 end；&nbsp;&nbsp;<br/>　　 //父进程不是Explorer，是调试器……&nbsp;&nbsp;<br/>　　 if ParentProc &lt;&gt; ExplProc then <br/>　　 begin&nbsp;&nbsp;<br/>　　 TerminateProcess（H，0）；//杀之!除之而后快也! :）&nbsp;&nbsp;<br/>　　 //你还可以加上其它什么死机代码来消遣消遣这位可爱的Cracker:）&nbsp;&nbsp;<br/>　　　 end&nbsp;&nbsp;<br/>　　 end<br/><br/> <br/>　　你可以在Delphi或者VC中试试，这样可以把Delphi和VC杀掉了，因为你现在用的是Delphi和VC的内置调试器来运行你的程序。调试的时候你还是把它的注释删掉吧，发布时别忘记激活哟! <br/><br/>第四招：保护字符串 <br/><br/>　　最后一个问题，这也是一个非常重要的问题：保护你的字符串!字符串在注册模块中非常重要!当一个富有经验的Cracker破解你的软件时，首先做的就是窃取你的字符串。比如他会输入错误的注册码，得到你关于错误注册码的提示，通常是“无效的注册码，请重新输入!”或者“Invalid key（please input again）”等等，然后用OllyDbg进行断点调试或者用WinDASM、IDA Pro等静态分析工具在被他脱壳后的程序中查找那个字符串，找到后进行分析。因此，请一定加密你的字符串! 使用时再临时解密出来，而且要尽量少使用消息提示框，避免被Cracker找到漏洞。加密字符串不需要太复杂的算法，随便找一个快速的对称算法就可以了。 <br/><br/>　　最后提醒大家一句，不要在加密上花太多的功夫!你应该把更多的时间和精力都用来完善你的软件，这样会更合算。借用一位前辈的话来忠告大家吧：花点时间考虑你自己的软件，看看它是否值得保护?如果没人用你的软件，保护也就没有意义了，不要过高估计你的软件“对世界的重要性”!<br/><br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=37" /> 
	  <id>http://blog.51haipai.com/default.asp?id=37</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[TreeView序列化，TreeView串行化，TreeView反序列化 c# winform]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2010-01-12T14:59:17+08:00</updated>
	  <published>2010-01-12T14:59:17+08:00</published>
		  <summary type="html"><![CDATA[-<br/><br/><br/><br/>前些天看到“序列化”这个概念，大意就是把对象保存为一个文件，下次再使用时，反序列化一下就OK了，第二天一大早到公司立马做了个Demo,哇，不错，非常之不错，使用此方法后，根本没有延迟的现象。今天终于应用到这个项目中了，同志们再也不用等那10秒了。<br/><br/>特记录于此，供后人瞻仰<br/><br/>view plaincopy to clipboardprint?<br/>using System;&nbsp;&nbsp; <br/>using System.IO;&nbsp;&nbsp; <br/>using System.Windows.Forms;&nbsp;&nbsp; <br/>using System.Runtime.Serialization.Formatters.Binary;&nbsp;&nbsp; <br/>using System.Data;&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>//from:<a href="http://www.ecjtu.org/forum/read.php?tid-12933.html" target="_blank" rel="external">http://www.ecjtu.org/forum/read.php?tid-12933.html</a>&nbsp;&nbsp; <br/>//反序列化：SerializeTree.TreeViewDataAccess.LoadTreeViewData(treeView1,&#34;C:\\treeview.txt&#34;);&nbsp;&nbsp; <br/>//序列化：&nbsp;&nbsp;SerializeTree.TreeViewDataAccess.SaveTreeViewData(treeView1,&#34;C:\\treeview.txt&#34;);&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;<br/>namespace SerializeTree&nbsp;&nbsp; <br/>{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;/// TreeView串行化类&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;public class TreeViewDataAccess&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeViewDataAccess() { }&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// TreeViewData&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Serializable()]&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public struct TreeViewData&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeNodeData[] Nodes;&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 递归初始化TreeView数据&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;treeview&#34;&gt;&lt;/param&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeViewData(TreeView treeview)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nodes = new TreeNodeData[treeview.Nodes.Count];&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (treeview.Nodes.Count == 0)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;= treeview.Nodes.Count - 1; i++)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nodes[i] = new TreeNodeData(treeview.Nodes[i]);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 通过TreeViewData弹出TreeView&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;treeview&#34;&gt;&lt;/param&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void PopulateTree(TreeView treeview)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this.Nodes == null || this.Nodes.Length == 0)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeview.BeginUp&#100;ate();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;= this.Nodes.Length - 1; i++)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeview.Nodes.Add(this.Nodes[i].ToTreeNode());&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeview.EndUp&#100;ate();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// TreeNodeData&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Serializable()]&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public struct TreeNodeData&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string Text;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int ImageIndex;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int Sel&#101;ctedImageIndex;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public bool Checked;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public bool Expanded;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public object Tag;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeNodeData[] Nodes;&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// TreeNode构造函数&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;node&#34;&gt;&lt;/param&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeNodeData(TreeNode node)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Text = node.Text;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.ImageIndex = node.ImageIndex;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Sel&#101;ctedImageIndex = node.Sel&#101;ctedImageIndex;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Checked = node.Checked;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Expanded = node.IsExpanded;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Nodes = new TreeNodeData[node.Nodes.Count];&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((!(node.Tag == null)) &amp;&amp; node.Tag.GetType().IsSerializable)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Tag = node.Tag;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Tag = null;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (node.Nodes.Count == 0)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;= node.Nodes.Count - 1; i++)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nodes[i] = new TreeNodeData(node.Nodes[i]);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// TreeNodeData返回TreeNode&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeNode ToTreeNode()&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode ToTreeNode = new TreeNode(this.Text, this.ImageIndex, this.Sel&#101;ctedImageIndex);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ToTreeNode.Checked = this.Checked;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ToTreeNode.Tag = this.Tag;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this.Expanded)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ToTreeNode.Expand();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this.Nodes == null &amp;&amp; this.Nodes.Length == 0)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (ToTreeNode != null &amp;&amp; this.Nodes.Length == 0)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ToTreeNode;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;= this.Nodes.Length - 1; i++)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ToTreeNode.Nodes.Add(this.Nodes[i].ToTreeNode());&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ToTreeNode;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 加载TreeView&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;treeView&#34;&gt;&lt;/param&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;path&#34;&gt;&lt;/param&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void LoadTreeViewData(TreeView treeView, string path)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter ser = new BinaryFormatter();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeViewData treeData = ((TreeViewData)(ser.Deserialize(file)));&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeData.PopulateTree(treeView);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Close();&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 保存TreeView到文件&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;treeView&#34;&gt;&lt;/param&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;path&#34;&gt;&lt;/param&gt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void SaveTreeViewData(TreeView treeView, string path)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter ser = new BinaryFormatter();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream file = new FileStream(path, FileMode.Cr&#101;ate);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ser.Serialize(file, new TreeViewData(treeView));&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Close();&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;//柳永法加的，序列化，及反序列化DataTable&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;class SerializeDataTable&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static DataTable LoadDataTable(string path)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter ser = new BinaryFormatter();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataTable dt = (DataTable)ser.Deserialize(file);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Close();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return dt;&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void SaveDataTable(DataTable dt, string path)&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter ser = new BinaryFormatter();&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream file = new FileStream(path, FileMode.Cr&#101;ate);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ser.Serialize(file, dt);&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Close();&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp; <br/>&nbsp;&nbsp;<br/>}&nbsp;&nbsp;<br/><br/>using System;<br/>using System.IO;<br/>using System.Windows.Forms;<br/>using System.Runtime.Serialization.Formatters.Binary;<br/>using System.Data;<br/><br/>//from:<a href="http://www.ecjtu.org/forum/read.php?tid-12933.html" target="_blank" rel="external">http://www.ecjtu.org/forum/read.php?tid-12933.html</a><br/>//反序列化：SerializeTree.TreeViewDataAccess.LoadTreeViewData(treeView1,&#34;C:\\treeview.txt&#34;);<br/>//序列化：&nbsp;&nbsp;SerializeTree.TreeViewDataAccess.SaveTreeViewData(treeView1,&#34;C:\\treeview.txt&#34;);<br/><br/><br/>namespace SerializeTree<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// TreeView串行化类<br/>&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;public class TreeViewDataAccess<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeViewDataAccess() { }<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// TreeViewData<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Serializable()]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public struct TreeViewData<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeNodeData[] Nodes;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 递归初始化TreeView数据<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;treeview&#34;&gt;&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeViewData(TreeView treeview)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nodes = new TreeNodeData[treeview.Nodes.Count];<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (treeview.Nodes.Count == 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;= treeview.Nodes.Count - 1; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nodes[i] = new TreeNodeData(treeview.Nodes[i]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 通过TreeViewData弹出TreeView<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;treeview&#34;&gt;&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public void PopulateTree(TreeView treeview)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this.Nodes == null || this.Nodes.Length == 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeview.BeginUp&#100;ate();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;= this.Nodes.Length - 1; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeview.Nodes.Add(this.Nodes[i].ToTreeNode());<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeview.EndUp&#100;ate();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// TreeNodeData<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[Serializable()]<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public struct TreeNodeData<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public string Text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int ImageIndex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public int Sel&#101;ctedImageIndex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public bool Checked;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public bool Expanded;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public object Tag;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeNodeData[] Nodes;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// TreeNode构造函数<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;node&#34;&gt;&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeNodeData(TreeNode node)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Text = node.Text;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.ImageIndex = node.ImageIndex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Sel&#101;ctedImageIndex = node.Sel&#101;ctedImageIndex;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Checked = node.Checked;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Expanded = node.IsExpanded;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Nodes = new TreeNodeData[node.Nodes.Count];<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ((!(node.Tag == null)) &amp;&amp; node.Tag.GetType().IsSerializable)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Tag = node.Tag;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;this.Tag = null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (node.Nodes.Count == 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;= node.Nodes.Count - 1; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Nodes[i] = new TreeNodeData(node.Nodes[i]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// TreeNodeData返回TreeNode<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;&lt;/returns&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public TreeNode ToTreeNode()<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeNode ToTreeNode = new TreeNode(this.Text, this.ImageIndex, this.Sel&#101;ctedImageIndex);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ToTreeNode.Checked = this.Checked;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ToTreeNode.Tag = this.Tag;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this.Expanded)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ToTreeNode.Expand();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (this.Nodes == null &amp;&amp; this.Nodes.Length == 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (ToTreeNode != null &amp;&amp; this.Nodes.Length == 0)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ToTreeNode;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt;= this.Nodes.Length - 1; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ToTreeNode.Nodes.Add(this.Nodes[i].ToTreeNode());<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return ToTreeNode;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 加载TreeView<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;treeView&#34;&gt;&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;path&#34;&gt;&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void LoadTreeViewData(TreeView treeView, string path)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter ser = new BinaryFormatter();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TreeViewData treeData = ((TreeViewData)(ser.Deserialize(file)));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;treeData.PopulateTree(treeView);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Close();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 保存TreeView到文件<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;treeView&#34;&gt;&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;path&#34;&gt;&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void SaveTreeViewData(TreeView treeView, string path)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter ser = new BinaryFormatter();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream file = new FileStream(path, FileMode.Cr&#101;ate);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ser.Serialize(file, new TreeViewData(treeView));<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Close();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;//柳永法加的，序列化，及反序列化DataTable<br/>&nbsp;&nbsp;&nbsp;&nbsp;class SerializeDataTable<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static DataTable LoadDataTable(string path)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter ser = new BinaryFormatter();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream file = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DataTable dt = (DataTable)ser.Deserialize(file);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Close();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return dt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void SaveDataTable(DataTable dt, string path)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BinaryFormatter ser = new BinaryFormatter();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Stream file = new FileStream(path, FileMode.Cr&#101;ate);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ser.Serialize(file, dt);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;file.Close();<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>}<br/><br/> <br/><br/><br/>引用本页地址：<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=36" /> 
	  <id>http://blog.51haipai.com/default.asp?id=36</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C#文件夹加密]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2010-01-12T14:01:01+08:00</updated>
	  <published>2010-01-12T14:01:01+08:00</published>
		  <summary type="html"><![CDATA[using System;<br/>using System.Drawing;<br/>using System.Collections;<br/>using System.ComponentModel;<br/>using System.Windows.Forms;<br/>using System.Data;<br/>using System.IO;<br/>using System.Diagnostics;<br/>using System.Threading;<br/>namespace 伪装文件夹<br/>{<br/>/// &lt;summary&gt;<br/>/// Form1 的摘要说明。<br/>/// &lt;/summary&gt;<br/>public class Form1 : System.Windows.Forms.Form<br/>{<br/>private System.Windows.Forms.GroupBox groupBox1;<br/>private System.Windows.Forms.Button button1;<br/>private System.Windows.Forms.FolderBrowserDialog foldeOpen;<br/>private System.Windows.Forms.TextBox AfoldePath;<br/>private System.Windows.Forms.GroupBox groupBox2;<br/>private System.Windows.Forms.Button button2;<br/>private System.Windows.Forms.Button button3;<br/>private System.Windows.Forms.TextBox textBox1;<br/>private System.Windows.Forms.Button AddPassword;<br/>private System.Windows.Forms.ComboBox comboBox1;<br/>private System.ComponentModel.IContainer components=null;<br/><br/>public Form1()<br/>{<br/>//<br/>// Windows 窗体设计器支持所必需的<br/>//<br/>InitializeComponent();<br/><br/>//<br/>// TODO: 在 InitializeComponent 调用后添加任何构造函数代码<br/>//<br/>}<br/><br/>/// &lt;summary&gt;<br/>/// 清理所有正在使用的资源。<br/>/// &lt;/summary&gt;<br/>protected override void Dispose( bool disposing )<br/>{<br/>if( disposing )<br/>{<br/>if (components != null) <br/>{<br/>components.Dispose();<br/>}<br/>}<br/>base.Dispose( disposing );<br/>}<br/><br/>#region Windows 窗体设计器生成的代码<br/>/// &lt;summary&gt;<br/>/// 设计器支持所需的方法 - 不要使用代码编辑器修改<br/>/// 此方法的内容。<br/>/// 孤竹残梦<br/>/// 转载请保留原出处<br/>/// &lt;/summary&gt;<br/>private void InitializeComponent()<br/>{<br/>System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));<br/>this.groupBox1 = new System.Windows.Forms.GroupBox();<br/>this.comboBox1 = new System.Windows.Forms.ComboBox();<br/>this.AddPassword = new System.Windows.Forms.Button();<br/>this.button1 = new System.Windows.Forms.Button();<br/>this.AfoldePath = new System.Windows.Forms.TextBox();<br/>this.foldeOpen = new System.Windows.Forms.FolderBrowserDialog();<br/>this.groupBox2 = new System.Windows.Forms.GroupBox();<br/>this.button2 = new System.Windows.Forms.Button();<br/>this.button3 = new System.Windows.Forms.Button();<br/>this.textBox1 = new System.Windows.Forms.TextBox();<br/>this.groupBox1.SuspendLayout();<br/>this.groupBox2.SuspendLayout();<br/>this.SuspendLayout();<br/>// <br/>// groupBox1<br/>// <br/>this.groupBox1.BackColor = System.Drawing.Color.Transparent;<br/>this.groupBox1.Controls.Add(this.comboBox1);<br/>this.groupBox1.Controls.Add(this.AddPassword);<br/>this.groupBox1.Controls.Add(this.button1);<br/>this.groupBox1.Controls.Add(this.AfoldePath);<br/>this.groupBox1.Location = new System.Drawing.Point(2, 2);<br/>this.groupBox1.Name = &#34;groupBox1&#34;;<br/>this.groupBox1.Size = new System.Drawing.Size(190, 94);<br/>this.groupBox1.TabIndex = 0;<br/>this.groupBox1.TabStop = false;<br/>this.groupBox1.Text = &#34;伪装&#34;;<br/>// <br/>// comboBox1<br/>// <br/>this.comboBox1.Items.AddRange(new object[] {<br/>&#34;我的电脑&#34;,<br/>&#34;我的文档&#34;,<br/>&#34;拨号网络&#34;,<br/>&#34;控制面板&#34;,<br/>&#34;计划任务&#34;,<br/>&#34;打印机&#34;,<br/>&#34;网络邻居&#34;,<br/>&#34;回收站&#34;,<br/>&#34;公文包&#34;,<br/>&#34;字体 &#34;,<br/>&#34;Web 文件夹&#34;});<br/>this.comboBox1.Location = new System.Drawing.Point(12, 44);<br/>this.comboBox1.Name = &#34;comboBox1&#34;;<br/>this.comboBox1.Size = new System.Drawing.Size(174, 20);<br/>this.comboBox1.TabIndex = 15;<br/>this.comboBox1.Text = &#34;加密类型&#34;;<br/>/// 孤竹残梦<br/>/// 转载请保留原出处<br/>// <br/>// AddPassword<br/>// <br/>this.AddPassword.BackColor = System.Drawing.Color.Transparent;<br/>this.AddPassword.Location = new System.Drawing.Point(110, 66);<br/>this.AddPassword.Name = &#34;AddPassword&#34;;<br/>this.AddPassword.TabIndex = 14;<br/>this.AddPassword.Text = &#34;伪装(&amp;S)&#34;;<br/>this.AddPassword.Click += new System.EventHandler(this.AddPassword_Click);<br/>// <br/>// button1<br/>// <br/>this.button1.Location = new System.Drawing.Point(12, 66);<br/>this.button1.Name = &#34;button1&#34;;<br/>this.button1.TabIndex = 8;<br/>this.button1.Text = &#34;文件夹(&amp;W)&#34;;<br/>this.button1.Click += new System.EventHandler(this.button1_Click);<br/>// <br/>// AfoldePath<br/>// <br/>this.AfoldePath.BackColor = System.Drawing.Color.FromArgb(((System.Byte)(255)), ((System.Byte)<br/><br/>(224)), ((System.Byte)(192)));<br/>this.AfoldePath.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;<br/>this.AfoldePath.Location = new System.Drawing.Point(12, 16);<br/>this.AfoldePath.Name = &#34;AfoldePath&#34;;<br/>this.AfoldePath.ReadOnly = true;<br/>this.AfoldePath.Size = new System.Drawing.Size(174, 21);<br/>this.AfoldePath.TabIndex = 7;<br/>this.AfoldePath.Text = &#34;&#34;;<br/>/// 孤竹残梦<br/>/// 转载请保留原出处<br/>// <br/>// groupBox2<br/>// <br/>this.groupBox2.BackColor = System.Drawing.Color.Transparent;<br/>this.groupBox2.Controls.Add(this.button2);<br/>this.groupBox2.Controls.Add(this.button3);<br/>this.groupBox2.Controls.Add(this.textBox1);<br/>this.groupBox2.Location = new System.Drawing.Point(2, 100);<br/>this.groupBox2.Name = &#34;groupBox2&#34;;<br/>this.groupBox2.Size = new System.Drawing.Size(190, 68);<br/>this.groupBox2.TabIndex = 1;<br/>this.groupBox2.TabStop = false;<br/>this.groupBox2.Text = &#34;还原&#34;;<br/>// <br/>// button2<br/>// <br/>this.button2.ForeColor = System.Drawing.Color.Red;<br/>this.button2.Location = new System.Drawing.Point(110, 40);<br/>this.button2.Name = &#34;button2&#34;;<br/>this.button2.TabIndex = 14;<br/>this.button2.Text = &#34;还原解密&#34;;<br/>this.button2.Click += new System.EventHandler(this.button2_Click);<br/>// <br/>// button3<br/>// <br/>this.button3.ForeColor = System.Drawing.Color.Red;<br/>this.button3.Location = new System.Drawing.Point(8, 40);<br/>this.button3.Name = &#34;button3&#34;;<br/>this.button3.TabIndex = 8;<br/>this.button3.Text = &#34;文件夹&#34;;<br/>this.button3.Click += new System.EventHandler(this.button3_Click);<br/>// <br/>// textBox1<br/>// <br/>this.textBox1.BackColor = System.Drawing.Color.White;<br/>this.textBox1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;<br/>this.textBox1.Location = new System.Drawing.Point(12, 16);<br/>this.textBox1.Name = &#34;textBox1&#34;;<br/>this.textBox1.ReadOnly = true;<br/>this.textBox1.Size = new System.Drawing.Size(174, 21);<br/>this.textBox1.TabIndex = 7;<br/>this.textBox1.Text = &#34;&#34;;<br/>// <br/>// Form1<br/>// <br/>this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);<br/>this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject(&#34;$this.BackgroundImage&#34;)));<br/>this.ClientSize = new System.Drawing.Size(192, 168);<br/>this.Controls.Add(this.groupBox2);<br/>this.Controls.Add(this.groupBox1);<br/>this.Cursor = System.Windows.Forms.Cursors.Hand;<br/>this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;<br/>this.Icon = ((System.Drawing.Icon)(resources.GetObject(&#34;$this.Icon&#34;)));<br/>this.MaximizeBox = false;<br/>this.Name = &#34;Form1&#34;;<br/>this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;<br/>this.Text = &#34;BY:孤竹残梦&#34;;<br/>this.groupBox1.ResumeLayout(false);<br/>this.groupBox2.ResumeLayout(false);<br/>this.ResumeLayout(false);<br/><br/>}<br/>#endregion<br/><br/>/// &lt;summary&gt;<br/>/// 孤竹残梦<br/>/// 转载请保留原出处<br/>/// 应用程序的主入口点。<br/>/// &lt;/summary&gt;<br/>[STAThread]<br/>static void Main() <br/>{<br/>Application.Run(new Form1());<br/>}<br/>private void button1_Click(object sender, System.EventArgs e)<br/>{<br/>if(foldeOpen.ShowDialog ()==DialogResult.OK )<br/>{<br/>try<br/>{<br/>if(foldeOpen.Sel&#101;ctedPath .Substring (3,10)==&#34;Documents &#34;)<br/>{<br/>MessageBox.Show (&#34;孤竹残梦提醒：不建议伪装系统文件夹下文件,可能会造成系统出问题&#34;,&#34;提示信<br/><br/>息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Error);<br/>}<br/>else<br/>{<br/>AfoldePath.Text =foldeOpen.Sel&#101;ctedPath;<br/>}<br/>}<br/>catch<br/>{<br/>if(foldeOpen.Sel&#101;ctedPath.Length &gt;=4)<br/>{<br/>AfoldePath.Text =foldeOpen.Sel&#101;ctedPath;<br/>}<br/>else<br/>{<br/>MessageBox.Show (&#34;孤竹残梦提醒：不能对盘符进行伪装&#34;,&#34;提示信<br/><br/>息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Error);<br/>}<br/>}<br/>}<br/>}<br/>private void AddPassword_Click(object sender, System.EventArgs e)<br/>{<br/>if(this.AfoldePath.Text==&#34;&#34;)<br/>{<br/>MessageBox.Show(&#34;请选择文件夹路径！&#34;,&#34;提示信息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Error);<br/>}<br/>else if(this.comboBox1.Text==&#34;加密类型&#34;)<br/>{<br/>MessageBox.Show(&#34;请选择加密类型！&#34;,&#34;提示信息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Error);<br/>}<br/>else<br/>{<br/>try<br/>{<br/>ProcessStartInfo p3=new ProcessStartInfo (&#34;attrib.exe&#34;,@&#34;-s -r -a -h &#34;+AfoldePath.Text);<br/>p3.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;<br/>Process.Start (p3);<br/>ProcessStartInfo p1=new ProcessStartInfo (&#34;attrib.exe&#34;,@&#34;-s -r -a -h<br/><br/>&#34;+AfoldePath.Text+@&#34;\desktop.ini&#34;);<br/>p1.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;<br/>Process.Start (p1);<br/>StreamWriter sw2=new StreamWriter (AfoldePath.Text+@&#34;\desktop.ini&#34; );<br/>sw2.WriteLine (@&#34;[.ShellClassInfo]&#34; );<br/>sw2.WriteLine (&#34;CLSID=&#34;+GetPasType());<br/>sw2.Close ();<br/>ProcessStartInfo p =new ProcessStartInfo (&#34;attrib.exe&#34;,@&#34;+s +a +h +r<br/><br/>&#34;+AfoldePath.Text+@&#34;\desktop.ini&#34;);<br/>p.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;<br/>Process.Start (p);<br/>ProcessStartInfo p2=new ProcessStartInfo (&#34;attrib.exe&#34;,@&#34;+s +r &#34;+AfoldePath.Text);<br/>p2.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;<br/>Process.Start (p2);<br/>MessageBox.Show(&#34;孤竹残梦提示：伪装成功！&#34;,&#34;提示信<br/><br/>息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Information);<br/>}<br/>catch<br/>{<br/>MessageBox.Show (&#34;孤竹残梦提示：不可多次进行伪装！&#34;,&#34;提示信<br/><br/>息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Error);<br/>}<br/>}<br/>}<br/>private string GetPasType()<br/>{<br/>int index=comboBox1.Sel&#101;ctedIndex;<br/>switch (index)<br/>{<br/>case 0: return @&#34;{20D04FE0-3AEA-1069-A2D8-08002B30309D}&#34;;<br/>case 1: return @&#34;{450D8FBA-AD25-11D0-98A8-0800361B1103}&#34;;<br/>case 2: return @&#34;{992CFFA0-F557-101A-88EC-00DD010CCC48}&#34;;<br/>case 3: return @&#34;{21EC2020-3AEA-1069-A2DD-08002B30309D}&#34;;<br/>case 4: return @&#34;{D6277990-4C6A-11CF-8D87-00AA0060F5BF}&#34;;<br/>case 5: return @&#34;{2227A280-3AEA-1069-A2DE-08002B30309D}&#34;;<br/>//case 6: return @&#34;{1FBA04EE-3024-11D2-8F1F-0000F87ABD16}&#34;;<br/>case 6: return @&#34;{208D2C60-3AEA-1069-A2D7-08002B30309D}&#34;;<br/>case 7: return @&#34;{645FF040-5081-101B-9F08-00AA002F954E}&#34;;<br/>case 8: return @&#34;{85BBD920-42A0-1069-A2E4-08002B30309D}&#34;;<br/>case 9: return @&#34;{BD84B380-8CA2-1069-AB1D-08000948F534}&#34;;<br/>case 10: return @&#34;{BDEADF00-C265-11d0-BCED-00A0C90AB50F}&#34;; <br/>}<br/>return @&#34;{20D04FE0-3AEA-1069-A2D8-08002B30309D}&#34;;<br/>}<br/>private void button3_Click(object sender, System.EventArgs e)<br/>{<br/>if(foldeOpen.ShowDialog ()==DialogResult.OK )<br/>{<br/>textBox1.Text =foldeOpen.Sel&#101;ctedPath;<br/>}<br/>}<br/><br/>private void button2_Click(object sender, System.EventArgs e)<br/>{<br/>if(this.textBox1.Text==&#34;&#34;)<br/>{<br/>MessageBox.Show(&#34;请选择加密文件的路径&#34;,&#34;提示信息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Error);<br/>return;<br/>}<br/>/// 孤竹残梦<br/>/// 转载请保留原出处<br/>// else<br/>// {<br/>// MessageBox.Show(&#34;未注册，请联系作者以购买正版。&#34;,&#34;提示信<br/><br/>息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Error);<br/>// return;<br/>// }<br/>if(this.textBox1.Text==&#34;&#34;)<br/>{<br/>MessageBox.Show(&#34;请选择加密过的文件夹！&#34;,&#34;提示信息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Error);<br/>}<br/>else<br/>{<br/>try<br/>{<br/>ProcessStartInfo p2=new ProcessStartInfo (&#34;attrib.exe&#34;,@&#34;-s -r -a -h &#34;+textBox1.Text);<br/>p2.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;<br/>Process.Start (p2);<br/>ProcessStartInfo p1=new ProcessStartInfo (&#34;attrib.exe&#34;,@&#34;-s -h -r<br/><br/>&#34;+textBox1.Text+@&#34;\desktop.ini&#34;);<br/>p1.WindowStyle= System.Diagnostics.ProcessWindowStyle.Hidden;<br/>Process.Start (p1);<br/>System.Threading.Thread.Sleep(1000);<br/>File.Del&#101;te (textBox1.Text+@&#34;\desktop.ini&#34;);<br/>MessageBox.Show (&#34;解密成功,已经还原&#34;,&#34;提示信息&#34;,MessageBoxButtons.OK,MessageBoxIcon.Information);<br/>}<br/>catch<br/>{<br/>MessageBox.Show(&#34;一次解密就OK啦，请勿多次！&#34;);<br/>}<br/>}<br/>}<br/>}<br/>}<br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=35" /> 
	  <id>http://blog.51haipai.com/default.asp?id=35</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[c# 自定义文件关联程序]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2009-11-20T13:20:54+08:00</updated>
	  <published>2009-11-20T13:20:54+08:00</published>
		  <summary type="html"><![CDATA[做很多程序都是独立运行的，然后做各种操作，今天尝试一下像播放器之类的程序，我们自定义一些文件类型，然后关联自己的软件。双击打开时就将文件传入了软件，同样可以支持将文件拖放到程序上运行。 闲话少说，下面开始写程序，首先建立一个c#的winForm程序。然后解决文件关联问题，其实就是操作注册表，在注册表中记录了文件的类型和关联的程序：<br/><br/> <br/><br/>下面这段是从网上看到的代码：<br/><br/>/// &lt;summary&gt;<br/>/// 关联文件<br/>/// &lt;/summary&gt;<br/>/// &lt;param name=&#34;_FilePathString&#34;&gt;应用程序路径&lt;/param&gt;<br/>/// &lt;param name=&#34;p_FileTypeName&#34;&gt;文件类型&lt;/param&gt;<br/>public static void SaveReg(string _FilePathString,string p_FileTypeName)<br/>{<br/>RegistryKey _RegKey = Registry.ClassesRoot.OpenSubKey(&#34;&#34;, true);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//打开注册表<br/>RegistryKey _VRPkey = _RegKey.OpenSubKey(p_FileTypeName, true);<br/>if (_VRPkey != null)<br/>{<br/>_RegKey.Del&#101;teSubKey(p_FileTypeName, true);<br/>}<br/>_RegKey.Cr&#101;ateSubKey(p_FileTypeName);<br/>_VRPkey = _RegKey.OpenSubKey(p_FileTypeName, true);<br/>_VRPkey.SetValue(&#34;&#34;, &#34;Exec&#34;);<br/>_VRPkey = _RegKey.OpenSubKey(&#34;Exec&#34;, true);<br/>if (_VRPkey != null) _RegKey.Del&#101;teSubKeyTree(&#34;Exec&#34;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //如果等于空就删除注册表DSKJIVR<br/>_RegKey.Cr&#101;ateSubKey(&#34;Exec&#34;);<br/>_VRPkey = _RegKey.OpenSubKey(&#34;Exec&#34;, true);<br/>_VRPkey.Cr&#101;ateSubKey(&#34;shell&#34;);<br/>_VRPkey = _VRPkey.OpenSubKey(&#34;shell&#34;, true);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//写入必须路径<br/>_VRPkey.Cr&#101;ateSubKey(&#34;open&#34;);<br/>_VRPkey = _VRPkey.OpenSubKey(&#34;open&#34;, true);<br/>_VRPkey.Cr&#101;ateSubKey(&#34;command&#34;);<br/>_VRPkey = _VRPkey.OpenSubKey(&#34;command&#34;, true);<br/>string _PathString = &#34;\&#34;&#34; + _FilePathString + &#34;\&#34; \&#34;%1\&#34;&#34;;<br/>_VRPkey.SetValue(&#34;&#34;, _PathString);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//写入数据<br/>}值得一提的是路径里面的&#34;%1”，即使去掉这个同样可以进行关联，但是在后面我们就会有一个很大的麻烦。我们在双击文件时，是否会将路径传入应用程序就取决于这个参数,而且有一点要说明一下，上面函数的_RegKey.Cr&#101;ateSubKey(p_FileTypeName);<br/>在vista下面执行的时候会报错，因为权限的原因。将vista的用户控制关掉即可（在“用户账户”中找到“打开或关闭用户账户控制”选项）。下面的一个函数是取消关联 <br/><br/>/// &lt;summary&gt;<br/>/// 取消文件关联<br/>/// &lt;/summary&gt;<br/>/// &lt;param name=&#34;p_FileTypeName&#34;&gt;文件类型&lt;/param&gt;<br/>public static void DelReg(string p_FileTypeName)<br/>{<br/>RegistryKey _Regkey = Registry.ClassesRoot.OpenSubKey(&#34;&#34;, true);<br/>RegistryKey _VRPkey = _Regkey.OpenSubKey(p_FileTypeName);<br/>if (_VRPkey != null)<br/>{<br/>_Regkey.Del&#101;teSubKey(p_FileTypeName, true);<br/>}<br/>if (_VRPkey != null)<br/>{<br/>_Regkey.Del&#101;teSubKeyTree(&#34;Exec&#34;);<br/>}<br/>}到现在为止，程序已经有了一个基本雏形，我们可以看一下 <br/><br/> 这样，我们双击扩展名为.zxl的文件时，就会运行刚刚所写的这个程序。但是光只有这样还是不够的，我们需要的是打开双击的文件。其实很简单，只要在main方法中加入参数就可以了 <br/><br/>/// &lt;summary&gt;<br/>/// 应用程序的主入口点。<br/>/// &lt;/summary&gt;<br/>[STAThread]<br/>static void Main(string [] Args)<br/>{<br/>Application.EnableVisualStyles();<br/>Application.SetCompatibleTextRenderingDefault(false);<br/>Application.Run(new f_reader(Args));<br/>}&nbsp;&nbsp;&nbsp;&nbsp;默认建winform程序时，main和form的构造函数是空的，我们加上了一个参数列表，这样的话，我们在双击文件时就会将文件的路径传入程序，到这时，我们无论对文件进行什么操作都随心所欲了。 这样还差很多，很多软件都支持拖放，可以把文件直接拖到软件上就打开了。下面我们写下面的代码，我们需要创建Form的DragEnter和DragDro&#112;事件：<br/><br/>private void f_reader_DragEnter(object sender, DragEventArgs e)<br/>{<br/>if (e.Data.GetDataPresent(DataFormats.FileDro&#112;))<br/>{<br/>e.Effect = DragDro&#112;Effects.Link;<br/>}<br/>else<br/>{<br/>e.Effect = DragDro&#112;Effects.None;<br/>}<br/>}<br/>private void f_reader_DragDro&#112;(object sender, DragEventArgs e)<br/>{<br/>lb_file.Items.Add(((System.Array)e.Data.GetData(DataFormats.FileDro&#112;)).GetValue(0).ToString());//这个地方得到的就是拖放的文件路径<br/>}到现在我们的程序就基本完成了。有临时想到了一个事情，双击多个文件时只打开一个程序实例，临时从网上搜了一下（下面的代码没有经过试验）： <br/><br/> 感谢，下面内容转自：<a href="http://www.cnblogs.com/Fooo/archive/2008/09/25/1298455.html" target="_blank" rel="external">http://www.cnblogs.com/Fooo/archive/2008/09/25/1298455.html</a><br/>防止程序运行多个实例的方法有多种,如:通过使用互斥量和进程名等.而我想要实现的是:在程序运行多个实例时激活的是第一个实例,使其获得焦点,并在前端显示. <br/><br/>主要用到两个API 函数: <br/><br/>ShowWindowAsync 该函数设置由不同线程产生的窗口的显示状态。 <br/>SetForegroundWindow 该函数将创建指定窗口的线程设置到前台，并且激活该窗口。键盘输入转向该窗口，并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。 <br/>代码如下：<br/>引用以下命名空间：<br/>using System.Runtime.InteropServices;<br/>using System.Diagnostics;<br/>using System.Reflection;<br/>//*****************************************************<br/>&nbsp;&nbsp;static class Program <br/>&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 该函数设置由不同线程产生的窗口的显示状态。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;hWnd&#34;&gt;窗口句柄&lt;/param&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;cmdShow&#34;&gt;指定窗口如何显示。查看允许值列表，请查阅ShowWlndow函数的说明部分。&lt;/param&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;如果函数原来可见，返回值为非零；如果函数原来被隐藏，返回值为零。&lt;/returns&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&#34;User32.dll&#34;)] <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private static extern bool ShowWindowAsync(IntPtr hWnd, int cmdShow); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 该函数将创建指定窗口的线程设置到前台，并且激活该窗口。键盘输入转向该窗口，并为用户改各种可视的记号。系统给创建前台窗口的线程分配的权限稍高于其他线程。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;hWnd&#34;&gt;将被激活并被调入前台的窗口句柄。&lt;/param&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;如果窗口设入了前台，返回值为非零；如果窗口未被设入前台，返回值为零。&lt;/returns&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[DllImport(&#34;User32.dll&#34;)] <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private static extern bool SetForegroundWindow(IntPtr hWnd); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;private const int WS_SHOWNORMAL = 1; <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 应用程序的主入口点。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[STAThread] <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static void Main() <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Application.EnableVisualStyles(); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Application.SetCompatibleTextRenderingDefault(false); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Process instance = RunningInstance(); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (instance == null) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Form1 frm = new Form1(); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Application.Run(new Form1()); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HandleRunningInstance(instance); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 获取正在运行的实例，没有运行的实例返回null; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static Process RunningInstance() <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Process current = Process.GetCurrentProcess(); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Process[] processes = Process.GetProcessesByName(current.ProcessName); <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach (Process process in processes) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (process.Id != current.Id) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (Assembly.GetExecutingAssembly().Location.Replace(&#34;/&#34;, &#34;\\&#34;) == current.MainModule.FileName) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return process; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return null; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 显示已运行的程序。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public static void HandleRunningInstance(Process instance) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ShowWindowAsync(instance.MainWindowHandle, WS_SHOWNORMAL); //显示，可以注释掉 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SetForegroundWindow(instance.MainWindowHandle);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//放到前端 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} <br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=34" /> 
	  <id>http://blog.51haipai.com/default.asp?id=34</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[WebBrowser页面与WinForm交互技巧]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2009-11-15T20:31:07+08:00</updated>
	  <published>2009-11-15T20:31:07+08:00</published>
		  <summary type="html"><![CDATA[近看到博客园入门教学文章比较流行，自己最近又偷懒比较多，没啥心得，不妨写一篇没啥深度的入门文章吧。 <br/><br/>话说有了WebBrowser类，终于不用自己手动封装SHDocVw的AxWebBrowser这个ActiveX控件了。这个类如果仅仅作为一个和IE一模一样浏览器，那就太没意思了（还不如直接用IE呢）。那么，无论我们是想做一个“定制版IE”，还是希望利用HTML来做用户界面（指WinApp而非WebApp。许多单机软件，包括Windows的帮助支持中心，都是HTML做的），都少不了Windows Form和包含在WebBrowser中的Web页面的交互。本文将通过几个实际的例子，初步介绍一下WinForm和WebBrowser所包含的Web页面之间的交互。 <br/><br/>下面的代码假设你已经建立了一个Windows Form，上面有一个WebBrowser名为“webBrowser”。 <br/><br/><br/>Study Case 1：用WinForm的Event Handler响应Web页面的事件 <br/><br/>现在有这样一个Windows Application，它的界面上只有一个WebBrowser，显示一个本地的HTML文件作为界面。现在的问题是，所有逻辑都可以放在HTML文件里，唯独“关闭”按钮遇到了困难——通常，Web页面是没有办法直接控制浏览器的，更不用说结束这个WinForm程序了。 <br/><br/>但是，在.Net 2.0当中，“由Windows Form响应Web页面的事件”已经成为了现实。 <br/><br/>在.Net 2.0中，整个HTML文档以及其包含的各个HTML元素，都和一个个HtmlDocument、HtmlElement之类的.Net对象对应。因此只要找到这个“关闭”按钮对应的HtmlElement对象，为其click事件添加Event Handler即可。 <br/><br/>假设HTML源代码如下： <br/><br/>阅读 编辑 运行 复制 保存&lt;html&gt; <br/>&lt;body&gt; <br/>&lt;input type=&#34;button&#34; id=&#34;btnClose&#34; value=&#34;关闭&#34; /&gt; <br/>&lt;/body&gt; <br/>&lt;/html&gt;<br/>&lt;html&gt; &lt;body&gt; &lt;input type=&#34;button&#34; id=&#34;btnClose&#34; value=&#34;关闭&#34; /&gt; &lt;/body&gt; &lt;/html&gt; <br/>那么找出该按钮并为之添加Event Handler的代码如下： <br/>复制 保存HtmlDocument htmlDoc = webBrowser.Document;<br/>HtmlElement btnElement = htmlDoc.All[&#34;btnClose&#34;];<br/>if (btnElement != null)<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;btnElement.click += new HtmlElementEventHandler(HtmlBtnClose_Click);<br/>}<br/><br/>其中HtmlBtnClose_Click是按下Web按钮时的Event Handler。 <br/><br/>很简单吧？那么稍稍高级一点的——我们都知道一个HTML元素可能有很多各种各样的事件，而HtmlElement这个类只给出最常用、共通的几个。那么，如何响应其他事件呢？这也很简单，只需要调用HtmlElement的AttachEventHandler就可以了： <br/>复制 保存btnElement.AttachEventHandler(&#34;onclick&#34;, new EventHandler(HtmlBtnClose_Click));&nbsp;&nbsp;<br/>//这一句等价于上面的btnElement.click += new HtmlElementEventHandler(HtmlBtnClose_Click);<br/><br/>对于其他事件，把&#34;onclick&#34;换成该事件的名字就可以了。例如： <br/>复制 保存formElement.AttachEventHandler(&#34;onsubmit&#34;, new EventHandler(HtmlForm_Submit));<br/><br/><br/>Study Case 2：表单（form）的自动填写和提交 <br/><br/>要使我们的WebBrowser具有自动填表、甚至自动提交的功能，并不困难。 <br/><br/>假设有一个最简单的登录页面，输入用户名密码，点“登录”按钮即可登录。已知用户名输入框的id（或Name，下同）是username，密码输入框的id是password，“登录”按钮的id是submitbutton，那么我们只需要在webBrowser的DocumentCompleted事件中使用下面的代码即可： <br/>复制 保存HtmlElement btnSubmit = webBrowser.Document.All[&#34;submitbutton&#34;];<br/>HtmlElement tbUserid = webBrowser.Document.All[&#34;username&#34;];<br/>HtmlElement tbPasswd = webBrowser.Document.All[&#34;password&#34;];<br/><br/>if (tbUserid == null || tbPasswd == null || btnSubmit == null)<br/>&nbsp;&nbsp;&nbsp;&nbsp;return;<br/><br/>tbUserid.SetAttribute(&#34;value&#34;, &#34;smalldust&#34;);<br/>tbPasswd.SetAttribute(&#34;value&#34;, &#34;12345678&#34;);<br/><br/>btnSubmit.InvokeMember(&#34;click&#34;);<br/><br/>这里我们用SetAttribute来设置文本框的“value”属性，用InvokeMember来调用了按钮的“click”方法。因为不同的Html元素，其拥有的属性和方法也不尽相同，所以.Net 2.0提供了统一的HtmlElement来概括各种Html元素的同时，提供了这两个方法以调用元素特有的功能。关于各种Html元素的属性和方法一览，可以查阅MSDN的DHTML Reference。 <br/><a href="http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp" target="_blank" rel="external">http://msdn.microsoft.com/workshop/author/dhtml/reference/dhtml_reference_entry.asp</a> <br/><br/>※关于表单的提交，的确还有另一种方法就是获取form元素而不是button，并用form元素的submit方法： <br/>复制 保存HtmlElement formLogin = webBrowser.Document.Forms[&#34;loginForm&#34;];&nbsp;&nbsp;<br/>//……&nbsp;&nbsp;<br/>formLogin.InvokeMember(&#34;submit&#34;);<br/><br/>本文之所以没有推荐这种方法，是因为现在的网页，很多都在submit按钮上添加onclick事件，以对提交的内容做最基本的验证。如果直接使用form的submit方法，这些验证代码就得不到执行，有可能会引起错误。 <br/><br/><br/>Study Case 3：查找并选择文本 <br/><br/>这次我们希望实现一个和IE一模一样的查找功能，以对Web页面内的文字进行查找。 <br/><br/>文本查找要借助于TextRange对象的findText方法。但是，.Net里并没有这个对象。这是因为，.Net 2.0提供的HtmlDocument，HtmlWindow，HtmlElement等类，只不过是对原有mshtml这个COM组件的不完整封装，只提供了mshtml的部分功能。所以许多时候，我们仍旧要借助mshtml来实现我们需要的功能。好在这些.Net类都提供了DomDocument这个属性，使得我们很容易把.Net对象转换为COM对象使用。下面的代码演示了如何查找Web页面的文本。 <br/>（需要添加mshtml的引用，并加上using mshtml;） <br/>复制 保存public partial class SearchDemo : Form<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;// 建立一个查找用的TextRange（IHTMLTxtRange接口） <br/>&nbsp;&nbsp;&nbsp;&nbsp;private IHTMLTxtRange searchRange = null;<br/>&nbsp;&nbsp;&nbsp;&nbsp;public SearchDemo()<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InitializeComponent();<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;private void btnSearch_Click(object sender, EventArgs e)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// Document的DomDocument属性，就是该对象内部的COM对象。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLDocument2 document = (IHTMLDocument2) webBrowser.Document.DomDocument;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string keyword = txtKeyword.Text.Trim();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (keyword == &#34;&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// IE的查找逻辑就是，如果有选区，就从当前选区开头+1字符处开始查找；没有的话就从页面最初开始查找。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 这个逻辑其实是有点不大恰当的，我们这里不用管，和IE一致即可。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (document.sel&#101;ction.type.ToLower() != &#34;none&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchRange = (IHTMLTxtRange) document.sel&#101;ction.cr&#101;ateRange();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchRange.collapse(true);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchRange.moveStart(&#34;character&#34;, 1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLBodyElement body = (IHTMLBodyElement) document.body;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchRange = (IHTMLTxtRange) body.cr&#101;ateTextRange();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 如果找到了，就选取（高亮显示）该关键字；否则弹出消息。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (searchRange.findText(keyword, 1, 0))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;searchRange.sel&#101;ct();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox.Show(&#34;已搜索到文档结尾。&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>到此为止，简单的查找就搞定了。至于替换功能，看了下一个例子，我相信你就可以触类旁通轻松搞定了。 <br/><br/><br/>Study Case 4：高亮显示 <br/><br/>上一个例子中我们学会了查找文本——究跟到底，对Web页面还是只读不写。那么，如果说要把所有的搜索结果高亮显示呢？我们很快会想到把所有匹配的文字颜色、背景改一下就可以了。 <br/><br/>首先想到的可能是直接修改HTML文本吧……但是，与SourceCode的高亮显示不同，我们需要并且只需要高亮页面中的文本部分。HTML标签、脚本代码等等是绝对不应该去改动的。因此我们不能把整个页面的Source Code读进来然后replace，那样有破坏HTML文件结构的可能；我们只能在能够分离出文本与其他内容（标签，脚本……）的前提下进行。 <br/><br/>具体方法有很多，下面提供两个比较简单的方法。 <br/><br/>方法一：使用TextRange（IHTMLTxtRange） <br/><br/>有了上一个Case的基础，相信大家立刻会想到使用TextRange。没错，TextRange除了提供查找方法之外，还提供了一个pasteHTML方法，以指定的HTML文本替换当前TextRange中的内容。代码片断如下： <br/>复制 保存public partial class HilightDemo : Form<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;// 定义高亮显示效果的标签。 <br/>&nbsp;&nbsp;&nbsp;&nbsp;string tagBefore = &#34;&lt;span style=&#39;background-color:yellow;color:black&#39;&gt;&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;string tagAfter = &#34;&lt;/span&gt;&#34;;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;// …… <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;private void btnHilight_Click(object sender, EventArgs e)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HtmlDocument htmlDoc = webBrowser.Document;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string keyword = txtKeyword.Text.Trim();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (keyword == &#34;&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;object oTextRange = htmlDoc.Body.InvokeMember(&#34;cr&#101;ateTextRange&#34;);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;mshtml.IHTMLTxtRange txtrange = oTextRange as mshtml.IHTMLTxtRange;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while (txtrange.findText(keyword, 1, 4))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;try<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;txtrange.pasteHTML(tagBefore + keyword + tagAfter);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;catch { }<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;txtrange.collapse(false);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>※这段代码里获取IHTMLTxtRange的方式和上面的例子稍稍不同，其实所谓条条大路通罗马，本质是一样的。 <br/><br/><br/>方法二：使用DOM（文档对象模型） <br/><br/>将HTML文档解析为DOM，然后遍历每个节点，在其中搜索关键字并进行相应替换处理即可。 <br/>复制 保存public partial class HilightDemo : Form<br/>{<br/>&nbsp;&nbsp;&nbsp;&nbsp;//…… <br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;private void btnHilight_Click(object sender, EventArgs e)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HTMLDocument document = (HTMLDocument) webBrowser.Document.DomDocument;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLDOMNode bodyNode = (IHTMLDOMNode) webBrowser.Document.Body.DomElement;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string keyword = txtKeyword.Text.Trim();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (keyword == &#34;&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HilightText(document, bodyNode, keyword);<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;private void HilightText(HTMLDocument document, IHTMLDOMNode node, string keyword)<br/>&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// nodeType = 3：text节点 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (node.nodeType == 3)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string nodeText = node.nodeValue.ToString();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 如果找到了关键字 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (nodeText.Contains(keyword))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLDOMNode parentNode = node.parentNode;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 将关键字作为分隔符，将文本分离，并逐个添加到原text节点的父节点 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;string[] result = nodeText.Split(new string[] { keyword }, StringSplitOptions.None);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i &lt; result.Length - 1; i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (result[i] != &#34;&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLDOMNode txtNode = document.cr&#101;ateTextNode(result[i]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parentNode.ins&#101;rtBefore(txtNode, node);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLDOMNode o&#114;gNode = document.cr&#101;ateTextNode(keyword);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLDOMNode hilightedNode = (IHTMLDOMNode) document.cr&#101;ateElement(&#34;SPAN&#34;);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLStyle style = ((IHTMLElement) hilightedNode).style;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;style.color = &#34;black&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;style.backgroundColor = &#34;yellow&#34;;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hilightedNode.appendChild(orgNode);<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parentNode.ins&#101;rtBefore(hilightedNode, node);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (result[result.Length - 1] != &#34;&#34;)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLDOMNode postNode = document.cr&#101;ateTextNode(result[result.Length - 1]);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parentNode.ins&#101;rtBefore(postNode, node);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;parentNode.removeChild(node);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} // End of nodeText.Contains(keyword) <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 如果不是text节点，则递归搜索其子节点 <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;IHTMLDOMChildrenCollection childNodes = node.childNodes as IHTMLDOMChildrenCollection;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;foreach (IHTMLDOMNode n in childNodes)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HilightText(document, n, keyword);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/>&nbsp;&nbsp;&nbsp;&nbsp;}<br/>}<br/><br/>上面的两段代码都是为了清晰易懂而精简得不能再简的，有很多地方很不完善。比如，没考虑到如何从高亮显示状态复原；也没有大小写匹配等等。当然，掌握了原理之后相信这些都不会太难。 <br/><br/>这两种方法各有优缺点： <br/>使用TextRange较轻量迅速，而且有一个特长，就是可以把跨标签（Tag）的关键字挑出来。例如，有这么一段HTML： <br/>阅读 编辑 运行 复制 保存&lt;b&gt;Hel&lt;/b&gt;lo World!<br/>&lt;b&gt;Hel&lt;/b&gt;lo World! <br/>先不管作者出于什么目的让Hel三个字母成为粗体，总之显示在页面上的是一句“Hello World!”。在我们希望高亮页面中的“Hello”这个关键字时，如果用DOM分析的话，会得出含有“Hel”的&lt;b&gt;节点和文本节点“lo World!”两个节点，因此无法将其挑出来。而TextRange则能正确识别，将其设置为高亮。因此也可以说TextRange是只和文本有关，和HTML语法结构无关的对象。 <br/><br/>但是，TextRange也有其致命缺点，加亮容易，反向的话就很难。换句话说，去除高亮显示的时候不能再用TextRange，而需要采用其他方法。 <br/><br/>而DOM方法则正好相反， 由于DOM的树状结构特性，虽然不能（或者很难）跨越Tag搜索关键字，但是去除高亮显示并不繁琐。 <br/><br/><br/>Study Case 5：与脚本的互操作 <br/><br/>在Case 1当中，我们已经看到，Web页面的HTML元素的事件，可以由Windows Form端来响应，可以在某种程度上看作是Web页面调用WinForm；那么反过来，WinForm除了可以直接访问Web页面的HTML元素之外，能否调用Web页面里的各种Script呢？ <br/><br/>首先是调用Web页面的脚本中已经定义好的函数。假设HTML中有如下Javascript： <br/>复制 保存function DoAdd(a, b) {<br/>&nbsp;&nbsp;&nbsp;&nbsp;return a + b;<br/>}<br/><br/>那么，我们要在WinForm调用它，只需如下代码即可： <br/>复制 保存object oSum = webBrowser.Document.InvokeScript(&#34;DoAdd&#34;, new object[] { 1, 2 });<br/>int sum = Convert.ToInt32(oSum);<br/><br/>其次，如果我们想执行一段Web页面中原本没有的脚本，该怎么做呢？这次.Net的类没有提供，看来还要依靠COM了。IHTMLWindow2可以将任意的字符串作为脚本代码来执行。 <br/>string scriptline01 = @&#34;function ShowPageInfo() {&#34;;<br/>string scriptline02 = @&#34;&nbsp;&nbsp;&nbsp;&nbsp; var numLinks = document.links.length; &#34;;<br/>string scriptline03 = @&#34;&nbsp;&nbsp;&nbsp;&nbsp; var numForms = document.forms.length; &#34;;<br/>string scriptline04 = @&#34;&nbsp;&nbsp;&nbsp;&nbsp; var numImages = document.images.length; &#34;;<br/>string scriptline05 = @&#34;&nbsp;&nbsp;&nbsp;&nbsp; var numScripts = document.scripts.length; &#34;;<br/>string scriptline06 = @&#34;&nbsp;&nbsp;&nbsp;&nbsp; alert(&#39;网页的统计结果：\r\n链接数：&#39; + numLinks + &#34;;<br/>string scriptline07 = @&#34;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;\r\n表单数：&#39; + numForms + &#34;;<br/>string scriptline08 = @&#34;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;\r\n图像数：&#39; + numImages + &#34;;<br/>string scriptline09 = @&#34;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#39;\r\n脚本数：&#39; + numScripts);}&#34;;<br/>string scriptline10 = @&#34;ShowPageInfo();&#34;;<br/><br/>string strScript = scriptline01 + scriptline02 + scriptline03 + scriptline04 + scriptline05 +<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; scriptline06 + scriptline07 + scriptline08 + scriptline09 + scriptline10;<br/><br/>IHTMLWindow2 win = (IHTMLWindow2)webBrowser.Document.Window.DomWindow;<br/>win.execScript(strScript, &#34;Javascript&#34;);<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=33" /> 
	  <id>http://blog.51haipai.com/default.asp?id=33</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C# OpenAPI API 通过 文件图标 ]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2009-09-24T10:09:12+08:00</updated>
	  <published>2009-09-24T10:09:12+08:00</published>
		  <summary type="html"><![CDATA[在C#中要获取各种文件的图标，可以通过API调用来完成。主要的函数是SHGetFileInfo.在C#中操作的方式如下 : <br/>&nbsp;&nbsp;第一步：准备SHGetFileInfo需要的各种参数<br/><br/>&nbsp;&nbsp;1.FileInfoStruct<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://blog.51haipai.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>[StructLayout( LayoutKind.Sequential)]<br/>public&nbsp;&nbsp; struct&nbsp;&nbsp;FileInfoStruct<br/>...{<br/>public&nbsp;&nbsp;IntPtr hIcon;<br/>public&nbsp;&nbsp; int&nbsp;&nbsp;iIcon;<br/>public&nbsp;&nbsp; int&nbsp;&nbsp;dwAttributes;<br/>[ MarshalAs( UnmanagedType.ByValTStr, SizeConst = 260 )]<br/>public&nbsp;&nbsp; string&nbsp;&nbsp;szDisplayName;<br/>[ MarshalAs( UnmanagedType.ByValTStr, SizeConst = 80 )]<br/>public&nbsp;&nbsp; string&nbsp;&nbsp;szTypeName;<br/>} 2.FileInfoFlags<br/>public&nbsp;&nbsp; enum&nbsp;&nbsp;FileInfoFlags :&nbsp;&nbsp;int<br/>...{<br/>SHGFI_ICON&nbsp;&nbsp;= 0x000000100 ,&nbsp;&nbsp;//&nbsp;&nbsp;get icon <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_DISPLAYNAME&nbsp;&nbsp;= 0x000000200 ,&nbsp;&nbsp;//&nbsp;&nbsp;get display name <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_TYPENAME&nbsp;&nbsp;= 0x000000400 ,&nbsp;&nbsp;//&nbsp;&nbsp;get type name <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_ATTRIBUTES&nbsp;&nbsp;= 0x000000800 ,&nbsp;&nbsp;//&nbsp;&nbsp;get attributes <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_ICONLOCATION&nbsp;&nbsp;= 0x000001000 ,&nbsp;&nbsp;//&nbsp;&nbsp;get icon location <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_EXETYPE&nbsp;&nbsp;= 0x000002000 ,&nbsp;&nbsp;//&nbsp;&nbsp;return exe type <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_SYSICONINDEX&nbsp;&nbsp;= 0x000004000 ,&nbsp;&nbsp;//&nbsp;&nbsp;get system icon index <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_LINKOVERLAY&nbsp;&nbsp;= 0x000008000 ,&nbsp;&nbsp;//&nbsp;&nbsp;put a link overlay on icon&nbsp;&nbsp;SHGFI_Sel&#101;ctED&nbsp;&nbsp;= 0x000010000 ,&nbsp;&nbsp;//&nbsp;&nbsp;show icon in sel&#101;cted state <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_ATTR_SPECIFIED&nbsp;&nbsp;= 0x000020000 ,&nbsp;&nbsp;//&nbsp;&nbsp;get only specified attributes <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_LARGEICON&nbsp;&nbsp;= 0x000000000 ,&nbsp;&nbsp;//&nbsp;&nbsp;get large icon <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_SMALLICON&nbsp;&nbsp;= 0x000000001 ,&nbsp;&nbsp;//&nbsp;&nbsp;get small icon <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_OPENICON&nbsp;&nbsp;= 0x000000002 ,&nbsp;&nbsp;//&nbsp;&nbsp;get open icon <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_SHELLICONSIZE&nbsp;&nbsp;= 0x000000004 ,&nbsp;&nbsp;//&nbsp;&nbsp;get shell size icon <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_PIDL&nbsp;&nbsp;= 0x000000008 ,&nbsp;&nbsp;//&nbsp;&nbsp;pszPath is a pidl <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_USEFILEATTRIBUTES&nbsp;&nbsp;= 0x000000010 ,&nbsp;&nbsp;//&nbsp;&nbsp;use passed dwFileAttribute <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_ADDOVERLAYS&nbsp;&nbsp;= 0x000000020 ,&nbsp;&nbsp;//&nbsp;&nbsp;apply the appropriate overlays <br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SHGFI_OVERLAYINDEX&nbsp;&nbsp;= 0x000000040&nbsp;&nbsp; //&nbsp;&nbsp;Get the index of the overlay <br/>&nbsp;&nbsp;&nbsp;&nbsp;} 3.FileAttributeFlags(这个.net中好像已经有了)<br/>public&nbsp;&nbsp; enum&nbsp;&nbsp;FileAttributeFlags :&nbsp;&nbsp;int<br/>...{<br/>FILE_ATTRIBUTE_READONLY&nbsp;&nbsp;= 0x00000001 ,<br/>FILE_ATTRIBUTE_HIDDEN&nbsp;&nbsp;= 0x00000002 ,<br/>FILE_ATTRIBUTE_SYSTEM&nbsp;&nbsp;= 0x00000004 ,<br/>FILE_ATTRIBUTE_DIRECTORY&nbsp;&nbsp;= 0x00000010 ,<br/>FILE_ATTRIBUTE_ARCHIVE&nbsp;&nbsp;= 0x00000020 ,<br/>FILE_ATTRIBUTE_DEVICE&nbsp;&nbsp;= 0x00000040 ,<br/>FILE_ATTRIBUTE_NORMAL&nbsp;&nbsp;= 0x00000080 ,<br/>FILE_ATTRIBUTE_TEMPORARY&nbsp;&nbsp;= 0x00000100 ,<br/>FILE_ATTRIBUTE_SPARSE_FILE&nbsp;&nbsp;= 0x00000200 ,<br/>FILE_ATTRIBUTE_REPARSE_POINT&nbsp;&nbsp;= 0x00000400 ,<br/>FILE_ATTRIBUTE_COMPRESSED&nbsp;&nbsp;= 0x00000800 ,<br/>FILE_ATTRIBUTE_OFFLINE&nbsp;&nbsp;= 0x00001000 ,<br/>FILE_ATTRIBUTE_NOT_CONTENT_INDEXED&nbsp;&nbsp;= 0x00002000 ,<br/>FILE_ATTRIBUTE_ENCRYPTED&nbsp;&nbsp;= 0x00004000<br/>}&nbsp;&nbsp;<br/></div></div><br/><br/>然后 开始准备调用SHELL API了 : <br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://blog.51haipai.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>[DllImport(&#34;shell32.dll &#34; , EntryPoint =&#34;SHGetFileInfo&#34;)]<br/>public static extern int GetFileInfo( string&nbsp;&nbsp;pszPath,&nbsp;&nbsp;int&nbsp;&nbsp;dwFileAttributes,<br/>ref&nbsp;&nbsp;FileInfoStruct psfi,&nbsp;&nbsp;int&nbsp;&nbsp;cbFileInfo, int&nbsp;&nbsp;uFlags); <br/></div></div><br/>&nbsp;&nbsp;好了现在一切都准备好了 我们现在通过下面的两个方法来获取图标<br/><br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://blog.51haipai.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"><br/>public static Icon GetLargeIcon(string pFilePath)<br/>...{<br/>FileInfoStruct _info&nbsp;&nbsp;= new&nbsp;&nbsp;FileInfoStruct();<br/>Win32API.GetFileInfo(pFilePath,&nbsp;&nbsp;0 ,&nbsp;&nbsp;ref&nbsp;&nbsp;_info, Marshal.SizeOf(_info),<br/>( int )(FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_LARGEICON));<br/>try<br/>...&nbsp;&nbsp; catch<br/>...{<br/>return&nbsp;&nbsp; null ;<br/>}<br/>}<br/>public static Icon GetSmallIcon(string pFilePath)<br/>...{<br/>FileInfoStruct _info&nbsp;&nbsp;= new&nbsp;&nbsp;FileInfoStruct();<br/>Win32API.GetFileInfo(pFilePath,&nbsp;&nbsp;0 ,&nbsp;&nbsp;ref&nbsp;&nbsp;_info, Marshal.SizeOf(_info),<br/>( int )(FileInfoFlags.SHGFI_ICON | FileInfoFlags.SHGFI_SMALLICON));<br/>try<br/>...<br/>catch<br/>...{<br/>return&nbsp;&nbsp; null ;<br/>}<br/>}<br/></div></div><br/>&nbsp;&nbsp;呵呵 工作就做完了。但是我发现这样取出来的Icon在TreeView 中显示的时候特别难看。但是目前也没有什么好方法。毕竟图标太多了。]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=32" /> 
	  <id>http://blog.51haipai.com/default.asp?id=32</id>
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[根据中心点将某点旋转n度 c#]]></title>
	  <author>
		 <name>ufo1199078</name>
		 <uri>http://blog.51haipai.com/</uri>
		 <email>admin1@51haipai.com</email>
	  </author>
	  <category term="" scheme="http://blog.51haipai.com/default.asp?cateID=9" label="技术文章" /> 
	  <updated>2009-08-13T23:12:05+08:00</updated>
	  <published>2009-08-13T23:12:05+08:00</published>
		  <summary type="html"><![CDATA[根据中心点将某点旋转n度<br/><div class="UBBPanel codePanel"><div class="UBBTitle"><img src="http://blog.51haipai.com/images/code.gif" style="margin:0px 2px -3px 0px" alt="程序代码"/> 程序代码</div><div class="UBBContent"> <br/>/// &lt;summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// 根据中心点将某点旋转n度<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;/summary&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;center&#34;&gt;中心点&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;point&#34;&gt;旋转点&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;param name=&#34;angle&#34;&gt;旋转角度&lt;/param&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/// &lt;returns&gt;旋转后的点&lt;/returns&gt;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;static PointF Rotate(PointF center, PointF point, float angle)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Drawing.Drawing2D.Matrix matrix = new System.Drawing.Drawing2D.Matrix();<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matrix.Rotate(angle);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 构造一个逆时针旋转的矩阵<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PointF[] points = { new PointF(point.X - center.X, point.Y - center.Y) };&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 把坐标原点移到&#39;那个原点&#39;那里<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;matrix.TransformPoints(points);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // 旋转<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new PointF(center.X + points[0].X, center.Y + points[0].Y);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 把坐标原点移回去<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br/></div></div> ]]></summary>
	  <link rel="alternate" type="text/html" href="http://blog.51haipai.com/article.asp?id=31" /> 
	  <id>http://blog.51haipai.com/default.asp?id=31</id>
  </entry>	
		
</feed>
