天涯一飘絮

导航

统计
公告
 

2011年6月22日

这里有一个 XML 架构验证类

using System;
using System.Collections;
using System.IO;
using System.Xml;
using System.Xml.Schema;

namespace RapidTier
{
    
/// <summary>
    
/// Helper class to perform schema validations.
    
/// </summary>

    public sealed class SchemaValidator
    
{
        
#region Private members
        
        
/// <summary>
        
/// The schemas that will be used for validation.
        
/// </summary>

        private ArrayList schemas = new ArrayList(2);

        
/// <summary>
        
/// The errors detected during the validation.
        
/// </summary>

        private ArrayList errors = new ArrayList(5);

        
/// <summary>
        
/// Whether the document is valid or not.
        
/// </summary>

        private bool isValid;

        
#endregion


        
#region Constructors

        
/// <summary>
        
/// Creates an instance of the SchemaValidator using the document and the schemas.
        
/// </summary>
        
/// <param name="document">The document to validate.</param>
        
/// <param name="schemas">A list of schemas to validate the document against.</param>

        public SchemaValidator( string document, params Stream[] schemas )
        
{
            
this.schemas.Add( document );
            
foreach(Stream s in schemas)
            
{
                
this.schemas.Add( s );
            }

            isValid 
= true;
        }


        
#endregion


        
#region Public members

        
/// <summary>
        
/// Validates the document and returns the result of the validation.
        
/// </summary>
        
/// <returns><c>true</c> if the document have succeeded the validation, otherwise <c>false</c>.</returns>

        public bool Validate()
        
{
            errors.Clear();
            XmlValidatingReader vr 
= null;
            
object doc = schemas[0];
            
if ( doc is Stream)
            
{
                vr 
= new XmlValidatingReader( (Stream)doc, XmlNodeType.Element, null );
            }

            
else if ( doc is String )
            
{
                vr 
= new XmlValidatingReader( (string)doc, XmlNodeType.Element, null );
            }


            
try
            
{
                
for(int i=1;i<schemas.Count;i++)
                
{
                    vr.Schemas.Add( 
nullnew XmlTextReader( (Stream)schemas[i] ) );
                }


                vr.ValidationEventHandler 
+= new System.Xml.Schema.ValidationEventHandler(ValidationEventHandler);
            
                
while( vr.Read() );
                
return isValid;
            }

            
finally
            
{
                vr.Close();
            }

        }


        
/// <summary>
        
/// Contains the validation errors encountered in the last validation operation.
        
/// </summary>

        public ValidationEventArgs[] Errors
        
{
            
get 
            

                
return (ValidationEventArgs[])errors.ToArray(typeof(ValidationEventArgs) ); 
            }

        }


        
/// <summary>
        
/// Helper method to capture the event handlers.
        
/// </summary>
        
/// <param name="sender">The sender of the event.</param>
        
/// <param name="e">The information about the event.</param>

        private void ValidationEventHandler(object sender, System.Xml.Schema.ValidationEventArgs e)
        
{
            errors.Add( e );
            
if ( e.Severity == XmlSeverityType.Warning )
            
{
                
return;
            }

            isValid 
= false;
        }


        
#endregion

    }

}

posted @ 2011-06-22 18:02 冰云 阅读(42) 评论(0) 编辑
 
一、MSXML解析器及.Net程序集对Xml验证的支持
  XML规范不仅描述了Xml数据的格式和语法,而且为处理Xml数据指定了一个两层的用户体系结构。第一层是Xml解析器(也被称为Xml处理程序)。XML解析器负责检查一个Xml文档,确保文档是格式正确的。当Xml文档有一个相关的dtd或者模式XDR或者架构Schema时,解析器也要确保文档时有效的。Xml解析器的行为可以定义为试图减轻应用程序处理xml数据的负担,同时把Xml数据的内容和结构以规定的方式送到第二层(Xml应用层)。 

  MSXML3就是一个我们曾常使用的解析器。msXml3解析器执行前面提到的所有检查。如果你使用过MSXML3,你可能已经对使用validateOnParse属性或者validate()方法来根据DTD或者XDR schema验证Xml文档非常熟悉。有了validateOnParse属性,一个文档在解析成DOM结构时会被验证,而validate()方法则允许对一个已经被解析并装载完的文档进行运行时验证。 

  对于Asp.net,微软构造了一个全新的、基于程序集的解析器以取代MSXML3,这个程序集在System.Xml名字空间中实现,该名字空间与同.Net框架一起安装的System.Xml集相关联。要使用.net框架的Xml功能,只需要在工程中引用System.Xml名字空间。 

  Asp.net依靠System.Xml集进行Xml解析,程序集中丰富的类、接口等对象及其方法、属性等为操作xml及其相关技术(规范)提供了强大的支持。使用.Net支持的多种程序语言(Visual C#、VB.Net等),可以很容易地对Xml文档执行XMLDR schema 或者W3C Xml Schema 验证,而且,验证方式变得更加强大而灵活。。 

  虽然你仍然可以在.Net语言中调用MSXML3,但这样做将无法充分发挥.Net的强大功能。 

  二、使用XmlValidatingReader类验证读取Xml文档
   .Net程序集System.Xml包含了许多类,这些类用于在.Net平台上提供Xml功能。 XmlValidatingReader类(XmlReader类的一种实现)就是其中的一种。在将xml文档或Xml片段读入系统时,该类提供验证支持。它实现 DTD、XML 数据简化 (XDR) 架构和 XML 架构定义语言 (XSD) 架构等规范所定义的有效性约束。 

  1、构造XmlValidatingReade类对象实例 
  初始化XmlValidatingReader类的新实例有多种方法,最常用的一种是传入XmlReader类型的参数: 

public XmlValidatingReader( XmlReader reader);
XmlValidatingReader vReader=new XmlValidatingReader(XmlTextReader xtr);


  作为XmlReader的具体实现之一,XmlTextReader类提供对Xml文档的快速、只前进、无缓存的读取,而XmlValidatingReader可以使用从XmlTextReader所返回的所有内容,并进一步提供验证支持。当然,如果一切正常,该过程不会造成信息丢失,从给定的 XmlReader 返回的所有节点和属性也都从此验证读取器返回。未从基础读取器返回的新节点可能由此读取器添加(例如,实体引用的默认属性和子级)。 

  2、指定验证类型 
  从前面已经能知道,有三种规范用于对xml文档执行验证。它们是DTD、XDR及XmlSchema。所以,在执行验证之前,需要确定验证的类型,这通过设置ValidatingReader类的ValidationType属性来完成: 

vReader.ValidationType=ValidationType.Schema.


  这行代码将验证声明为XSD Schema。 

  3、使用XmlSchemaCollection类缓存架构 

  如果需要根据XDR或者XSD Schema进行验证,可以使用XmlSchemaCollection类来缓存架构,这样将可以提高性能。XmlSchemaCollection类的Add方法加载架构,同时,架构会与命名空间 URI 关联。对于"XML 架构"的源文件(.xsd)来说,这通常会是架构的 targetNamespace 属性。 

XmlSchemaCollection xsc=new XmlSchemaCollection();
Xsc.Add("http://www.tuha.net","vschema.xsd");


  当然,如果架构内联于Xml文档中,就不需要这样做了。 

  4、关联架构缓存 

  在向XmlSchemaCollection中添加完schema之后,XmlValidatingReader并不能自动识别并使用schema,还需要将两者关联起来。通过使用读取器的 Schemas 属性引用缓存在 XmlSchemaCollection 中的架构文件来完成这一过程: 

vReader.Schemas.Add(xsc);



  5、ValidationEventHandler事件处理程序回调 
  在使用ValidatingReader执行验证读取Xml文档时,可能发生意外。这时,可以通过ValidationEventHandler 回调报告验证错误和警告。ValidationEventHandler 事件用于设置一个事件处理程序以接收有关文档类型定义 (DTD)、数据简化 XML (XDR) 和 XML 架构定义语言 (XSD) 架构验证错误的信息。 

  不过,如果不提供 ValidationEventHandler,你依然可以使用通用的异常处理机制来捕捉错误。当发生分析错误时,将通过引发 XmlException 报告错误。如果发生验证错误,将引发 XmlSchemaException。当然,任何一种异常,将无法重新启动 XmlValidatingReader。 

  指定事件及回调用遵循通用的做法:通过+=将XmlValidatingReader与事件处理程序ValidationEventHandler连接起来: 

vReader.ValidationEventHandler+=new ValidationEventHandler(vCallback);



  参数vCallback是回调处理程序的方法名称,这个方法必须包含一个ValidationEventArgs类型的参数,ValidationEventArgs 类具有针对以下各项的属性:文本消息,表示 Error 或 Warning 的 XmlSeverityType 枚举,以及包含与特定验证错误关联的 XmlSchemaException 信息的异常。 


private void vCallback(object sender,ValidationEventArgs args)
{
//发生错误时的处理代码
}


  这一步不是必须的,如果你能保证错误不会发生或者发生就发生去吧! 

  6、执行验证读操作 

  做完以上准备工作后,你可以使用XmlValidatingReader类的读方法开始验证读取Xml文档了。可以是 Read、ReadInnerXml、ReadOuterXml 中的任一种以及其他将改变接点的方法,如Skip()方法。这时,都将发生验证。 

While(vReader.Read())
{
//处理读取的内容
}



  三、实例
  综合以上知识,下面创建一个Windows Console控制台应用程序,用于在商务领域中处理产品数据,一般地,不同公司产品数据将遵循一定的格式,这里通过XSD 

  Xsd,该架构文件对xml文档提供结构信息,用于在数据交换时遵循一致的标准 

<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="Products" targetNamespace="http://www.tuha.net" elementFormDefault="qualified"
xmlns="http://www.tuha.net" xmlns:mstns="http://www.tuha.net"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="Products" type="a1"></xs:element>
<xs:complexType name="b1">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="Type" type="xs:string" />
<xs:element name="Usefor" type="xs:string" />
</xs:sequence>
</xs:complexType>
<xs:complexType name="a1">
<xs:sequence maxOccurs="unbounded">
<xs:element name="Item" type="b1" />
</xs:sequence>
</xs:complexType>
</xs:schema>


  根据上面的架构文件,下面构造了一个产品数据xml文档,这里使用了产品库内容的部分段落,为方便测试,让它成为了一个完整的xml文档: 

<?xml version="1.0" encoding="utf-8" ?>
<Products xmlns="http://www.tuha.net">
<Item>
<Name>Talking Online</Name>
<Type>Fittings</Type>
<Usefor>Communicate</Usefor>
</Item>
<Item>
<Name>Debugging Online</Name>
<Type>Professional</Type>
<Usefor>Machine</Usefor>
</Item>
</Products>


  下面的应用程序对xml文档进行处理,并验证其数据是否是符合该架构的有效的! 

using System;
using System.IO;
using System.Xml;
using System.Xml.Schema;
namespace MyXmlValidationgReader
{
class Class1
{
static bool sign=true;
[STAThread]
static void Main(string[] args)
{
XmlTextReader xtr=null;
XmlValidatingReader xvr=null;
string xmlFile="http://www.cnblogs.com/Products.xml";//xml源文档
string xsdFile="http://www.cnblogs.com/Products.xsd";//xsd架构文档
xtr=new XmlTextReader(xmlFile);//构造非验证读取器
XmlSchemaCollection xsc=new XmlSchemaCollection();//构造Schema架构缓存
xsc.Add("http://www.tuha.net",xsdFile);//在缓存中添加架构文件及对应名字空间
xvr=new XmlValidatingReader(xtr);//构造验证读取器
xvr.Schemas.Add(xsc);//关联验证读取器与架构集合
xvr.ValidationType=ValidationType.Schema;//设置验证类型为Schema架构
xvr.ValidationEventHandler+=new ValidationEventHandler(vCallback);
//发生错误时的事件处理程序
while(xvr.Read())//执行读操作
{

Console.Write("Finished! "+sign.ToString());
}
private static void vCallback(object sender,ValidationEventArgs args)
//错误回调程序
{
sign=false;//改变标记
}
}
}
posted @ 2011-06-22 17:38 冰云 阅读(321) 评论(0) 编辑

2011年1月9日

1 几种调用扫描仪的方案http://hi.baidu.com/scutsolo/blog/item/89f9f0fadeb6c514a9d31170.html

2.用imgscan.ocx来扫描图像(转) http://blog.csdn.net/trnbo/archive/2004/11/09/174162.aspx

3.使用WIA Scripting
http://www.codeproject.com/dotnet/wiascriptingdotnet.asp

用twain_32.dll 的地址应该是
http://www.codeproject.com/dotnet/twaindotnet.asp?msg=333602&target=twain

4.http://blog.csdn.net/fenin/archive/2009/06/02/4237385.aspx在C#中使用WIA获取扫描仪数据(一)

5.http://www.cnblogs.com/bb5059619/archive/2008/07/29/1255916.html

6.http://space.cnblogs.com/question/13964/

7.利用wia和imgscan从扫描仪获取图像(vb6 c#)

 

wiaScan.rar

Scan_Twain.rar

twaingui_src.zip

imaScanimgedit.rar

posted @ 2011-01-09 17:18 冰云 阅读(522) 评论(0) 编辑
 

在“随风飘散” 博客里面,介绍了一个不错的DataGridView数据窗口控件《DataGridView数据窗口控件开发方法及其源码提供下载》,这种控件在有些场合下,还是非常直观的。因为,在一般要求客户录入数据的地方,一般有两种途径,其一是通过弹出一个新的窗口,在里面列出各种需要输入的要素,然后保存的,如下图所示;

 

其二就是直接在DataGridView中直接输入。这两种方式各有优劣,本文介绍采用该控件实现第二种模式的数据数据。如下图所示

 

 这种方式,直接通过在DataGridView中下拉列表或者文本框中输入内容,每列的数据可以联动或者做限制,实现用户数据的约束及规范化。

控件只要接受了DataTable的DataSource之后,会根据列的HeadText内容,显示表格的标题及内容,应用还是比较直观方便的。

        private void BindGridViewData(DataTable dt, DataTable dtNoRelation)
        {
            organTable 
= dt;
            noRelationTable 
= dtNoRelation;

            DataGridView dataGridView1 
= new DataGridView();
            
this.groupBox1.Controls.Clear();
            
this.groupBox1.Controls.Add(dataGridView1);
            dataGridView1.Dock 
= DockStyle.Fill;
            dataGridView1.CellValueChanged 
+=new DataGridViewCellEventHandler(organDataGridView_CellValueChanged);
            dataGridView1.UserDeletedRow 
+= new DataGridViewRowEventHandler(organDataGridView_UserDeletedRow);

            dataGridView1.AutoGenerateColumns 
= false;
            dataGridView1.Rows.Clear();
            dataGridView1.Columns.Clear();

            DataGridViewDataWindowColumn col1 
= new DataGridViewDataWindowColumn();
            col1.HeaderText 
= "机构代码";
            col1.Name 
= "机构代码";   

            
//下拉列表的数据
            col1.DataSource = GetDataTable(dtNoRelation);
            dataGridView1.Columns.Add(col1);

            DataGridViewTextBoxColumn col2 
= new DataGridViewTextBoxColumn();
            col2.HeaderText 
= "机构名称";
            col2.Name 
= "机构名称";
            col2.Width 
= 300;
            col2.ReadOnly 
= true;
            dataGridView1.Columns.Add(col2);

            
if (dt != null)
            {
                
foreach (DataRow dr in dt.Rows)
                {
                    
string value = dr[0].ToString();
                    DataGridViewRow row 
= new DataGridViewRow();
                    DataGridViewDataWindowCell cell 
= new DataGridViewDataWindowCell();
                    cell.Value 
= value;
                    row.Cells.Add(cell);
                    cell.DropDownHeight 
= 400;
                    cell.DropDownWidth 
= 300;

                    DataGridViewTextBoxCell cell2 
= new DataGridViewTextBoxCell();
                    cell2.Value 
= dr[1].ToString();
                    row.Cells.Add(cell2);
                    dataGridView1.Rows.Add(row);
                }
            }
        }

 

 

由于列之间的数据输入等相关的影响需要处理,因此控件的处理方式是通过委托函数进行处理,如上面的部分代码中就是处理这些事件的。

            dataGridView1.CellValueChanged +=new DataGridViewCellEventHandler(organDataGridView_CellValueChanged);
            dataGridView1.UserDeletedRow 
+= new DataGridViewRowEventHandler(organDataGridView_UserDeletedRow);

 

 

由于本例子是通过输入内容后,及时更新数据库及控件的显示,因此需要对该事件进行处理,处理代码如下所示。

        private void organDataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            DataGridView organDataGridView 
= sender as DataGridView;
            
if (!organDataGridView.IsCurrentCellInEditMode)
                
return;

            
#region 显示关联机构名称
            
if (e.RowIndex > -1)
            {
                
if (organDataGridView.CurrentCell.Value == System.DBNull.Value)
                {
                    
return;
                }

                
if (e.ColumnIndex == 0)
                {
                    DataGridViewCell cell 
= organDataGridView.Rows[e.RowIndex].Cells["机构代码"];
                    
if (cell.Value == null)
                        
return;
                    
string organCode = cell.Value.ToString();
                    
string organName = GetOrganName(organTable, organCode);
                    
if (string.IsNullOrEmpty(organName))
                    {
                        organName 
= GetOrganName(noRelationTable, organCode);
                    }
                    organDataGridView.Rows[e.RowIndex].Cells[
"机构名称"].Value = organName;
                }
            } 
            
#endregion

            
if (this.treeView1.SelectedNode != null)
            {
                
string gjOrganCode = this.treeView1.SelectedNode.Tag.ToString();
                
if (!string.IsNullOrEmpty(gjOrganCode))
                {
                    
string yctOrganCode = organDataGridView.CurrentCell.Value.ToString();

                    OrganCodeMapDAL organMapDal 
= new OrganCodeMapDAL();
                    organMapDal.UpdateOrganMapData(gjOrganCode, yctOrganCode);
                }
            }
        }

        
private void organDataGridView_UserDeletedRow(object sender, DataGridViewRowEventArgs e)
        {
            DataGridView organDataGridView 
= sender as DataGridView;
            
string organCode = e.Row.Cells[0].Value.ToString();
            OrganCodeMapDAL organMapDal 
= new OrganCodeMapDAL();
            organMapDal.DeleteOrganMapData(organCode);
        }

 

 

另外,该控件还提供了一个用于对话框窗体中的复杂下拉列表的数据显示方式,控件支持内容的过滤检索,非常方便实用,如下所示

 

 

该控件的使用代码如下所示:

        private void BindData()
        {            
            
//设置DataWindow属性
            this.dataWindow1.PopupGridAutoSize = false;
            
this.dataWindow1.DropDownHeight = 300;
            
this.dataWindow1.DropDownWidth = 240;
            
this.dataWindow1.FormattingEnabled = true;
            
this.dataWindow1.sDisplayField = "车辆编码,车牌号码";
            
this.dataWindow1.sDisplayMember = "车辆编码";
            
this.dataWindow1.sValueMember = "车辆编码";
            
this.dataWindow1.SeparatorChar = "|";

            BusDAL busDal 
= new BusDAL();
            DataTable dt 
= busDal.GetYCTBusTable(this.txtOrganName.Tag.ToString());
            
this.dataWindow1.DataSource = dt;
            
this.dataWindow1.AfterSelector += new EventHandler(dataWindow1_AfterSelector);

            
//必须在DataSource绑定之后设置该属性
            this.dataWindow1.RowFilterVisible = true;
        }

        
//选择完下拉表格后执行的事件
        private void dataWindow1_AfterSelector(object sender, EventArgs e)
        {
        }

 

posted @ 2011-01-09 17:09 冰云 阅读(200) 评论(0) 编辑
 

在开发Winform程序的时候,经常会用到等待窗口(如网络通讯、数据库连接等需要一定时间来执行的操作),这样可以给用户提供更好的体验。

         等待窗口的主要功能是一边执行需要等待的操作,一边显示一个等待界面。当执行完毕时等待界面消失。用户可以提前取消操作,还可以设置操作的最大等待时间,若超过指定时间仍没完成操作可结束当前操作。等待窗口的操作处理内容可用λ表达式,在后面的应用实例中可看到使用方法。

         实现界面如下图:

 

         等待界面主要包含的部分:

  • 等待图片;
  • 等待消息文字("正在处理数据,请稍后..."):可自定义;
  • 计时器:可设置不显示;
  • 取消返回按钮:可设置不显示;
  • 另外等待窗口显示和关闭的时候都有渐变的一个简单特效,等待窗口的颜色是在一定范围内随即的。

等待窗口实现代码:

 

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace WinForm_Test
{
    public partial class frmWaitingBox : Form
    {
        #region Properties
        private int _MaxWaitTime;
        private int _WaitTime;
        private bool _CancelEnable;
        private IAsyncResult _AsyncResult;
        private EventHandler<EventArgs> _Method;
        private bool _IsShown = true;
        private readonly int _EffectCount = 10;
        private readonly int _EffectTime = 500;
        /// <summary>
        /// 控制界面显示的特性
        /// </summary>
        private Timer _Timer;
        public string Message { get; private set; }
        public int TimeSpan { get; set; }
        public bool FormEffectEnable { get; set; }
        #endregion

        #region frmWaitingBox
        public frmWaitingBox(EventHandler<EventArgs> method,int maxWaitTime,string waitMessage,bool cancelEnable,bool timerVisable)
        {
            maxWaitTime *= 1000;
            Initialize(method, maxWaitTime,waitMessage, cancelEnable, timerVisable);
        }
        public frmWaitingBox(EventHandler<EventArgs> method)
        {
            int maxWaitTime=60*1000;
            string waitMessage = "正在处理数据,请稍后...";
            bool cancelEnable=true;
            bool timerVisable=true;
            Initialize(method, maxWaitTime,waitMessage, cancelEnable, timerVisable);
        }
        public frmWaitingBox(EventHandler<EventArgs> method, string waitMessage)
        {
            int maxWaitTime = 60 * 1000;
            bool cancelEnable = true;
            bool timerVisable = true;
            Initialize(method, maxWaitTime, waitMessage, cancelEnable, timerVisable);
        }
        public frmWaitingBox(EventHandler<EventArgs> method, bool cancelEnable, bool timerVisable)
        {
            int maxWaitTime = 60*1000;
            string waitMessage = "正在处理数据,请稍后...";
            Initialize(method, maxWaitTime,waitMessage, cancelEnable, timerVisable);
        }
        #endregion

        #region Initialize
        private void Initialize(EventHandler<EventArgs> method, int maxWaitTime,string waitMessage,bool cancelEnable, bool timerVisable)
        {
            InitializeComponent();
            //initialize form
            this.FormBorderStyle = FormBorderStyle.None;
            this.StartPosition = FormStartPosition.CenterParent;
            this.ShowInTaskbar = false;
            Color[] c = GetRandColor();
            this.panel1.BackColor = c[0];
            this.BackColor = c[1];
            this.labMessage.Text = waitMessage;
            _Timer = new Timer();
            _Timer.Interval = _EffectTime/_EffectCount;
            _Timer.Tick += _Timer_Tick;
            this.Opacity = 0;
            FormEffectEnable = true;
            //para
            TimeSpan = 500;
            Message = string.Empty;
            _CancelEnable = cancelEnable;
            _MaxWaitTime = maxWaitTime;
            _WaitTime = 0;
            _Method = method;
            this.pictureBoxCancel.Visible = _CancelEnable;
            this.labTimer.Visible = timerVisable;
            this.timer1.Interval = TimeSpan;
            this.timer1.Start();
        }
        #endregion

        #region Color
        private Color[] GetRandColor()
        {
            int rMax = 248;
            int rMin = 204;
            int gMax = 250;
            int gMin = 215;
            int bMax = 250;
            int bMin = 240;
            Random r = new Random(DateTime.Now.Millisecond);
            int r1 = r.Next(rMin, rMax);
            int r2 = r1 + 5;
            int g1 = r.Next(gMin, gMax);
            int g2 = g1 + 5;
            int b1 = r.Next(bMin, bMax);
            int b2 = b1 + 5;
            Color c1 = Color.FromArgb(r1, g1, b1);
            Color c2 = Color.FromArgb(r2, g2, b2);
            Color[] c = { c1, c2 };
            return c;
        }
        #endregion

        #region Events
        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Message = "您结束了当前操作!";
            this.Close();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            _WaitTime += TimeSpan;
            this.labTimer.Text = string.Format("{0}秒", _WaitTime / 1000);
            if (!this._AsyncResult.IsCompleted)
            {
                if (_WaitTime > _MaxWaitTime)
                {
                    Message = string.Format("处理数据超时{0}秒,结束当前操作!", _MaxWaitTime / 1000);
                    this.Close();
                }
            }
            else
            {
                this.Message = string.Empty;
                this.Close();
            }
            
        }

        private void frmWaitingBox_Shown(object sender, EventArgs e)
        {
            _AsyncResult = _Method.BeginInvoke(null, null, null, null);
            //Effect
            if (FormEffectEnable)
            {
                _Timer.Start();
            }
            else
                this.Opacity = 1;
        }
        private void frmWaitingBox_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (FormEffectEnable)
            {
                if(this.Opacity>=1)
                    e.Cancel = true;
                _Timer.Start();
            }
        }
        private void _Timer_Tick(object sender, EventArgs e)
        {
            if (_IsShown)
            {
                if (this.Opacity >= 1)
                {
                    _Timer.Stop();
                    _IsShown = false;
                }
                this.Opacity += 1.00 / _EffectCount;
            }
            else
            {
                if (this.Opacity <= 0)
                {
                    _Timer.Stop();
                    _IsShown = true;
                    this.Close();
                }
                this.Opacity -= 1.00 / _EffectCount;
            }
        }
        #endregion

        
    }
}
 

应用实例代码:

 

string res;
 DataTable dt=null;
 frmWaitingBox f = new frmWaitingBox((obj,args)=>
     {
         Thread.Sleep(5000);
         string sql = "SELECT * FROM [test].[dbo].[studentInfo]";
         SQLHelper sqlHelper=new SQLHelper();
         dt = sqlHelper.ExecuteSqlStr(sql,out res);
     });
 f.ShowDialog(this);

 dataGridView1.DataSource = dt;

 

源码下载:下载地址——(http://files.cnblogs.com/anding/WinForm_Test1.rar)

posted @ 2011-01-09 17:04 冰云 阅读(387) 评论(1) 编辑
 

快捷键在WinForm软件中必不可少,可以提高使用者的效率,下面就来看看怎样在我们的窗体中加上快捷键,新建一个Windows应用程序(我将解决方案命名为Keybd_Test,项目名为UI)。删掉自动生成的Form1.cs窗体,新建MainForm.cs窗体。调整大小,将StartPosition设置为CenterScreen,让窗体一运行就可以居中;将ShowIcon设置为false,去掉窗体标题栏的图标,现在什么控件也不加:

每个窗体都有这样3个事件:KeyDown、KeyPress、KeyUp,KeyDown和KeyPress都是按键按下事件,但KeyDown用的是KeyCode跟键盘各个按键相对应,它对应Keys枚举,用起来比较方便;而KeyPress用的是KeyChar,这个就要找ASC II编码了,不方便。KeyUp是按键弹起事件,不常用,因此我们使用KeyDown事件来设置窗体的快捷键,双击该事件后的空白生成代码,首先我们设置单个按键,让它按下F11最大化,再次按下还原,在事件中加入如下代码:

if (e.KeyCode == Keys.F11)
{
    if (WindowState == FormWindowState.Maximized)
        WindowState = FormWindowState.Normal;
    else
        WindowState = FormWindowState.Maximized;
}

若窗体的WindowState为Maximized则还原,否则最大化,运行下试试,很好用 :-)

下面在窗体中加入一个名为txtInput的TextBox,两个名为btnConfirm、btnExit的Button:

再次运行窗体,按下F11,不起作用了?这是怎么回事?

因为这时窗体运行后,焦点已不在窗体上,而在控件上了,我们要将窗体的KeyPreview设置为True,向窗体注册控件上产生的键盘事件,再次运行,问题解决了。

那么组合按键又怎么设置呢?例如要按下Alt和数字0,需要这样:

if (e.Modifiers == Keys.Alt && e.KeyCode == Keys.D0)
{
    MessageBox.Show("按下了Alt + 0");
}

使用Modifiers可设置组合键,键盘数字区按键的Keys枚举以D打头,而小键盘上的数字以NumPad打头。按下Ctrl与Shift组合键的方法与其类似,下面我们看看按下Ctrl + Alt + 数字0该怎样设置:

if ((int)e.Modifiers == ((int)Keys.Control + (int)Keys.Alt) && e.KeyCode == Keys.D0)
{
    MessageBox.Show("按下了Control + Alt + 0");
}

将Ctrl和Alt的枚举转换为int型相加后与Modifiers对比,这样即可判断是否按下了该组合键。

另外的,与窗体的AcceptButton属性相关联的按钮,将与键盘上的Enter键对应;与窗体的CancelButton属性相关联的按钮,将与键盘上的Ecs键对应。

在设置Button的Text属性时,在一个英文字母的前面加上&(and符),例如将btnConfirm的Text属性设置为:&Confirm,当运行窗体,按下Alt + C时,就相当于按下该键。

上面的示例名为Keybd_Test,点击这里下载(用VS 2005创建,.NET版本2.0)。

posted @ 2011-01-09 16:44 冰云 阅读(244) 评论(1) 编辑
 
using System;    
using System.IO;    
using System.Text;    
using System.Collections;    
namespace PDFGenerator    
{    
     public class PDFGenerator    
      {    
          static float pageWidth = 594.0f;    
          static float pageDepth = 828.0f;    
          static float pageMargin = 30.0f;    
          static float fontSize = 20.0f;    
          static float leadSize = 10.0f;    
          static StreamWriter pPDF = new StreamWriter("E:\\myPDF.pdf");    
          static MemoryStream mPDF = new MemoryStream();    
          static void ConvertToByteAndAddtoStream(string strMsg)    
           {    
                 Byte[] buffer = null;    
                 buffer = ASCIIEncoding.ASCII.GetBytes(strMsg);    
                 mPDF.Write(buffer, 0, buffer.Length);    
                 buffer = null;    
           }    
          static string xRefFormatting(long xValue)    
           {    
                string strMsg = xValue.ToString();    
                int iLen = strMsg.Length;    
                if (iLen < 10)    
                 {    
                      StringBuilder s = new StringBuilder();    
                     int i = 10 - iLen;    
                      s.Append("0", i);    
                      strMsg = s.ToString() + strMsg;    
                 }    
                return strMsg;    
           }    
          static void Main(string[] args)    
           {    
                 ArrayList xRefs = new ArrayList();    
                //Byte[] buffer=null;    
                float yPos = 0f;    
                long streamStart = 0;    
                long streamEnd = 0;    
                long streamLen = 0;    
                string strPDFMessage = null;    
                //PDF文档头信息    
                 strPDFMessage = "%PDF-1.1 ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 xRefs.Add(mPDF.Length);    
                 strPDFMessage = "1 0 obj ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = "<< /Length 2 0 R >> ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = "stream ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                /**/   
                ////////PDF文档描述    
                 streamStart = mPDF.Length;    
                //字体    
                 strPDFMessage = "BT /F0 " + fontSize + " Tf ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                //PDF文档实体高度    
                 yPos = pageDepth - pageMargin;    
                 strPDFMessage = pageMargin + " " + yPos + " Td ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = leadSize + " TL ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                //实体内容    
                 strPDFMessage = "(http://www.wenhui.org)Tj ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = "ET ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 streamEnd = mPDF.Length;    
                 streamLen = streamEnd - streamStart;    
                 strPDFMessage = "endstream endobj ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                //PDF文档的版本信息    
                 xRefs.Add(mPDF.Length);    
                 strPDFMessage = "2 0 obj " + streamLen + " endobj ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 xRefs.Add(mPDF.Length);    
                 strPDFMessage = "3 0 obj <</Type/Page/Parent 4 0 R/Contents 1 0 R>> endobj ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 xRefs.Add(mPDF.Length);    
                 strPDFMessage = "4 0 obj <</Type /Pages /Count 1 ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = "/Kids[ 3 0 R ] ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = "/Resources<</ProcSet[/PDF/Text]/Font<</F0 5 0 R>> >> ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = "/MediaBox [ 0 0 " + pageWidth + " " + pageDepth + " ] >> endobj ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 xRefs.Add(mPDF.Length);    
                 strPDFMessage = "5 0 obj <</Type/Font/Subtype/Type1/BaseFont/Courier/Encoding/WinAnsiEncoding>> endobj ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 xRefs.Add(mPDF.Length);    
                 strPDFMessage = "6 0 obj <</Type/Catalog/Pages 4 0 R>> endobj ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 streamStart = mPDF.Length;    
                 strPDFMessage = "xref 0 7 0000000000 65535 f ";    
                for (int i = 0; i < xRefs.Count; i++)    
                 {    
                      strPDFMessage += xRefFormatting((long)xRefs[i]) + " 00000 n ";    
                 }    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = "trailer << /Size " + (xRefs.Count + 1) + " /Root 6 0 R >> ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 strPDFMessage = "startxref " + streamStart + " %%EOF ";    
                 ConvertToByteAndAddtoStream(strPDFMessage);    
                 mPDF.WriteTo(pPDF.BaseStream);    
                 mPDF.Close();    
                 pPDF.Close();    
           }    
      }    
}  
posted @ 2011-01-09 16:20 冰云 阅读(76) 评论(0) 编辑
 
C#自定义消息通信往往采用事件驱动的方式实现,但有时候我们不得不采用操作系统的消息通信机制,例如在和底层语言开发的DLL交互时,是比较方便的。下面列举了一些实现方式,供大家参考:

一、通过SendMessage或postmessage函数发送:

1、  定义消息
在C++中引用底层的函数很简单,自定义消息如下
#define WM_TEST WM_USER + 101
而在c#中消息需要定义成windows系统中的原始的16进制数字,比如自定义消息
public const int USER = 0x0400;

 public const int WM_TEST = USER +101;

2、  发送消息
消息发送是通过windows提供的API函数SendMessagepostmessage来实现的,它的原型定义:        

[DllImport("User32.dll",EntryPoint="SendMessage")]
          private static extern int SendMessage(
            IntPtr hWnd,      // 窗体句柄
            uint Msg,         // 消息的标识符
            uint wParam,      // 具体取决于消息
            uint lParam       // 具体取决于消息
       );

[DllImport("User32.dll",EntryPoint="PostMessage")]
          private static extern int SendMessage(
            IntPtr hWnd,      // 接收消息的那个窗口的句柄。如设为HWND_BROADCAST,表示投递给系统中的所有顶级窗口。如设为零,表示投递一条线程消息(可参考PostThreadMessage
            uint Msg,         // 消息的标识符
            uint wParam,      // 具体取决于消息
            uint lParam       // 具体取决于消息
       );

至于两个函数的区别这里就不累述了,有兴趣的朋友可以自己查阅资料。


3、  消息接收
消息发出之后,在Form中如何接收呢?我们可以重载DefWinproc函数来接收消息。
protected override void DefWndProc ( ref System.Windows.Forms.Message m )
        {
            switch(m.Msg)
            {
                case Message.WM_TEST:   //处理消息
                break;
                default:
                base.DefWndProc(ref m);   //调用基类函数处理非自定义消息。
break;
            }
        }

 

二、使用PostThreadMessage函数向线程发送消息

 1、映射消息结构体原型和自定义消息

public struct tagMSG
        {
            public int hwnd;
            public uint message;
            public int wParam;
            public long lParam;
            public uint time;
            public int pt;
        }

public const int WM_CX_NULL = 0x400 + 100;

2、发送消息

[DllImport("user32.dll")]

private static extern int PostThreadMessage(

                  int threadId,   //线程标识

                   uint msg,      //消息标识符

                  int wParam,   //具体由消息决定

                   int lParam);  //具体由消息决定

此函数获取当前线程一个唯一的线程标识符,这点需要特别注意:Win32 API无法识别管理线程,你必须发送消息到Windows的线程ID上,而不是管理线程的ID上。

[DllImport("kernel32.dll")]

private static extern int GetCurrentThreadId();

 

因此发送消息过程如下:

private int _NewThreadId = GetCurrentThreadId();

PostThreadMessage(_NewThreadId, WM_CX_NULL, 1, 1);

 

3、接收消息

该函数从调用线程的消息队列里取得一个消息并将其放于指定的结构。此函数可取得与指定窗口联系的消息和由PostThreadMesssge寄送的线程消息。此函数接收一定范围的消息值。GetMessage不接收属于其他线程或应用程序的消息

[DllImport("user32.dll")]
private static extern int GetMessage(

                  ref tagMSG lpMsg, //指向MSG结构的指针,该结构从线程的消息队列里接收消息信息;

                  int hwnd,       //取得其消息的窗口的句柄。这是一个有特殊含义的值(NULL)。GetMessage为任何属于调用线程的窗口检索消息;                                                 int wMsgFilterMin,     //指定被检索的最小消息值的整数

                  int wMsgFilterMax);    //指定被检索的最大消息值的整数

接收实现如下:

 public void ThreadExectue()
        {
            _NewThreadId = GetCurrentThreadId();  //发送线程和接收线程一定要是同一个线程,否则接收不到消息
            while (GetMessage(ref msg, 0, 0, 0) > 0)
            {
                if (msg.message == WM_CX_NULL)
                {
                    MessageBox.Show("消息收到!");
                }
            }
        }


 三、使用Application.AddMessageFilter拦截系统消息

1、实现消息过滤器接口

        internal class MyMessager : IMessageFilter
        {
            //截取消息,进行处理
            public bool PreFilterMessage(ref System.Windows.Forms.Message m)
            {
                switch (m.Msg)
                {
                     case CUSTOM_MESSAGE:      //拦截自定义消息 
                        MessageBox.Show("消息收到!");
                        return true;                       
                     default:
                        return false;           //返回false则消息未被裁取,系统会处理
                }
            }
        }
2、安装消息过滤器
 private void Form1_Load(object sender, EventArgs e)
  {
       Application.AddMessageFilter(new MyMessager());
  }


posted @ 2011-01-09 13:51 冰云 阅读(320) 评论(0) 编辑
 
using System;   
using System.Collections.Generic;   
using System.ComponentModel;   
using System.Data;   
using System.Drawing;   
using System.Linq;   
using System.Text;   
using System.Windows.Forms;   
  
namespace TabControlTest   
{   
    
public partial class Form1 : Form   
    {   
        
public Form1()   
        {   
            InitializeComponent();   
        }   
  
        
const int CLOSE_SIZE = 15;   
        Bitmap image 
= new Bitmap("ONE.ico");   
  
  
        
private void MainTabControl_DrawItem(object sender, DrawItemEventArgs e)   
        {   
            
try  
            {   
                Rectangle myTabRect 
= this.MainTabControl.GetTabRect(e.Index);   
  
                
//先添加TabPage属性      
                e.Graphics.DrawString(this.MainTabControl.TabPages[e.Index].Text   
                , 
this.Font, SystemBrushes.ControlText, myTabRect.X + 2, myTabRect.Y + 2);   
  
                
//再画一个矩形框   
                using (Pen p = new Pen(Color.White))   
                {   
                    myTabRect.Offset(myTabRect.Width 
- (CLOSE_SIZE + 3), 2);   
                    myTabRect.Width 
= CLOSE_SIZE;   
                    myTabRect.Height 
= CLOSE_SIZE;   
                    e.Graphics.DrawRectangle(p, myTabRect);   
  
                }   
  
                
//填充矩形框   
                Color recColor = e.State == DrawItemState.Selected ? Color.White : Color.White;   
                
using (Brush b = new SolidBrush(recColor))   
                {   
                    e.Graphics.FillRectangle(b, myTabRect);   
                }   
  
                
//画关闭符号   
                using (Pen objpen = new Pen(Color.Black))   
                {   
                    
//"\"线   
                    Point p1 = new Point(myTabRect.X + 3, myTabRect.Y + 3);   
                    Point p2 
= new Point(myTabRect.X + myTabRect.Width - 3, myTabRect.Y + myTabRect.Height - 3);   
                    e.Graphics.DrawLine(objpen, p1, p2);   
  
                    
//"/"线   
                    Point p3 = new Point(myTabRect.X + 3, myTabRect.Y + myTabRect.Height - 3);   
                    Point p4 
= new Point(myTabRect.X + myTabRect.Width - 3, myTabRect.Y + 3);   
                    e.Graphics.DrawLine(objpen, p3, p4);   
                    
////=============================================   
                    Bitmap bt = new Bitmap(image);   
                    Point p5 
= new Point(myTabRect.X - 504);   
                    e.Graphics.DrawImage(bt, p5);   
                    
//e.Graphics.DrawString(this.MainTabControl.TabPages[e.Index].Text, this.Font, objpen.Brush, p5);   
                }   
  
  
                
//绘制小图标                 
                
//==============================================================================   
                
//Bitmap bt = new Bitmap("E:\\1\\2.jpg");   
                
//Point p5 = new Point(4, 4);   
                ////e.Graphics.DrawImage(bt, e.Bounds);   
                //e.Graphics.DrawImage(bt, p5);   
                
//Pen pt = new Pen(Color.Red);   
                ////e.Graphics.DrawString(this.MainTabControl.TabPages[e.Index].Text, this.Font, pt.Brush, e.Bounds);   
                //e.Graphics.DrawString(this.MainTabControl.TabPages[e.Index].Text, this.Font, pt.Brush, p5);   
  
                e.Graphics.Dispose();   
            }   
            
catch  
            {   
    
            }   
    
        }   
  
        
private void MainTabControl_MouseDown(object sender, MouseEventArgs e)   
        {   
             
if (e.Button == MouseButtons.Left)   
             {   
                  
int x = e.X, y = e.Y;   
  
                
//计算关闭区域      
                 Rectangle myTabRect = this.MainTabControl.GetTabRect(this.MainTabControl.SelectedIndex);   
    
                 myTabRect.Offset(myTabRect.Width 
- (CLOSE_SIZE + 3), 2);   
                 myTabRect.Width 
= CLOSE_SIZE;   
                 myTabRect.Height 
= CLOSE_SIZE;   
    
                 
//如果鼠标在区域内就关闭选项卡      
                 bool isClose = x > myTabRect.X && x < myTabRect.Right   
                  
&& y > myTabRect.Y && y < myTabRect.Bottom;   
    
                 
if (isClose == true)   
                 {   
                     
this.MainTabControl.TabPages.Remove(this.MainTabControl.SelectedTab);   
                 }   
             }   
    
  
        }   
  
         
//初始化页面   
         private void Form1_Load(object sender, EventArgs e)   
         {   
             
//清空控件   
             
//this.MainTabControl.TabPages.Clear();   
             
//绘制的方式OwnerDrawFixed表示由窗体绘制大小也一样   
             this.MainTabControl.DrawMode = TabDrawMode.OwnerDrawFixed;   
             
this.MainTabControl.Padding = new System.Drawing.Point(CLOSE_SIZE, CLOSE_SIZE);   
             
this.MainTabControl.DrawItem += new DrawItemEventHandler(this.MainTabControl_DrawItem);   
             
this.MainTabControl.MouseDown += new System.Windows.Forms.MouseEventHandler(this.MainTabControl_MouseDown);   
         }   
  
         
//添加新的tabPage并修改所有tabPage标签上面的图片   
         private void button1_Click(object sender, EventArgs e)   
         {   
             TabPage tabtage 
= new TabPage();   
             MainTabControl.TabPages.Add(tabtage);   
             MainTabControl.SelectedTab 
= tabtage;   
             image 
= new Bitmap("ONE.ico");   
  
  
         }   
         
//关闭选中的tabPage   
         private void button2_Click(object sender, EventArgs e)   
         {   
             MainTabControl.TabPages.Remove(MainTabControl.SelectedTab);   
         }   
    }   
}
posted @ 2011-01-09 12:41 冰云 阅读(930) 评论(0) 编辑
 
有些CPU不支持获取序列号。

获取strCpu = myObject.Properties["Processorid"].Value.ToString();时,请判断下返回是否为null,为null的话就说明cpu不支持。
获取集合对象属性,除非100%确定,否则不要直接访问属性。一旦返回空,就会报空引用错误

 

代码
 using System.Management;//需要在项目中添加System.Management引用

namespace ECBC_CDKEY
{
public class SoftReg
{
/// <summary>
/// 取得设备硬盘的卷标号
/// </summary>
/// <returns></returns>
public string GetDiskVolumeSerialNumber()
{
ManagementClass mc
= new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObject disk
= new ManagementObject("win32_logicaldisk.deviceid=\"c:\"");
disk.Get();
return disk.GetPropertyValue("VolumeSerialNumber").ToString();
}

/// <summary>
/// 获得CPU的序列号
/// </summary>
/// <returns></returns>
public string getCpu()
{
string strCpu = null;
ManagementClass myCpu
= new ManagementClass("win32_Processor");
ManagementObjectCollection myCpuConnection
= myCpu.GetInstances();
foreach (ManagementObject myObject in myCpuConnection)
{
strCpu
= myObject.Properties["Processorid"].Value.ToString();
break;
}
return strCpu;
}

/// <summary>
/// 生成机器码
/// </summary>
/// <returns></returns>
public string getMNum()
{
string strNum = getCpu() + GetDiskVolumeSerialNumber();//获得24位Cpu和硬盘序列号
string strMNum = strNum.Substring(0, 24);//从生成的字符串中取出前24个字符做为机器码
return strMNum;
}
public int[] intCode = new int[127];//存储密钥
public int[] intNumber = new int[25];//存机器码的Ascii值
public char[] Charcode = new char[25];//存储机器码字
public void setIntCode()//给数组赋值小于10的数
{
for (int i = 1; i < intCode.Length; i++)
{
intCode[i]
= i % 9;
}
}

/// <summary>
/// 生成注册码
/// </summary>
/// <returns></returns>
public string getRNum()
{
setIntCode();
//初始化127位数组
string MNum = this.getMNum();//获取注册码
for (int i = 1; i < Charcode.Length; i++)//把机器码存入数组中
{
Charcode[i]
= Convert.ToChar(MNum.Substring(i - 1, 1));
}
for (int j = 1; j < intNumber.Length; j++)//把字符的ASCII值存入一个整数组中。
{
intNumber[j]
= intCode[Convert.ToInt32(Charcode[j])] + Convert.ToInt32(Charcode[j]);
}
string strAsciiName = "";//用于存储注册码
for (int j = 1; j < intNumber.Length; j++)
{
if (intNumber[j] >= 48 && intNumber[j] <= 57)//判断字符ASCII值是否0-9之间
{
strAsciiName
+= Convert.ToChar(intNumber[j]).ToString();
}
else if (intNumber[j] >= 65 && intNumber[j] <= 90)//判断字符ASCII值是否A-Z之间
{
strAsciiName
+= Convert.ToChar(intNumber[j]).ToString();
}
else if (intNumber[j] >= 97 && intNumber[j] <= 122)//判断字符ASCII值是否a-z之间
{
strAsciiName
+= Convert.ToChar(intNumber[j]).ToString();
}
else//判断字符ASCII值不在以上范围内
{
if (intNumber[j] > 122)//判断字符ASCII值是否大于z
{
strAsciiName
+= Convert.ToChar(intNumber[j] - 10).ToString();
}
else
{
strAsciiName
+= Convert.ToChar(intNumber[j] - 9).ToString();
}
}
}
return strAsciiName;//返回注册码
}
}
}
posted @ 2011-01-09 11:21 冰云 阅读(778) 评论(0) 编辑