<?xml version="1.0" encoding="UTF-8"?>
  <feed xmlns="http://www.w3.org/2005/Atom">
  <title type="html"><![CDATA[Achely's Blog]]></title>
  <subtitle type="html"><![CDATA[水至清则无鱼,人至贱则无敌!]]></subtitle>
  <id>http://www.zhangyongjun.com/blog/</id> 
  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/" /> 
  <link rel="self" type="application/atom+xml" href="http://www.zhangyongjun.com/blog/atom.asp" /> 
  <generator uri="http://www.pjhome.net/" version="2.4.1022">PJBlog2</generator> 
  <updated>2010-09-09T21:13:26+08:00</updated> 

  <entry>
	  <title type="html"><![CDATA[ThinkinginAJAX--基于AJAX的WEB设计]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=7" label="Ajax" /> 
	  <updated>2010-09-09T21:13:26+08:00</updated>
	  <published>2010-09-09T21:13:26+08:00</published>
		  <summary type="html"><![CDATA[	                个人资料                                                                		        <img src="http://portrait1.sinaimg.cn/1785791952/blog/180" id="comp_901_head_image" width="180" height="180" alt="" title="hahazhang2010" />       	    		      		        <img id="comp_901_online_icon" style="display:none;" class="SG_icon SG_icon1" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" width="15" height="15" align="absmiddle" />		        hahazhang2010		                                      		      		        <img class="SG_icon SG_icon16" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" width="15" height="15" align="absmiddle" />播客		        <img class="SG_icon SG_icon51" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" width="15" height="15" align="absmiddle" />微博		        		      			      	           	博客等级：读取中…	博客积分：读取中…			博客访问：读取中…	关注人气：读取中…					                                                 相关博文                 	        								<br/>　　下跌不再温柔					<br/>　　徐小明													<br/>　　女大学生当二奶是否开除					<br/>　　wu2198													<br/>　　今天是个不应忘记的日子					<br/>　　封起De日子													<br/>　　技术与大环境的结合引发起爆点					<br/>　　空空道人													<br/>　　访谈					<br/>　　当年明月													<br/>　　《婆婆驾到》的三大看点					<br/>　　马善记													<br/>　　李连杰耗资2亿元的超级豪宅（					<br/>　　丑鱼尼莫													<br/>　　球员打架不必上纲上线					<br/>　　黄健翔													<br/>　　回到原点：生命在平凡与平淡之					<br/>　　金歌													<br/>　　9月9日股市直播					<br/>　　徐湘毅							更多&gt;&gt;                                 推荐博文                                                                    	<br/>　　我是如何搞定田亮的		<br/>　　茜茜		<br/>　　守贞是末流的办法		<br/>　　李扁		<br/>　　簡單的仇恨		<br/>　　张大春		<br/>　　钓鱼岛的观点误区		<br/>　　李牧		<br/>　　关于作家谢朝平被跨省抓捕若干		<br/>　　周泽		<br/>　　培训班的“婆婆”到底是谁？		<br/>　　老丑		<br/>　　身无彩凤双飞翼——来自西班牙		<br/>　　我的留学厨房		<br/>　　女大学生当二奶是否开除		<br/>　　wu2198		<br/>　　中国队！我为你痴狂！		<br/>　　stephanie		<br/>　　鲁迅作品要不要退出中学课本？		<br/>　　罗庆学		查看更多>>                                                                  谁看过这篇博文                                                                    	<img src="http://simg.sinajs.cn/blog7style/images/common/loading.gif" />加载中…				    正文	    字体大小：大 中 小	    			 								Thinking in AJAX -- 基于AJAX的WEB设计								(2010-09-09 19:22:23)<img class="SG_icon SG_icon111" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" width="15" height="15" align="absmiddle" />转载																																标签：																				杂谈																																																			来源：信息发布<br/><br/>　　(转载)<br/>　　m ul u0 01 文章版权归原作者所有！--(www.mulu001.com)<br/>　　众所周知，异步交互、JavaScript脚本和XML封装数据是AJAX的三大特征。其实，在实际应用中，不需要牢牢套死这三条大律，在我看来，AJAX<br/>																	        	分享 <img class="SG_icon SG_icon110" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" width="18" height="18" title="" align="absmiddle" /> <img class="SG_icon SG_icon117" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" width="18" height="18" title="" align="absmiddle" /> <img class="SG_icon SG_icon113" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" width="18" height="18" title="" align="absmiddle" /> <img class="SG_icon SG_icon116" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" width="18" height="18" title="" align="absmiddle" />             	        		            	<br/><br/>　　<img width="15" height="15" align="absmiddle" src="http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif" class="SG_icon SG_icon34">顶	            	                    														阅读┊ 				评论 ┊				收藏				┊转载				┊				顶▼									┊打印┊举报																														]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4935" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4935</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[java的版本以及特性]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=14" label="JAVA" /> 
	  <updated>2010-09-09T21:13:20+08:00</updated>
	  <published>2010-09-09T21:13:20+08:00</published>
		  <summary type="html"><![CDATA[					<br/>　　Java的版版本按应用范围分有3个：<br/>　　1.JAVA SE<br/>　　	Java SE(Java Platform，Standard Edition)标准版是各种应用平台的基础，主要应用于桌面开发和低端商务应用的解决方案。Java SE也包含了支持Java Web服务开发的类库，并为Java EE提供了基础。Java SE 1.4与1.5以后的版本有很大的差别，大多数开发人员都使用1.6版本。目前虽然官方没有正式发布Java SE 7.0，但是开源组织陆续采集了很多高级特性归纳到Java SE 7.0中。Java SE 7.0的组成如图所示。<br/>　　<img src="http://hi.csdn.net/attachment/201009/9/7859083_1284029332lcCB.jpg" alt="" width="698" height="364" /><br/><br/>　　Java SE中包含的主要技术如下。<br/>　　(1) Java Beans Component Architecture是一个为Java平台定义可重用软件组件的框架，可以在图形化构建工具中设计这些组件。<br/>　　(2) Java Foundation Classes(Swing)(JFC)是一套Java类库，支持为基于Java的客户机应用程序构建GUI(Graphical User Interface，图形用户界面)和图形化功能。<br/>　　(3) Java Help是一个独立于平台的可扩展的帮助系统，开发人员可以使用它将在线帮助集成到Applet、组件、应用程序、操作系统和设备中，还可以提供基于Web的在线文档。<br/>　　(4) Java Native Interface(JNI)是JVM中运行的Java代码，可以与用其他编程语言编写的应用程序和库进行互操作。<br/>　　(5) Java Platform Debugger Architecture(JPDA)是用于Java SE调试支持的基础结构。<br/>　　(6) Java 2D API是一套用于高级2D图形和图像的类(为图像组合和alpha通道图像提供丰富的支持)，一套提供精确的颜色空间定义和转换的类以及一套面向显示的图像操作符。<br/>　　(7) Java Web Start允许用户通过一次单击操作下载并启动特性完整的应用程序(比如电子表格)，而不需要进行安装，从而简化了Java应用程序的部署。<br/>　　(8) Certification Path API提供了一套用于创建、构建和检验认证路径(也称为"认证链")的API，可以安全地建立公共密钥到主体的映射。<br/>　　(9) Java Database Connectivity(JDBC)是一个API，它使用户能够从Java代码中访问大多数表格式数据源，提供了对许多SQL数据库的跨DBMS连接能力，并可以访问其他表格式数据源，比如电子表格或平面文件。<br/>　　(10) Java Advanced Imaging(JAI)是一个API，提供了一套面向对象的接口，这些接口支持一个简单的高级编程模型，使开发人员能够轻松地操作图像。<br/>　　(11) Java Authentication and Authorization Service(JAAS)是一个包，实现了标准的Pluggable Authentication Module(PAM)框架的Java版本并支持基于用户的授权，能够对用户进行身份验证和访问控制。<br/>　　(12) Java Cryptography Extension(JCE)是一组包，提供了用于加密、密钥生成和协商以及Message Authentication Code(MAC)算法的框架和实现。JCE给对称、不对称、块和流密码提供加密支持，它还支持安全流和密封的对象。<br/>　　(13) Java Data Objects(JDO)是一种基于标准接口的持久化Java模型抽象，使程序员能够将Java领域模型实例直接保存到数据库(持久化存储器)中，这可以替代直接文件 I/O、串行化、JDBC以及EJB、BMP(Bean Managed Persistence)或CMP(Container Managed Persistence)实体Bean等方法。<br/>　　(14) Java Management Extensions(JME)提供了用于构建分布式、基于Web、模块化且动态的应用程序的工具，这些应用程序可以用来管理和监视设备、应用程序和服务驱动的网络。<br/>　　(15) Java Media Framework(JMF)可以将音频、视频和其他基于时间的媒体添加到Java应用程序和Applet中。<br/>　　(16) Java Naming and Directory Interface(JNDI)为Java应用程序提供一个连接到企业中的多个命名和目录服务的统一接口，可以无缝地连接结构不同的企业命名和目录服务。<br/>　　(17) Java Secure Socket Extensions(JSSE)是一组包，它们支持安全的互联网通信，实现了SSL(Secure Sockets Layer)和TLS(Transport Layer Security)的Java版本，包含了数据加密、服务器身份验证、消息完整性和可选的客户机身份验证等功能。<br/>　　(18) Java Speech API(JSAPI)包含Java Speech Grammar Format(JSGF)和Java Speech Markup Language(JSML)规范，使Java应用程序能够将语音技术集成到用户界面中。JSAPI定义了一个跨平台的 API，支持命令和控制识别器、听写系统及语音识别器。<br/>　　(19) Java 3D 是一个 API，它提供了一套面向对象的接口，这些接口支持一个简单的高级编程模型，开发人员可以使用这个API轻松地将可伸缩的独立于平台的3D图形集成到 Java应用程序中。<br/>　　(20) Metadata Facility 允许给类、接口、字段和方法标上特定的属性，从而使开发工具、部署工具和运行时能够以特殊方式处理它们。<br/>　　(21) Java Content Repository API 是一个用于访问Java SE中独立于实现的内容存储库的 API。内容存储库是一个高级信息管理系统，是传统数据存储库的超集。<br/>　　(22) Enumerations(枚举)是一种类型，允许以类型安全的方式将特定的数据表示为常量。<br/>　　(23) Generics(泛型)允许定义具有抽象类型参数的类，可以在实例化时指定这些参数。<br/>　　(24) Concurrency Utilities是一套中级实用程序，提供了并发程序中常用的功能。<br/>　　(25) Java API for XML Processing(JAXP)允许Java应用程序独立于特定的XML处理，实现对XML文档进行解析和转换，允许灵活地在XML处理程序之间进行切换，而不需要修改应用程序代码。Java API for XML Binding(JAXB)允许在XML文档和Java对象之间进行自动的映射。<br/>　　(26) SOAP with Attachments API for Java(SAAJ)使开发人员能够按照SOAP1.1规范和 SOAP with Attachments note生成和消费消息。<br/>　　2.JAVA EE<br/>　　	Java EE(Java Platform，Enterprise Edition)企业版是以企业为环境而开发应用程序的解决方案，这个版本以前称为J2EE。企业版本帮助开发和部署可移植、健壮、可伸缩且安全的服务器端Java应用程序。Java EE是在Java SE的基础上构建的，它提供了Web服务、组件模型、管理和通信API，可以用来实现企业级的面向服务体系结构(Service oriented Architecture，SOA)和Web 2.0应用程序。<br/>　　Java EE中包含的主要技术如下。<br/>　　(1) Enterprise Java Beans(EJB)技术使用一个组件模型来简化中间件应用程序的开发，提供了对事务、安全性和数据库连接等服务的自动支持。<br/>　　(2) Portlet Specification 定义了一套用于Java门户计算的API，可以解决聚合、个人化、表示和安全性方面的问题。<br/>　　(3) Java Mail是一个API，提供了一套对邮件系统进行建模的抽象类。<br/>　　(4) Java Message Service(JMS)是一个API，它为所有与JMS技术兼容的消息传递系统定义一套通用的消息概念和编程策略，从而支持开发可移植的基于消息的Java应用程序。<br/>　　(5) Java Server Faces(JSF)提供一个编程模型，帮助开发人员将可重用UI组件组合在页面中，将这些组件连接到应用程序数据源，将客户机生成的事件连接到服务器端的事件处理程序，从而轻松地组建Web应用程序。<br/>　　(6) Java Server Pages(JSP)允许Web开发人员快速地开发和轻松地维护动态的独立于平台的Web页面，并将用户界面和内容生成隔离开，这样设计人员就能够修改页面布局而不必修改动态内容。这种技术使用类似XML的标记来封装为页面生成内容的逻辑。<br/>　　(7) Standard Tag Library for Java Server Pages(JSTL)是一个定制标记集合，它以一种标准化的格式启用许多常见的Web站点功能。<br/>　　(8) Java Servlets提供了一种基于组件的独立于平台的方法，可以构建基于Web的应用程序，同时避免CGI程序的性能限制，从而扩展并增强了Web服务器的功能。<br/>　　(9) J2EE Connector Architecture(JCA)为将J2EE平台连接到各种结构的Enterprise Information Systems(EIS)定义了一个标准的体系结构，它定义了一套可伸缩的安全的事务性机制，使EIS厂商能够提供标准的资源适配器，可以将这些资源适配器插入到应用服务器中。<br/>　　(10) J2EE Management Specification(JMX)为J2EE平台定义了一个信息管理模型。根据其设计，J2EE Management Model可与多种管理系统和协议进行互操作；包含模型到Common Information Model(CIM)的标准映射，CIM是一个SNMP Management Information Base(MIB)；还可以通过一个驻留在服务器上的EJB组件--J2EE Management EJB Component (MEJB)映射到Java对象模型。<br/>　　(11) Java Transaction API(JTA)是一个独立于实现和协议的高级API，它使应用程序和应用服务器可以访问事务。Java Transaction Service(JTS)指定了Transaction Manager的实现，它支持JTA并在这个API之下的层上实现OMG Object Transaction Service(OTS)1.1规范的Java映射。JTS使用Internet Inter-ORB Protocol(IIOP)传播事务。<br/>　　3.JAVA ME<br/><br/>　　	Java ME(Java Platform，Micro Edition)微型版致力于消费产品和嵌入式设备的最佳解决方案，这个版本以前称为J2ME。Java ME为在移动设备和嵌入式设备(比如手机、PDA、电视机顶盒和打印机)上运行的应用程序提供一个健壮且灵活的环境。Java ME包括灵活的用户界面、健壮的安全模型、许多内置的网络协议以及对可以动态下载的联网和离线应用程序的丰富支持。基于Java ME规范的应用程序只需编写一次就可以用于许多设备，而且可以利用每个设备的自身功能。<br/>　　Java ME中包含的主要技术如下。<br/>　　(1) Connected Limited Device Configuration(CLDC)描述最基本的库和虚拟机特性，所有包含K虚拟机(K Virtual Machine，KVM)的J2ME环境实现中都必须提供这些库和特性。<br/>　　(2) Mobile Information Device Profile(MIDP)提供核心应用程序功能，包括用户界面、网络连接、本地数据存储和应用程序生命周期管理。<br/>　　(3) Connected Device Configuration(CDC)是一个基于标准的框架，用来构建和交付可以跨许多连接网络的消费类设备和嵌入式设备共享的应用程序。<br/>　　(4) Mobile 3D Graphics API for J2ME(M3G)是一种轻量的交互式3D图形API，它作为可选的包与J2ME和MIDP结合使用。<br/>　　JAVA特性<br/>　　1.简单<br/>　　2.面向对象<br/>　　3.分布式<br/>　　4.可移植性<br/>　　5.解释性<br/>　　6.安全性<br/>　　7.健壮性<br/>　　8.多线程<br/>　　9.高性能<br/>　　10.动态					<br/>　　						发表于 @						2010年09月09日　18:55:00 &#124; 评论( loading...							) &#124; 编辑&#124									举报&#124; 收藏							旧一篇:is-a, is-like-a, has-a | 新一篇:this								查看最新精华文章 请访问博客首页相关文章				]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4934" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4934</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[同步两个SQLServer数据库]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=15" label="数据库" /> 
	  <updated>2010-09-09T21:13:12+08:00</updated>
	  <published>2010-09-09T21:13:12+08:00</published>
		  <summary type="html"><![CDATA[			<br/>　　如何同步两个SQLServer数据库的内容?<br/>　　程序代码可以有版本管理CVS进行同步管理,可是数据库同步就非常麻烦,只能自己改了一个后再去改另一个,如果忘记了更改另一个经常造成两个数据库的结构或内容上不一致.<br/>　　各位有什么好的方法吗?<br/>　　分发与复制<br/>　　用强制订阅实现数据库同步操作<br/>　　大量和批量的数据可以用数据库的同步机制处理:<br/>　　//<br/>　　说明：<br/>　　为方便操作,所有操作均在发布服务器(分发服务器)上操作,并使用推模式<br/>　　在客户机器使用强制订阅方式。<br/><br/>　　测试通过<br/>　　//<br/>　　--1:环境<br/>　　服务器环境:<br/>　　机器名称： ZehuaDb<br/>　　操作系统：Windows 2000 Server<br/>　　数据库版本：SQL 2000 Server 个人版<br/>　　客户端<br/>　　机器名称：Zlp<br/>　　操作系统：Windows 2000 Server<br/>　　数据库版本：SQL 2000 Server 个人版<br/>　　--2:建用户帐号<br/>　　在服务器端建立域用户帐号<br/>　　我的电脑管理-&gt;本地用户和组-&gt;用户-&gt;建立<br/>　　UserName:zlp<br/>　　UserPwd:zlp<br/>　　--3:重新启动服务器MSSQLServer<br/>　　我的电脑-&gt;控制面版-&gt;管理工具-&gt;服务-&gt;MSSQLServer服务<br/>　　(更改为：域用户帐号,我们新建的zlp用户 .\zlp,密码:zlp)<br/>　　--4:安装分发服务器<br/>　　A:配置分发服务器<br/>　　工具-&gt;复制-&gt;配置发布、订阅服务器和分发-&gt;下一步-&gt;下一步(所有的均采用默认配置)<br/>　　B:配置发布服务器<br/>　　工具-&gt;复制-&gt;创建和管理发布-&gt;选择要发布的数据库(SZ)-&gt;下一步-&gt;快照发布-&gt;下一步-&gt;<br/>　　选择要发布的内容-&gt;下一步-&gt;下一步-&gt;下一步-&gt;完成<br/>　　C:强制配置订阅服务器(推模式,拉模式与此雷同)<br/>　　工具-&gt;复制-&gt;配置发布、订阅服务器和分发-&gt;订阅服务器-&gt;新建-&gt;SQLServer数据库-&gt;输入客户端服务器名称(ZLP)-&gt;使用SQLServer身份验证(sa,空密码)-&gt;确定-&gt;应用-&gt;确定<br/>　　D:初始化订阅<br/>　　复制监视器-&gt;发布服务器(ZEHUADB)-&gt;双击订阅-&gt;强制新建-&gt;下一步-&gt;选择启用的订阅服务器-&gt;ZLP-&gt;<br/>　　下一步-&gt;下一步-&gt;下一步-&gt;下一步-&gt;完成<br/>　　--5:测试配置是否成功<br/>　　复制监视器-&gt;发布服务器(ZEHUADB)-&gt;双击SZ:SZ-&gt;点状态-&gt;点立即运行代理程序<br/>　　查看：<br/>　　复制监视器-&gt;发布服务器(ZEHUADB)-&gt;SZ:SZ-&gt;选择ZLP:SZ(类型强制)-&gt;鼠标右键-&gt;启动同步处理<br/>　　如果没有错误标志(红色叉)，恭喜您配置成功<br/>　　--6:测试数据<br/>　　--在服务器执行:<br/>　　选择一个表，执行如下SQL<br/>　　insert into WQ_NEWSGROUP_S select'测试成功',5<br/>　　复制监视器-&gt;发布服务器(ZEHUADB)-&gt;SZ:SZ-&gt;快照-&gt;启动代理程序<br/>　　                                     -&gt;ZLP:SZ(强制)-&gt;启动同步处理<br/>　　去查看同步的 WQ_NEWSGROUP_S 是否插入了一条新的记录<br/>　　测试完毕，通过。<br/>　　--7修改数据库的同步时间,一般选择夜晚执行数据库同步处理<br/>　　(具体操作略) :D<br/><br/>　　ps:<br/>　　 1）强制删除订阅可查询下面两个表删除相关的内容 （订阅端）<br/>      delete MSreplication_subscriptions<br/>      sysmergesubscriptions<br/>　　 2）同步的时候如果有机器名在安装过SQL后修改过，同步会有问题，需要运行下列程序。<br/>　　--Select @@SERVERNAME,SERVERPROPERTY('ServerName')<br/><br/>USE master<br/>GO<br/>　　-- Declare local variables<br/>DECLARE @serverproperty_servername varchar(100),<br/> @servername   varchar(100)<br/>　　-- Get the value returned by theSERVERPROPERTY system function<br/>Select @serverproperty_servername = CONVERT(varchar(100),SERVERPROPERTY('ServerName'))<br/>　　-- Get the value returned by@@SERVERNAME global variable<br/>Select @servername = CONVERT(varchar(100), @@SERVERNAME)<br/>　　-- Drop the server with incorrectname<br/>EXEC sp_dropserver @server=@servername<br/>　　-- Add the correct server as a localserver<br/>EXEC sp_addserver @server=@serverproperty_servername,@local='local'<br/>									]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4933" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4933</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[c#读写excel(一)]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=6" label=".Net" /> 
	  <updated>2010-09-09T21:13:06+08:00</updated>
	  <published>2010-09-09T21:13:06+08:00</published>
		  <summary type="html"><![CDATA[<br/>　　一<br/>　　首先Add References Excel.dll，注意在MS office 2003的版本中，可能找不到Excel.dll,这时需要从Excel.exe中扣出来，怎么扣？网上有很多方法，扣出来的同时也把Excel.dll变成了受托管的。<br/>       1.读取Excel File。<br/>       其实读取Excel和读取数据库的方式差不多：<br/><br/>#region<br/>1             string StrConn = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + FilePath + ";Extended Properties='Excel 8.0;HDR=NO'";<br/>2              OleDbConnection MyConn = new OleDbConnection(StrConn);<br/>3              MyConn.Open();<br/>4             string StrCmd = "select * from [sheet1$]";<br/>5              OleDbDataAdapter MyCommand = new OleDbDataAdapter(StrCmd,MyConn);<br/>6              DataSet Ds = new DataSet();<br/>7              MyCommand.Fill(Ds,"NameTB");<br/>8              DataTable dt=Ds.Tables["NameTB"]<br/>＃endregion<br/><br/>　　<br/>      如果Excel第一行是表头的话，可以把StrConn里面的HDR=NO改成，HDR=YES; 当然这样读出来的数据有时候是有问题的，比如本来只有3行的数据，却读来有&gt;3行，我还不知道是什么原因，哪位知道告诉我谢谢。那么这个时候可以用下面的方法判断真实的行数：<br/><br/>1             int b = 0;<br/>2             if (Ds.Tables["NameTB"].Rows[Ds.Tables["NameTB"].Rows.Count - 1][0].ToString() != string.Empty)<br/>3                  b = Ds.Tables["NameTB"].Rows.Count;<br/>4             else<br/>5              {<br/>6                 while (Ds.Tables["NameTB"].Rows[b][0].ToString() != string.Empty)<br/>7                  {<br/>8                      b++;<br/>9                  }<br/>10              }<br/><br/>　　      这里的Excel中的数据是一列多行。同时在从Table 中取出来用的时候要保证Ds.Tables["NameTB"].Rows[i][0].ToString() .Trim()!= string.Empty。<br/>      2.生成Excel并插入数据。<br/>      有时我们需要把检索出来的数据导出到Excel。下面说说如何生成,插入数据到Excel. 首先Add References Excel.dll，引用using Excel;<br/>下面的代码是将ListView中的数据导入到Excel：<br/><br/>1              System.Reflection.Missing miss = System.Reflection.Missing.Value;<br/>2              Excel.ApplicationClass m_objExcel = new Excel.ApplicationClass();<br/>               m_objExcel.Visible = false;<br/>3              Excel.Workbooks m_objBooks = (Excel.Workbooks)m_objExcel.Workbooks;<br/>4              Excel.Workbook m_objBook = (Excel.Workbook)(m_objBooks.Add(miss));<br/>5              Excel.Worksheet m_objSheet = (Excel.Worksheet)m_objBook.ActiveSheet;<br/>6              Excel.Range ER = null;<br/>16            ER = m_objSheet.get_Range((object)"A1", System.Reflection.Missing.Value);<br/>17            ER.Value2 = "Last Name";<br/>18            ER.ColumnWidth = 12;<br/>19            ER = m_objSheet.get_Range((object)"B1", System.Reflection.Missing.Value);<br/>20            ER.Value2 = "Frst Name";<br/>21            ER.ColumnWidth = 15;<br/>22            ER = m_objSheet.get_Range((object)"C1", System.Reflection.Missing.Value);<br/>23            ER.Value2 = "Address";<br/>24            ER.ColumnWidth = 35;<br/>43            m_objSheet.get_Range("A1", "D1").Font.Bold = true;<br/>45            m_objSheet.get_Range("A1", "D1").VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;<br/>47             for (int i = 2; i &lt; this.lvResult.Items.Count + 2; i++)<br/>48                  {<br/>50                      m_objExcel.Cells[i, 1] = this.lvResult.Items[i - 2].SubItems[1].Text.ToString().Trim();<br/>51                      m_objExcel.Cells[i, 2] = this.lvResult.Items[i - 2].SubItems[2].Text.ToString().Trim();<br/>52                      m_objExcel.Cells[i, 3] = this.lvResult.Items[i - 2].SubItems[3].Text.ToString().Trim();<br/>59                  }<br/>                 //生成Excel.<br/>61              m_objBook.SaveAs(SavePath, miss, miss, miss, miss, miss, Excel.XlSaveAsAccessMode.xlNoChange, miss, miss, miss, miss, miss);<br/>62              //释放资源。<br/>63              m_objBook.Close(false, miss, miss);<br/>64              m_objBooks.Close();<br/>65              m_objExcel.Quit();<br/>66 <br/>67              System.Runtime.InteropServices.Marshal.ReleaseComObject(ER);<br/>68              System.Runtime.InteropServices.Marshal.ReleaseComObject(m_objSheet);<br/>69              System.Runtime.InteropServices.Marshal.ReleaseComObject(m_objBook);<br/>70              System.Runtime.InteropServices.Marshal.ReleaseComObject(m_objBooks);<br/>71              System.Runtime.InteropServices.Marshal.ReleaseComObject(m_objExcel);<br/>72              GC.Collect();<br/><br/>　　对IO操作一般都要考虑到异常，自己添加。在网上也找了一些例子，觉得上面的资源释放机制是相对比较好的。<br/><br/>　　<br/>　　二<br/><br/>　　C#读写EXCEL方法一<br/>using System;<br/>using System.Collections.Generic;<br/>using System.Drawing;<br/>using System.Reflection;<br/>using System.IO;<br/><br/>namespace ExcelTest<br/>{<br/>     class Program<br/>     {<br/>         static void Main(string[] args)<br/>         {<br/>             ////创建Application对象<br/>             Excel.Application xlsApp = new Excel.Application();<br/>             if (xlsApp == null)<br/>             {<br/>                 return;<br/>             }<br/>　　             xlsApp.Visible = true;<br/><br/>             //得到WorkBook对象, 可以用两种方式<br/>             //之一: 打开已有的文件<br/>             //Excel.Workbook xlsBook = xlsApp.Workbooks.Open(@"E:\Documents and Settings\daniel.chen\Desktop\test.xls",Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value, Missing.Value);<br/>             //之二：新建一个文件<br/>             Excel.Workbook xlsBook = xlsApp.Workbooks.Add(Missing.Value);<br/><br/>             //指定要操作的Sheet，两种方式<br/>             //之一：<br/>             Excel.Worksheet xlsSheet = (Excel.Worksheet)xlsBook.Sheets[1];<br/>             //之二：<br/>             //Excel.Worksheet xlsSheet = (Excel.Worksheet)xlsApp.ActiveSheet;<br/><br/>             //指定单元格，读取数据，两种方法<br/>             //之一：<br/>             Excel.Range range1 = xlsSheet.get_Range("C2",Type.Missing);<br/>             Console.WriteLine(range1.Value2);<br/>             //之二：<br/>             Excel.Range range2 = (Excel.Range)xlsSheet.Cells[2, 3];<br/>             Console.WriteLine(range2.Value2);<br/><br/>             //在单元格中写入数据<br/>             Excel.Range range3 = xlsSheet.get_Range("A1",Type.Missing);<br/>             range3.Value2 = "Hello World!";<br/>             range3.Borders.Color = Color.FromArgb(123, 231, 32).ToArgb();<br/>             range3.Font.Color = Color.Red.ToArgb();<br/>             range3.Font.Name = "Arial";<br/>             range3.Font.Size = 9;<br/>             //range3.Orientation = 90;   //vertical<br/>             range3.Columns.HorizontalAlignment = Excel.Constants.xlCenter;<br/>             range3.VerticalAlignment = Excel.Constants.xlCenter;<br/>             range3.Interior.Color = Color.FromArgb(192,192,192).ToArgb();<br/>             range3.Columns.AutoFit();//adjust the column width automatically<br/><br/>             //在某个区域写入数据数组<br/>             int matrixHeight = 20;<br/>             int matrixWidth = 20;<br/>             string[,] martix=new string[matrixHeight,matrixWidth];<br/>             for (int i = 0; i &lt; matrixHeight; i++)<br/>                 for (int j = 0; j &lt; matrixWidth; j++)<br/>                 {<br/>                     martix[i, j] = String.Format("{0}_{1}", i+1, j+1);<br/>                 }<br/>             string startColName=GetColumnNameByIndex(0);<br/>             string endColName=GetColumnNameByIndex(matrixWidth-1);<br/>             //取得某个区域，两种方法<br/>             //之一：<br/>             Excel.Range range4 = xlsSheet.get_Range("A1",Type.Missing);<br/>             range4 = range4.get_Resize(matrixHeight,matrixWidth);<br/>             //之二：<br/>             //Excel.Range range4 = xlsSheet.get_Range(String.Format("{0}{1}", startColName, 1), String.Format("{0}{1}", endColName, martixHeight));<br/>             range4.Value2 = martix;<br/>             range4.Font.Color = Color.Red.ToArgb();<br/>             range4.Font.Name="Arial";<br/>             range4.Font.Size = 9;<br/>             range4.Columns.HorizontalAlignment = Excel.Constants.xlCenter;<br/><br/>             //设置column和row的宽度和颜色<br/>             int columnIndex=3;<br/>             int rowIndex=3;<br/>             string colName = GetColumnNameByIndex(columnIndex);<br/>             xlsSheet.get_Range(colName + rowIndex.ToString(), Type.Missing).Columns.ColumnWidth = 20;<br/>             xlsSheet.get_Range(colName + rowIndex.ToString(), Type.Missing).Rows.RowHeight = 40;<br/>             xlsSheet.get_Range(colName + rowIndex.ToString(), Type.Missing).Columns.Interior.Color = Color.Blue.ToArgb();//单格颜色<br/>             xlsSheet.get_Range(5 + ":" + 7, Type.Missing).Rows.Interior.Color = Color.Yellow.ToArgb();//第5行到第7行的颜色<br/>             //xlsSheet.get_Range("G : G", Type.Missing).Columns.Interior.Color=Color.Pink.ToArgb();//第n列的颜色如何设置？？<br/>　　             //保存，关闭<br/>             if (File.Exists(@"E:\Documents and Settings\daniel.chen\Desktop\test1.xls"))<br/>             {<br/>                 File.Delete(@"E:\Documents and Settings\daniel.chen\Desktop\test1.xls");<br/>             }<br/>             xlsBook.SaveAs(@"E:\Documents and Settings\daniel.chen\Desktop\test1.xls", Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlNoChange, Type.Missing, Type.Missing, Type.Missing, Type.Missing);<br/>             xlsBook.Close(false, Type.Missing, Type.Missing);<br/>             xlsApp.Quit();<br/>　　             GC.Collect();<br/>　　             Console.ReadKey();<br/>         }<br/>　　         //将column index转化为字母，至多两位<br/>         public static string GetColumnNameByIndex(int index)<br/>         {<br/>             string[] alphabet = new string[] {"","A", "B", "C", "D", "E", "F", "G", "H", "I", "J" ,"K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};<br/>             string result = "";<br/>             int temp = index / 26;<br/>             int temp2 = index % 26 + 1;<br/>             if (temp &gt; 0)<br/>             {<br/>                 result += alphabet[temp];<br/>             }<br/>             result += alphabet[temp2];<br/>             return result;<br/>         }<br/>     }<br/>}<br/>C#读写EXCEL方法二<br/>通过数据库方式<br/>　　   OleDbDataAdapter    ada    =    new    OleDbDataAdapter("Select    *    FROM    [Sheet1$]",    "Provider=Microsoft.Jet.OLEDB.4.0;Data    Source="    +    openFileDialog1.FileName    +    ";Extended    Properties=Excel    8.0;");   <br/>   DataTable    dt    =    new    DataTable();   <br/>   try   <br/>   {   <br/>   ada.Fill(dt);   <br/>   }   <br/>   catch(Exception    ex)   <br/>   {   <br/>   MessageBox.Show(ex.ToString());   <br/>   }   <br/>   dataGrid1.DataSource    =    dt;   <br/>   }<br/>　　 ]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4932" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4932</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[何在ASP.NetAjax中调用WebService]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=7" label="Ajax" /> 
	  <updated>2010-09-09T16:53:54+08:00</updated>
	  <published>2010-09-09T16:53:54+08:00</published>
		  <summary type="html"><![CDATA[<br/>　　何在ASP.Net Ajax中调用WebService<br/>2008-9-22<br/>    今天我想实现利用JavaScript调用WebService我首先就想到了ASP.Net Ajax 因为微软的东西用着方便,我从网上看了看,这东西好多人都写了,我就从官方找了个Demo下了看看源代码,感觉没什么特殊的,于是动手开始写.先添加一个 webservice.asmx然后在default.aspx中加入ScriptManager 并设置serviecs属性<br/>&lt;asp:ScriptManager runat="server" ID="scriptManager"&gt;<br/>        &lt;services&gt;<br/>                &lt;asp:servicereference  path="webservice.asmx" /&gt;<br/>        services&gt;<br/>&lt;/asp:ScriptManager&gt;<br/>然后我有加了个button 并为其指定click事件<br/>&lt;button onclick="getHello()"&gt;hello world&lt;/button&gt;<br/>接下来开始写脚本<br/>&lt;script type="text/javascript"&gt;<br/>    function getHello()<br/>    {<br/>        webservice.HelloWorld(callComplete);<br/>    }<br/>    function callComplete(result)<br/>    {<br/>        alert(result);<br/>    }<br/>&lt;/script&gt;<br/>       按说应该没有什么问题了但是点击按钮的时候脚本报错 webservice未定义 <br/>我就开始和人家的开始比,到底是哪错了,一开始我以为是脚本写的不对,后来看到webservice那部分发现人家导如了Microsoft.Web.Script.Services;这个命名空间,而且在类前设置了[ScriptService]属性,我觉得问题可能就在这了,加上就可以了!<br/>　　如何在ASP.Net Ajax中调用WebService 中国IT实验室收集整理 佚名 2008-9-22 保存本文 推荐给好友 收藏本页 欢迎进入.NET社区论坛，与200万技术人员互动交流 &gt;&gt;进入<br/>    今天我想实现利用JavaScript调用WebService我首先就想到了ASP.Net Ajax 因为微软的东西用着方便,我从网上看了看,这东西好多人都写了,我就从官方找了个Demo下了看看源代码,感觉没什么特殊的,于是动手开始写.先添加一个 webservice.asmx然后在default.aspx中加入ScriptManager 并设置serviecs属性<br/>&lt;asp:ScriptManager runat="server" ID="scriptManager"&gt;<br/>        &lt;services&gt;<br/>                &lt;asp:servicereference  path="webservice.asmx" /&gt;<br/>        services&gt;<br/>&lt;/asp:ScriptManager&gt;<br/>然后我有加了个button 并为其指定click事件<br/>&lt;button onclick="getHello()"&gt;hello world&lt;/button&gt;<br/>接下来开始写脚本<br/>&lt;script type="text/javascript"&gt;<br/>    function getHello()<br/>    {<br/>        webservice.HelloWorld(callComplete);<br/>    }<br/>    function callComplete(result)<br/>    {<br/>        alert(result);<br/>    }<br/>&lt;/script&gt;<br/>       按说应该没有什么问题了但是点击按钮的时候脚本报错 webservice未定义 <br/>我就开始和人家的开始比,到底是哪错了,一开始我以为是脚本写的不对,后来看到webservice那部分发现人家导如了Microsoft.Web.Script.Services;这个命名空间,而且在类前设置了[ScriptService]属性,我觉得问题可能就在这了,加上就可以了!<br/>]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4931" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4931</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[动态执行JAVA脚本]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=14" label="JAVA" /> 
	  <updated>2010-09-09T16:53:38+08:00</updated>
	  <published>2010-09-09T16:53:38+08:00</published>
		  <summary type="html"><![CDATA[<br/>　　1 背景<br/>在我们的项目中，有时候在需要运行时获取一段脚本并执行其逻辑以灵活地实现业务需求。有人的第一想法就是脚本语言，我们当然可以在程序中内嵌一个Python解释器，然后在需要灵活变动的地方使用Python脚本实现我们的逻辑。但是这样做太“重量级”了，况且身为一个Java程序员，你不一定懂得Python的语法，又或者你忠于Java根本不愿把项目交托给其他语言。如果能够使用符合Java语法的脚本，而且不必嵌入任何解释器，那么这是不是一个完美的选择？<br/>　　2 原理 <br/>Java本身具有足够的灵活性能让我们做到这一点，JVM可以在运行时动态编译Java源文件然后加载类，这是Java脚本动态获得生命力的基础。不过，动态编译的输入是一个完整的Java类的源文件，和javac工具一样，而我们要执行的仅仅是一段脚本。另外，这段Java脚本还需要有上下文环境，例如输入和输出，不然凭空写一段脚本没有任何意义，这就要费一番心思去设计了。要满足这些要求也不难，这里提供一个简单的实现方法，基本思路是生成一个临时类，将上下文变量声明为该类的成员，将脚本放在该类的excute()方法里，然后将这个临时类动态编译并执行excute()方法，即可使脚本生效。对于程序来说，动态编译的过程是透明的，其结果是准确获得了脚本的输出。<br/><br/>　　3 具体示例<br/>3.1 需求描述<br/>程序从数据库中取出了别名和姓名，而在界面上显示怎样的名字却不确定，因为这点会经常变动，有些场合显示别名和姓名的组合，有些场合仅显示姓名等等，为了适应这种灵活变化，需要将如何显示名称的逻辑作为一段脚本写在外部文件里，程序在运行时执行这段脚本得到名称然后显示。<br/>　　3.2 解决过程<br/>假设程序从数据库中取出了别名和姓名，分别存入变量<br/>　　view plaincopy to clipboardprint?<br/>String alias = “万里独行”;   <br/>String name = “田伯光”;   <br/>String alias = “万里独行”;<br/>String name = “田伯光”;<br/><br/>　　并从外部文件读取了脚本内容<br/>　　view plaincopy to clipboardprint?<br/>01.String script = “displayName = aliasName + ':' + originalName”;   <br/>String script = “displayName = aliasName + ':' + originalName”;<br/>　　从脚本里可以看到3个变量，分别是displayName、aliasName和originalName，这是我们默认提供给脚本的上下文变量环境，就像在Jsp页面里默认有request对象一样。<br/>　　3.2.1 首先需要构造一个Java类的完整源代码<br/>利用StringBuilder构造如下内容的字符串 String javaSource：<br/>　　view plaincopy to clipboardprint?<br/>01.public class Temp   <br/>02.{    <br/>03.public String aliasName;    <br/>04.public String originalName;    <br/>05.public String displayName;    <br/>06.public void excute()   <br/>07.{   <br/>08.    displayName = aliasName + ‘:’+ originalName;    <br/>09.}   <br/>10.}  <br/>public class Temp<br/>{ <br/>public String aliasName; <br/>public String originalName; <br/>public String displayName; <br/>public void excute()<br/>{<br/>    displayName = aliasName + ‘:’+ originalName; <br/>}<br/>}<br/><br/>其中，excute()方法体的内容就是脚本内容，其余部分是固定的，将aliasName等3个变量声明为Temp类的成员变量，这样就为脚本代码构建了上下文环境（不然连编译都没法通过）。源代码内容构造完成之后，就要将它写入文件，文件名当然就是Temp.java了。<br/>　　view plaincopy to clipboardprint?<br/>01.OutputStream os = new FileOutputStream("Temp.java");    <br/>02.os.write(javaSource.getBytes());    <br/>03.os.close();   <br/>OutputStream os = new FileOutputStream("Temp.java"); <br/>os.write(javaSource.getBytes()); <br/>os.close();<br/>　　这样，就在当前目录产生了一个我们需要的Java源文件。<br/><br/>　　3.2.2 然后编译这个Java源文件和加载编译后的class<br/><br/>　　编译源文件：<br/><br/>　　view plaincopy to clipboardprint?<br/>01.String[] compileArgs = new String[] {"Temp.java"};    <br/>02.com.sun.tools.javac.Main.compile(compileArgs);   <br/>String[] compileArgs = new String[] {"Temp.java"}; <br/>com.sun.tools.javac.Main.compile(compileArgs);<br/>　　注意，使用com.sun.tools.javac.Main类必须为项目添加tools.jar包的引用，这个jar包在JDK根目录下的lib文件夹里，自Java1.4开始包含。如果你的项目用手工编译，则必须添加类路径参数 “-cp tools.jar”。<br/>　　加载编译后的class：<br/><br/>view plaincopy to clipboardprint?<br/>01.URLClassLoader loader =    <br/>02.    new URLClassLoader(new URL[]{new File(".").toURI().toURL()});   <br/>03.Class&lt;?&gt; scriptClass = loader.loadClass("Temp");  <br/>URLClassLoader loader = <br/>    new URLClassLoader(new URL[]{new File(".").toURI().toURL()});<br/>Class&lt;?&gt; scriptClass = loader.loadClass("Temp");<br/>　　3.2.3 然后向临时变量注入上下文变量环境<br/>虽然刚才构造的Java源代码里面已经有了aliasName和originalName两个成员变量提供给脚本代码使用，但是这两个变量并没有实际意义的值，实际的值应该是从数据库里取出来的值，我们要想办法将这个值传递给脚本。<br/>　　view plaincopy to clipboardprint?<br/>01.Object obj = scriptClass.newInstance();    <br/>02.c.getDeclaredField("aliasName").set(obj, alias);    <br/>03.c.getDeclaredField("originalName").set(obj, name);   <br/>Object obj = scriptClass.newInstance(); <br/>c.getDeclaredField("aliasName").set(obj, alias); <br/>c.getDeclaredField("originalName").set(obj, name);<br/>　　用类反射的方法将我们之前从数据库里取出来的别名和姓名赋值给Temp的实例obj，这样当执行脚本的时候，脚本里面所引用的aliasName和originalName就是实际中应用的值了。<br/>　　3.2.4 最后是执行脚本代码并获得显示名称 <br/>view plaincopy to clipboardprint?<br/>01.c.getDeclaredMethod("excute").invoke(obj);    <br/>02.String displayName = (String)c.getDeclaredField("displayName").get(obj);   <br/>c.getDeclaredMethod("excute").invoke(obj); <br/>String displayName = (String)c.getDeclaredField("displayName").get(obj);  <br/>用类反射执行excute()方法实际上就是执行了外部脚本的逻辑，而外部脚本已将显示名称构造完成，所以取出临时变量的displayName属性即是我们需要的显示名称。这样，我们就实现了在运行时获取并执行外部Java脚本的需求，在一些场合下大大提高了应用程序的灵活性。当然，为了提高性能，不可能让程序每次都进行动态编译，可以将临时对象缓存起来，仅当脚本变化后才重新编译，不过这不属于本文的范畴，留待以后讨论。<br/>　　4       改进 <br/>4.1 避免源文件冲突<br/>我们可以通过构造唯一的路径或文件名来保证生成的Java源文件的唯一性，但是复杂的路径会增加后续编译和加载的复杂度，所以最好还是使用唯一的文件名。文件名可以用前缀+UUID的方式构造，也可以通过Java提供的临时文件来构造，临时文件能够保证唯一性。<br/>　　view plaincopy to clipboardprint?<br/>01.//在当前目录构造前缀为Temp，扩展名为.java的临时文件    <br/>02.File.createTempFile("Temp", ".java", new File("."));   <br/>//在当前目录构造前缀为Temp，扩展名为.java的临时文件 <br/>File.createTempFile("Temp", ".java", new File(".")); <br/><br/>　　4.2 编译参数增强 <br/>Main.compile()的参数是一个String数组，它支持的参数和javac工具支持的参数一致，只要将javac命令行的每一个单词依次作为数组的元素即可，例如<br/>　　view plaincopy to clipboardprint?<br/>01.String[] compileArgs =    <br/>02.new String[] { "-d", “.”, “-cp”, “.;xx1.jar;xx2.jar”, "Temp.java"};  <br/>String[] compileArgs = <br/>new String[] { "-d", “.”, “-cp”, “.;xx1.jar;xx2.jar”, "Temp.java"};<br/>　　4.3 简化构造的源代码<br/>如果脚本的上下文变量环境较多，那么构造源代码的过程就变得复杂低效易错，我们可以用继承的方式来消除这种复杂性，而且还可以用”多态”来代替一些类反射的使用，例如定义以下类：<br/>　　view plaincopy to clipboardprint?<br/>01.public abstract class ScriptContext    <br/>02.{    <br/>03.public Object context1;    <br/>04.public Object context2;    <br/>05.//……其他上下文变量    <br/>06.public void excute() {}   <br/>07.}  <br/>public abstract class ScriptContext <br/>{ <br/>public Object context1; <br/>public Object context2; <br/>//……其他上下文变量 <br/>public void excute() {}<br/>}<br/>　　有了这样一个抽象基类，我们构造的源代码只需要继承ScriptContext，然后覆盖excute()方法即可，而执行脚本的过程也可以直接调用ScriptContext.excute()，而不必通过类反射定位到excute()方法然后执行。在新的思路下我们刚才构造的源代码可能变成这样：<br/>　　view plaincopy to clipboardprint?<br/>01.public class Temp {    <br/>02.@Override    <br/>03.public void excute() {    <br/>04.displayName = aliasName + ‘:’ + originalName;   <br/>05.}   <br/>06.}  <br/>public class Temp { <br/>@Override <br/>public void excute() { <br/>displayName = aliasName + ‘:’ + originalName;<br/>}<br/>}<br/>　　而执行脚本的过程也相应简化为：<br/><br/>view plaincopy to clipboardprint?<br/>01.Class&lt;?&gt; scriptClass = loader.loadClass("Temp");    <br/>02.ScriptContext obj = (ScriptContext) scriptClass.newInstance();    <br/>03.obj. aliasName = alias;    <br/>04.obj. originalName = name; //上下文变量属于父类   <br/>05.obj.excute();//利用多态调用覆盖的excute()函数   <br/>06.String displayName = obj. displayName;//直接获得脚本的输出结果 ]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4930" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4930</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[C#获得SQLServer服务器名、数据库...]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=15" label="数据库" /> 
	  <updated>2010-09-09T16:53:21+08:00</updated>
	  <published>2010-09-09T16:53:21+08:00</published>
		  <summary type="html"><![CDATA[<br/>　　using System.Data.SqlClient;   <br/><br/>        /// &lt;summary&gt;   <br/>          /// 获取局域网内的所有数据库服务器名称   <br/>         /// &lt;/summary&gt;   <br/>        /// &lt;returns&gt;服务器名称数组&lt;/returns&gt;   <br/>        public List&lt;string&gt; GetSqlServerNames()   <br/>        {   <br/>            DataTable dataSources = SqlClientFactory.Instance.CreateDataSourceEnumerator().GetDataSources();   <br/><br/>            DataColumn column = dataSources.Columns["InstanceName"];   <br/>            DataColumn column2 = dataSources.Columns["ServerName"];   <br/><br/>            DataRowCollection rows = dataSources.Rows;   <br/>            List&lt;string&gt; Serverlist = new List&lt;string&gt;();   <br/>            string array = string.Empty;   <br/>            for (int i = 0; i &lt; rows.Count; i++)   <br/>            {   <br/>                string str2 = rows[i][column2] as string;   <br/>                string str = rows[i][column] as string;   <br/>                if (((str == null) || (str.Length == 0)) || ("MSSQLSERVER" == str))   <br/>                {   <br/>                    array = str2;   <br/>                }   <br/>                else  <br/>                {   <br/>                    array = str2 + @"\" + str;   <br/>                }   <br/><br/>                Serverlist.Add(array);   <br/>            }   <br/><br/>            Serverlist.Sort();   <br/><br/>            return Serverlist;   <br/>        }   <br/><br/>        /// &lt;summary&gt;   <br/>        /// 查询sql中的非系统库   <br/>        /// &lt;/summary&gt;   <br/>        /// &lt;param name="connection"&gt;&lt;/param&gt;   <br/>        /// &lt;returns&gt;&lt;/returns&gt;   <br/>        public List&lt;string&gt; databaseList(string connection)   <br/>        {   <br/>            List&lt;string&gt; getCataList = new List&lt;string&gt;();   <br/>            string cmdStirng = "select name from sys.databases where database_id &gt; 4";   <br/>            SqlConnection connect = new SqlConnection(connection);   <br/>            SqlCommand cmd = new SqlCommand(cmdStirng, connect);   <br/>            try  <br/>            {   <br/>                if (connect.State == ConnectionState.Closed)   <br/>                {   <br/>                    connect.Open();   <br/>                    IDataReader dr = cmd.ExecuteReader();   <br/>                    getCataList.Clear();   <br/>                    while (dr.Read())   <br/>                    {   <br/>                        getCataList.Add(dr["name"].ToString());   <br/>                    }   <br/>                    dr.Close();   <br/>                }   <br/><br/>            }   <br/>            catch (SqlException e)   <br/>            {   <br/>                //MessageBox.Show(e.Message);   <br/>            }   <br/>            finally  <br/>            {   <br/>                if (connect != null &amp;&amp; connect.State == ConnectionState.Open)   <br/>                {   <br/>                    connect.Dispose();   <br/>                }   <br/>            }   <br/>            return getCataList;   <br/>        }   <br/><br/>        /// &lt;summary&gt;   <br/>        /// 获取列名   <br/>        /// &lt;/summary&gt;   <br/>        /// &lt;param name="connection"&gt;&lt;/param&gt;   <br/>        /// &lt;returns&gt;&lt;/returns&gt;   <br/>        public List&lt;string&gt; GetTables(string connection)   <br/>        {   <br/>            List&lt;string&gt; tablelist = new List&lt;string&gt;();   <br/>            SqlConnection objConnetion = new SqlConnection(connection);   <br/>            try  <br/>            {   <br/>                if (objConnetion.State == ConnectionState.Closed)   <br/>                {   <br/>                    objConnetion.Open();   <br/>                    DataTable objTable = objConnetion.GetSchema("Tables");   <br/>                    foreach (DataRow row in objTable.Rows)   <br/>                    {   <br/>                        tablelist.Add(row[2].ToString());   <br/>                    }   <br/>                }   <br/>            }   <br/>            catch  <br/>            {   <br/><br/>            }   <br/>            finally  <br/>            {   <br/>                if (objConnetion != null &amp;&amp; objConnetion.State == ConnectionState.Closed)   <br/>                {   <br/>                    objConnetion.Dispose();   <br/>                }   <br/><br/>            }   <br/>            return tablelist;   <br/>        }   <br/><br/>        /// &lt;summary&gt;   <br/>        /// 获取字段   <br/>        /// &lt;/summary&gt;   <br/>        /// &lt;param name="connection"&gt;&lt;/param&gt;   <br/>        /// &lt;param name="TableName"&gt;&lt;/param&gt;   <br/>        /// &lt;returns&gt;&lt;/returns&gt;   <br/>        public List&lt;string&gt; GetColumnField(string connection, string TableName)   <br/>        {   <br/>            List&lt;string&gt; Columnlist = new List&lt;string&gt;();   <br/>            SqlConnection objConnetion = new SqlConnection(connection);   <br/>            try  <br/>            {   <br/>                if (objConnetion.State == ConnectionState.Closed)   <br/>                {   <br/>                    objConnetion.Open();   <br/>                }   <br/><br/>                SqlCommand cmd = new SqlCommand("Select Name FROM SysColumns Where id=Object_Id('" + TableName + "')", objConnetion);   <br/>                SqlDataReader objReader = cmd.ExecuteReader();   <br/><br/>                while (objReader.Read())   <br/>                {   <br/>                    Columnlist.Add(objReader[0].ToString());   <br/><br/>                }   <br/>            }   <br/>            catch  <br/>            {   <br/><br/>            }   <br/>            objConnetion.Close();   <br/>            return Columnlist;   <br/>        }<br/><br/>本文来自CSDN博客，转载请标明出处：http://blog.csdn.net/kenkao/archive/2010/08/17/5817407.aspx]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4929" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4929</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[如何在C#中使用全局鼠标、键盘Hook]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=6" label=".Net" /> 
	  <updated>2010-09-09T16:53:04+08:00</updated>
	  <published>2010-09-09T16:53:04+08:00</published>
		  <summary type="html"><![CDATA[<br/>　　　　今天，有个同事问我，怎样在C#中使用全局钩子？以前写的全局钩子都是用unmanaged C或C++写个DLL来实现，可大家都知道，C#是基于.Net Framework的，是managed，怎么实现全局钩子呢？于是开始到网上搜索，好不容易找到一篇，318804 - HOW TO: Set a Windows Hook in Visual C# .NET，里面详细的说明了如何使用鼠标钩子捕获鼠标的移动等，可是，它只能在Application里起作用，出了Application就没用了，就是说它还是没有实现全局钩子，而且文章结尾处说：“Global Hooks are not supported in the .NET Framework...”，这可怎么办呢？<br/>　　别担心，办法总是有的，经过一番摸索以后，发现WH_KEYBORAD_LL和WH_MOUSE_LL这两个low-level的hook可以被安装成全局的，这就好办了，我们不妨用这两个low-level的hook替换掉WH_KEYBORAD和WH_MOUSE，于是开始测试。结果成功了，在C#里实现了全局钩子。<br/>　　我们来看一下主要代码段。<br/>　　首先倒入所需要的windows函数，主要有三个，SetWindowsHookEX用来安装钩子，UnhookWindowsHookEX用来卸载钩子以及CallNextHookEX用来将hook信息传递到链表中下一个hook处理过程。<br/><br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">[DllImport("user32.dll", CharSet = CharSet.Auto,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">           CallingConvention = CallingConvention.StdCall, SetLastError = true)]<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">        private static extern int SetWindowsHookEx(<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            int idHook,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            HookProc lpfn,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            IntPtr hMod,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            int dwThreadId);<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif"><br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">[DllImport("user32.dll", CharSet = CharSet.Auto,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            CallingConvention = CallingConvention.StdCall, SetLastError = true)]<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">        private static extern int UnhookWindowsHookEx(int idHook);<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif"><br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">[DllImport("user32.dll", CharSet = CharSet.Auto,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">             CallingConvention = CallingConvention.StdCall)]<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">        private static extern int CallNextHookEx(<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            int idHook,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            int nCode,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            int wParam,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">            IntPtr lParam);<br/>　　下面是有关这两个low-level hook在Winuser.h中的定义：<br/>/// &lt;summary&gt;<br/>        /// Windows NT/2000/XP: Installs a hook procedure that monitors low-level mouse input events.<br/>        /// &lt;/summary&gt;<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">        private const int WH_MOUSE_LL       = 14;<br/>        /// &lt;summary&gt;<br/>        /// Windows NT/2000/XP: Installs a hook procedure that monitors low-level keyboard  input events.<br/>        /// &lt;/summary&gt;<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">        private const int WH_KEYBOARD_LL    = 13;<br/>　　在安装全局钩子的时候，我们就要做替换了，将WH_MOUSE和WH_KEYBORAD分别换成WH_MOUSE_LL和WH_KEYBORAD_LL：<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">//install hook<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                hMouseHook = SetWindowsHookEx(<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    WH_MOUSE_LL,　//原来是WH_MOUSE<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    MouseHookProcedure,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    Marshal.GetHINSTANCE(<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                        Assembly.GetExecutingAssembly().GetModules()[0]),<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    0);<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif"><br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">//install hook<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                hKeyboardHook = SetWindowsHookEx(<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    WH_KEYBOARD_LL, //原来是WH_KEYBORAD<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    KeyboardHookProcedure,<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    Marshal.GetHINSTANCE(<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    Assembly.GetExecutingAssembly().GetModules()[0]),<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">                    0);<br/><br/>　　这样替换了之后，我们就可以实现全局钩子了，而且，不需要写DLL。看一下程序运行情况：<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" border=0 hspace=1 alt="" vspace=1 src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125855546.jpg"><br/>　　下面是关于鼠标和键盘的两个Callback函数：<br/><br/>　　private int MouseHookProc(int nCode, int wParam, IntPtr lParam)<br/>　　        {<br/>　　            // if ok and someone listens to our events<br/>　　            if ((nCode &gt;= 0) &amp;&amp; (OnMouseActivity != null))<br/>　　            {<br/>　　                //Marshall the data from callback.<br/>　　                MouseLLHookStruct mouseHookStruct = (MouseLLHookStruct)Marshal.PtrToStructure(lParam, typeof(MouseLLHookStruct));<br/><br/>　　                //detect button clicked<br/>　　                MouseButtons button = MouseButtons.None;<br/>　　                short mouseDelta = 0;<br/>　　                switch (wParam)<br/>　　                {<br/>　　                    case WM_LBUTTONDOWN:<br/>　　                        //case WM_LBUTTONUP:<br/>　　                        //case WM_LBUTTONDBLCLK:<br/>　　                        button = MouseButtons.Left;<br/>　　                        break;<br/>　　                    case WM_RBUTTONDOWN:<br/>　　                        //case WM_RBUTTONUP:<br/>　　                        //case WM_RBUTTONDBLCLK:<br/>　　                        button = MouseButtons.Right;<br/>　　                        break;<br/>　　                    case WM_MOUSEWHEEL:<br/>　　                        //If the message is WM_MOUSEWHEEL, the high-order word of mouseData member is the wheel delta.<br/>　　                        //One wheel click is defined as WHEEL_DELTA, which is 120.<br/>　　                        //(value &gt;&gt; 16) &amp; 0xffff; retrieves the high-order word from the given 32-bit value<br/>　　                        mouseDelta = (short)((mouseHookStruct.mouseData &gt;&gt; 16) &amp; 0xffff);<br/>　　                        //TODO: X BUTTONS (I havent them so was unable to test)<br/>　　                        //If the message is WM_XBUTTONDOWN, WM_XBUTTONUP, WM_XBUTTONDBLCLK, WM_NCXBUTTONDOWN, WM_NCXBUTTONUP,<br/>　　                        //or WM_NCXBUTTONDBLCLK, the high-order word specifies which X button was pressed or released,<br/>　　                        //and the low-order word is reserved. This value can be one or more of the following values.<br/>　　                        //Otherwise, mouseData is not used.<br/>　　                        break;<br/>　　                }<br/><br/>　　                //double clicks<br/>　　                int clickCount = 0;<br/>　　                if (button != MouseButtons.None)<br/>　　                    if (wParam == WM_LBUTTONDBLCLK || wParam == WM_RBUTTONDBLCLK) clickCount = 2;<br/>　　                    else clickCount = 1;<br/><br/>　　                //generate event<br/>　　                 MouseEventArgs e = new MouseEventArgs(<br/>　　                                                    button,<br/>　　                                                    clickCount,<br/>　　                                                    mouseHookStruct.pt.x,<br/>　　                                                    mouseHookStruct.pt.y,<br/>　　                                                    mouseDelta);<br/>　　                //raise it<br/>　　                OnMouseActivity(this, e);<br/>　　            }<br/>　　            //call next hook<br/>　　            return CallNextHookEx(hMouseHook, nCode, wParam, lParam);<br/>　　        }<br/><IMG title="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" alt="如何在C中使用全局鼠标、键盘Hook - 静待〃花落 - 静待〃花落" src="http://www.bccn.net/Article/UploadFDL0024/200709/20070901125852299.gif">private int KeyboardHookProc(int nCode, Int32 wParam, IntPtr lParam)<br/> {<br/>            //indicates if any of underlaing events set e.Handled flag<br/>            bool handled = false;<br/>            //it was ok and someone listens to events<br/>            if ((nCode &gt;= 0) &amp;&amp; (KeyDown != null || KeyUp != null || KeyPress != null))<br/>            {<br/>                //read structure KeyboardHookStruct at lParam<br/>                KeyboardHookStruct MyKeyboardHookStruct = (KeyboardHookStruct)Marshal.PtrToStructure(lParam, typeof(KeyboardHookStruct));<br/>                //raise KeyDown<br/>                if (KeyDown != null &amp;&amp; (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN))<br/>                {<br/>                    Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;<br/>                    KeyEventArgs e = new KeyEventArgs(keyData);<br/>                    KeyDown(this, e);<br/>                    handled = handled || e.Handled;<br/>                }<br/>                // raise KeyPress<br/>                if (KeyPress != null &amp;&amp; wParam == WM_KEYDOWN)<br/>                {<br/>                    bool isDownShift = ((GetKeyState(VK_SHIFT) &amp; 0x80) == 0x80 ? true : false);<br/>                    bool isDownCapslock = (GetKeyState(VK_CAPITAL) != 0 ? true : false);<br/>                    byte[] keyState = new byte[256];<br/>                    GetKeyboardState(keyState);<br/>                    byte[] inBuffer = new byte[2];<br/>                    if (ToAscii(MyKeyboardHookStruct.vkCode,<br/>                              MyKeyboardHookStruct.scanCode,<br/>                              keyState,<br/>                              inBuffer,<br/>                              MyKeyboardHookStruct.flags) == 1)<br/>                    {<br/>                        char key = (char)inBuffer[0];<br/>                        if ((isDownCapslock ^ isDownShift) &amp;&amp; Char.IsLetter(key)) key = Char.ToUpper(key);<br/>                        KeyPressEventArgs e = new KeyPressEventArgs(key);<br/>                        KeyPress(this, e);<br/>                        handled = handled || e.Handled;<br/>                    }<br/>                }<br/>                // raise KeyUp<br/>                if (KeyUp != null &amp;&amp; (wParam == WM_KEYUP || wParam == WM_SYSKEYUP))<br/>                {<br/>                    Keys keyData = (Keys)MyKeyboardHookStruct.vkCode;<br/>                    KeyEventArgs e = new KeyEventArgs(keyData);<br/>                    KeyUp(this, e);<br/>                    handled = handled || e.Handled;<br/>                }<br/>            }<br/>            //if event handled in application do not handoff to other listeners<br/>            if (handled)<br/>                return 1;<br/>            else<br/>                return CallNextHookEx(hKeyboardHook, nCode, wParam, lParam);<br/>        }<br/><br/>　　<br/>　　 ]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4928" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4928</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[关于magicajax的用法]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=7" label="Ajax" /> 
	  <updated>2010-09-09T12:33:30+08:00</updated>
	  <published>2010-09-09T12:33:30+08:00</published>
		  <summary type="html"><![CDATA[					<br/><br/>　　MagicAjax（http://www.magicajax.net/），他让你体验什么叫EasyAJAX，并支持.Net2.0。你无需对现有的webform方式开发有任何的改变，你只需配配web.config，拉拉控件就行了。本文不说用法，因为他实在太简单了，我在这里对他做一个分析，让大家了解他的工作方式。<br/><br/>最近，用了一下MagicAjax觉得不错，使用很简单，经验终结如下：<br/>-----------------------------------------------------------------------------------------<br/>让MagicAjax支持中文！<br/>　　我直接改ajaxcallobject.js文件也可以呀。。 <br/>不过web.config要写上js的路径,我参考了以前一篇文章。。<br/>下面是web.config的配制 <br/>&lt;magicAjax scriptPath ="~/js/ajaxscript/"<br/>outputCompareMode="HashCode" <br/>tracing="false"&gt; <br/>&lt;pageStore<br/>mode="NoStore" <br/>unloadStoredPage="false" <br/>cacheTimeout="5"<br/>maxConcurrentPages="5" <br/>maxPagesLimitAlert="false" <br/><br/><br/>/&gt;<br/>&lt;/magicAjax&gt;<br/>-----------------------------------------------------------------------------------------<br/>　　1．  首先去http://sourceforge.net/projects/magicajax下载MagicAjax的Dll了。<br/>　　2．  将该dll加入到webForm所在项目的引用中。<br/>　　3．  在Web.Config文件中&lt;configuration&gt;节点下添加如下子节点：<br/>　　    &lt;configSections&gt;<br/>　　       &lt;section name="magicAjax"type="MagicAjax.Configuration.MagicAjaxSectionHandler, MagicAjax" /&gt;<br/>　　    &lt;/configSections&gt;<br/>　　4．  在Web.Config文件中&lt; system.web&gt;节点下添加如下子节点：<br/>　　        &lt;httpModules&gt;<br/>　　            &lt;add name="MagicAjaxModule" type="MagicAjax.MagicAjaxModule,MagicAjax" /&gt;<br/>　　        &lt;/httpModules&gt;<br/>　　5．  在希望采用Ajax的webForm页面HTML开头引入Ajax的注册语句：<br/>　　&lt;%@ Register TagPrefix="ajax" Namespace="MagicAjax.UI.Controls"Assembly="MagicAjax" %&gt;<br/>　　-----------------------------------------------------------------------------------------<br/>　　  1、打开vs 添加 MagicAjax.dll，就会有AjaxPanel 控件，就往上拖东西吧。（简单吧！）<br/>  2、打开web.config添加：<br/>　　        &lt;configSections&gt;<br/>           &lt;section name="magicAjax"type="MagicAjax.Configuration.MagicAjaxSectionHandler,MagicAjax"/&gt;<br/>        &lt;/configSections&gt;<br/>　　            &lt;system.web&gt;<br/>               ...<br/>&lt;httpModules&gt;<br/>                         &lt;add name="MagicAjaxModule"type="MagicAjax.MagicAjaxModule, MagicAjax"/&gt;<br/>&lt;/httpModules&gt;<br/>              ...<br/>           &lt;/system.web&gt;<br/>　　       以上两步就可以实现Ajax了，是不是很简单。如果你觉得loading....很难看，接着来。<br/>　　 3、首先，下载magicAjax源码，拷贝script目录到你的目录里。<br/>　　4、 打开web.config 添加：<br/>　　           &lt;magicAjax tracing="false"scriptPath="~/script"&gt;<br/>            &lt;pageStore/&gt;<br/>&lt;/magicAjax&gt;<br/>　　5、 打开script目录，编辑AjaxCallObject.js（在最后）找到并改成下面的，<br/>.....<br/>                  function CreateWaitElement(){<br/>                      var elem =document.getElementById('__AjaxCall_Wait');<br/>                   if (!elem) {<br/>                             elem =document.createElement("div");<br/>                             elem.id ='__AjaxCall_Wait';<br/>                             elem.style.position ='absolute';<br/>                             elem.style.height =17;<br/>                             elem.border ="1px";<br/>                             elem.style.paddingLeft ="3px";<br/>                             elem.style.paddingRight ="3px";<br/>                             elem.style.fontSize ="12px";<br/>                             elem.style.borderColor ="#990000";<br/>                             elem.style.borderWidth ="0";<br/>elem.style.borderStyle="solid";<br/>elem.style.backgroundColor = "#990000";<br/>elem.style.color = "#FFFFFF";<br/>                             elem.innerHTML ="正在加载...";<br/>                             elem.style.visibility = 'hidden';<br/>　　                        document.body.insertBefore(elem,document.body.firstChild);     <br/>                }<br/>waitElement = elem;    <br/>                   }<br/>                    // endwait element<br/><br/>           试一下 ，看看效果，怎么出现乱码？别急，接着改。<br/>　　6、 打开web.config 改<br/>       第一：&lt;?xml version="1.0" encoding="gb2312" ?&gt;<br/>       第二：添加 <br/>&lt;globalization<br/>requestEncoding="gb2312"<br/>responseEncoding="gb2312"<br/>/&gt;<br/><br/>-----------------------------------------------------------------------------------------<br/><br/>好，再试试！如何，不错吧！大家可能还有更好的方法，期待高手指点！<br/>　　再加一个定时刷新的： <br/>... <br/>protected void Page_Load(object sender, EventArgs e)<br/>{ <br/>if (!IsPostBack) <br/>{ <br/>//每10秒刷新<br/>MagicAjax.AjaxCallHelper.SetAjaxCallTimerInterval(10000); <br/>}<br/>this.Label1.Text = DateTime.Now.ToString();<br/>　　} <br/>....<br/><br/>　　从例子入手吧，一个button，一个label，点击button更新lable到当前时间。<br/>　　设计器上的html： <br/>&lt;div style="width: 300px"&gt; <br/>    &lt;ajax:AjaxPanelID="AjaxPanel1" runat="server"&gt; <br/>        &lt;asp:Button ID="Button1"runat="server" OnClick="Button1_Click" Text="Button" /&gt; <br/>&lt;asp:Label ID="Label1" runat="server"Text="Label"&gt;&lt;/asp:Label&gt;&lt;/ajax:AjaxPanel&gt; <br/>&lt;/div&gt;<br/>输出后的html： <br/>&lt;div&gt; <br/>&lt;input type="hidden"name="__CONTROL_FINGERPRINTS_AjaxPanel1" id="__CONTROL_FINGERPRINTS_AjaxPanel1"value="" /&gt; <br/>&lt;input type="hidden" name="AjaxPanel1$RBS_Store"id="AjaxPanel1$RBS_Store" value="" /&gt; <br/>&lt;input type="hidden"name="__VIEWSTATE" id="__VIEWSTATE"value="/wEPDwUJNTg1NTY3MzczD2QWAgIDD2QWAgIBDw9kFgIeCEFqYXhDYWxsBQVhc3luY2RkWqu19ZXiwLYiiNPPAP+GKoHYdzs="/&gt; <br/>&lt;/div&gt; <br/>&lt;div style="width: 300px"&gt; <br/>    &lt;spanid='AjaxPanel1$RBS_Holder'&gt;&lt;span id="Span1" AjaxCall="async"&gt;<br/>        &lt;span id="Button1$ajaxdest" name="__ajaxmark"&gt;&lt;inputtype="submit" name="Button1" value="Button" id="Submit1" /&gt;&lt;/span&gt;<br/>        &lt;span id="Label1$ajaxdest" name="__ajaxmark"&gt;&lt;spanid="Span2"&gt;Label&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;<br/>&lt;/div&gt; <br/>&lt;script type="text/javascript"&gt; <br/>&lt;!--<br/>var RBS_Controls =  newArray(document.getElementById("AjaxPanel1$RBS_Holder")); <br/>varRBS_Controls_Store =  new Array(document.forms[0]["AjaxPanel1$RBS_Store"]);<br/>// --&gt; <br/>&lt;/script&gt;<br/>　　MagicAjaxModule是一个IHttpModule拦截请求。主要处理在： <br/>voidApplication_AcquireRequestState(object sender, EventArgs e)<br/>&middot;如果是普通Page，直接输出页面。 <br/>&middot;如果请求是&ldquo;Get&rdquo;，直接输出页面。<br/>&middot;如果是ajax请求的话，由_request.Form["__AJAXCALL"]判断是否一个ajax请求，如果是则调用HttpContext.Current.Handler.ProcessRequest(HttpContext.Current)并更新相关状态，包括ViewState，最后Flush()页面。在这个过程当中，输出都是交给AjaxCallHelper完成，而这个help最后产生一个script，那么在客户端在接收到这个script，就直接执行：eval(responseText).比如例子中点击button后，最后产生的script是：<br/>AJAXCbo.ExtendedSetHtmlOfElementScript("&lt;span id=\"Label1\"&gt;2005-12-818:03:22&lt;/span&gt;","Label1$ajaxdest");<br/>　　AJAXCbo.SetFieldScript("__CONTROL_FINGERPRINTS_AjaxPanel1","C04A0FC;Button1#7DA27781;Label1#F84162CA");<br/>　　AJAXCbo.SetFieldScript("__VIEWSTATE","/wEPDwUKMTkwNzc1NDY4MQ9kFgICAw9kFgICAQ8PZBYCHghBamF4Q2FsbAUFYXN5bmMWAgIDDw8WAh4EVGV4dAUSMjAwNS0xMi04IDE4OjAzOjIyZGRk+HNmUx11Ztw2Z2CodiIhPxrEm4A=");<br/>　　'AJAX_LOADING_OK'; 由此可以看出，点击button后，返回给客户端，客户端负责解释和执行这个script。<br/>第一行：更新label里面的时间 <br/>第二行：更新panel的隐含字段 <br/>第三行：更新ViewState<br/>第四行：一个标志，表示请求成功<br/>　　客户端的js工作流程：<br/>1）首先，他把页面所有的ajaxPanel放在一个array里面：RBS_Controls，而每个panel都对应到另外一个array：RBS_Controls_Store里面的各个panel的状态。 <br/>2）这时候大家注意到页面上这句js： <br/>&lt;scriptlanguage='javascript'&gt; <br/>    if (typeof(AJAXCbo) == 'undefined')<br/>        alert("Unable to find script library '/AjaxCallObject.js'. Copy thefile to the required location, or change the 'scriptPath' setting at magicAjaxsection of web.config."); <br/>    else <br/>AJAXCbo.HookAjaxCall(false,false,false); <br/>&lt;/script&gt;AjaxCallObject.prototype.HookAjaxCall = function(bPageIsStored,bUnloadStoredPage, bTracing)会hook几个事件： <br/>window.onload，window.onbeforeunload，  window.onunload，document.forms[0].onsubmit（这是是重点）<br/>3）点击panel里面的button发出一个submit，由于document.forms[0].onsubmit被hook了，他在这里引发：AJAXCbo.DoAjaxCall(target.name,"", cbType)并return false,就不会引发页面刷新。<br/>4）在DoAjaxCall里面，一个for循环把form里面的内容序列化成字符串放在变量theData里面<br/>5）调用XmlHttp工作：open-&gt;onreadystatechange（设置异步完成引发事件）-&gt;setRequestHeader-&gt;send<br/>不管异步调用还是同步调用，最后都会引发：OnComplete事件，OnComplete就会调用eval(responseText)来执行服务段返回的script了。<br/>　　AjaxPanel控件： <br/>控件主要render HTML，配合客户端的js工作。<br/>&middot;构造函数初始化控件的panel里面的XmlHttp请求方式。（同步/异步） <br/>&middot;void AddedControl(Controlcontrol, int index)把panel里面的服务端控件加到_addedControls这个集合里面，上面就是把Button1和Lable1加载。<br/>&middot;void OnLoad(EventArgse)注册这个panel的隐含字段，就是上面的__CONTROL_FINGERPRINTS_AjaxPanel1。 <br/>&middot;voidOnPreRender(EventArgs e)：如果不是嵌套的panel加入隐含字段AjaxPanel1$RBS_Store和两个变量（RBS_Controls和RBS_Controls_Store）用处处理客户端AJAX调用。这里必要说明一下，这个隐含字段是用于类似ViewState的用途？<br/>&middot;void Render(HtmlTextWriter writer)把非嵌套的panel输出成&lt;span&gt;，就是上面的&lt;spanid='AjaxPanel1$RBS_Holder'&gt; ，如果是嵌套的panel就只有顶层的panel有这个&lt;span&gt;。 <br/>&middot;voidRenderChildren(HtmlTextWriterwriter)把panel里面的子控件输出，非服务端控件输出不变。如果是服务端控件就把这个控件放在一个&lt;span&gt;里面，并且id为：控件名称+$ajaxdest，name为：__ajaxmark。最后如果IsPageNoStoreMode是true则注册一个js，他会在客户端执行（AJAXCbo.SetFieldIfEmptyScript），把控件的状态放到__CONTROL_FINGERPRINTS_AjaxPanel1这个隐含字段。<br/>&lt;script type='text/javascript'&gt;<br/>AJAXCbo.SetFieldIfEmptyScript("__CONTROL_FINGERPRINTS_AjaxPanel1","C04A0FC;Button1#7DA27781;Label1#31926D7E");<br/>&lt;/script&gt; &middot;void OnUnload(EventArgse)IsPageNoStoreMode为true的话，会更新控件的更新控件的状态。<br/><br/>哈～好像写完了，最后给大家一个小秘诀。看看AjaxCallObject.js，当请求的时候，他会象GMail那样在右上脚出现一个Wait...的等待，很cool，你只要在这里做一个小更改，改CreateWaitElement那部分就能达到另外的效果。我这里把请求数据时，改成windows关机时，整个页面变灰的那种效果，类似的js如下：&lt;SCRIPT type="text/javascript"&gt;<br/>    &lt;!--<br/>    functionlog_out()<br/>    {<br/>        ht1 =parent.frames.item(0).document.getElementsByTagName("html");<br/>ht1[0].style.filter ="progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)";<br/>        ht2 =document.getElementsByTagName("html");<br/>        ht2[0].style.filter ="progid:DXImageTransform.Microsoft.BasicImage(grayscale=1)";<br/>        if(confirm('你是否确认注销？'))<br/>        {<br/>            return true;<br/>}<br/>        else<br/>        {<br/>            ht1[0].style.filter ="";<br/>            ht2[0].style.filter = "";<br/>            returnfalse;<br/>        }<br/>    }<br/>    //--&gt;<br/>&lt;/SCRIPT&gt;<br/>　　这是一个全新的开放源代码Ajax框架，比我用过的Ajax.NET要方便很多很多，不但需要学习的东西少，而且加入ajax技术后，你的网站甚至可以不用编译，只需要修改ａｓｐｘ文件就可以。这一切让我惊喜不已，所有赶快拿出来和大家分享。MagicAjax.NET支持.NET1.1和2.0，但是目前我下载到的源代码是需要.NET2.0。<br/>　　MagicAjax.NET方便之处在于：他提供一个AjaxPanel的容器控件，需要无刷新更新的部分（控件，HTML代码...）放到这个Panel里面就可以;MagicAjax.NET也不需要在程序后台代码中添加什么东西，而且web.config的配置也不复杂。<br/><br/>　　<br/>      我做了个简单的测试程序。用Google的广告来看是否整个页面刷新。<br/>       在页面上拖放一个AjaxPanel控件，然后把Botton和Label控件放到里面。如果把Botton放到Panel外面，那么会整页刷新。<br/>      <img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/images/cnblogs_com/format/design.JPG" border="1" alt="design.JPG" width="466" height="220" /><br/>Botton控件的事件代码是：<br/>1<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />private void btnTime_Click(object sender, System.EventArgs e)<br/>2<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" /><img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />        <img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://www.cnblogs.com/Images/dot.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />{<br/>3<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/InBlock.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />            this.lblTime.Text=DateTime.Now.ToString();<br/>4<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />        }<br/>　　最后的效果：<br/><img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/images/cnblogs_com/format/after.JPG" border="1" alt="after.JPG" width="279" height="216" /><br/><br/>效果非常好!使用很方便。<br/><br/>后面给大家一个最基本的web.config配置文件。如果在.NET1.1下，那么必须要有这个，然而程序无法找到嵌入其中的js资源。 1<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />&lt;configuration&gt;<br/> 2<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />    &lt;configSections&gt;<br/> 3<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />        &lt;section name="magicAjax" <br/> 4<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />                type="MagicAjax.Configuration.MagicAjaxSectionHandler, MagicAjax"/&gt;<br/> 5<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />    &lt;/configSections&gt;<br/> 6<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />    <br/> 7<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />    &lt;magicAjax<br/> 8<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />        outputCompareMode="HashCode"<br/> 9<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />        tracing="false"&gt;<br/>10<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />        &lt;pageStore<br/>11<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />            mode="NoStore"<br/>12<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />            unloadStoredPage="false"<br/>13<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />            cacheTimeout="5"<br/>14<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />            maxConcurrentPages="5"<br/>15<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />            maxPagesLimitAlert="false"<br/>16<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />        /&gt;<br/>17<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />    &lt;/magicAjax&gt;<br/>18<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" /> &lt;system.web&gt;<br/>19<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />  &lt;httpModules&gt;<br/>20<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />             &lt;add name="MagicAjax" type="MagicAjax.MagicAjaxModule, MagicAjax" /&gt; <br/>21<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />     &lt;/httpModules&gt;<br/>22<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" /><br/>23<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" /> &lt;/system.web&gt;<br/>24<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" /><br/>25<img title="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" src="http://format.cnblogs.com/Images/OutliningIndicators/None.gif" alt="关于magicajax的用法 - 帅虎 - 帅虎的猫窝" />&lt;/configuration&gt;					<br/>　　						发表于 @						2010年09月09日　09:36:00 &#124; 评论( loading...							) &#124; 编辑&#124									举报&#124; 收藏								查看最新精华文章 请访问博客首页相关文章				]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4927" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4927</id> 
  </entry>	
		
  <entry>
	  <title type="html"><![CDATA[java网络通信小程序]]></title>
	  <author>
		 <name></name>
		 <uri>http://www.zhangyongjun.com/blog/</uri>
		 <email>achely@gmail.com</email>
	  </author>
	  <category term="" scheme="http://www.zhangyongjun.com/blog/default.asp?cateID=14" label="JAVA" /> 
	  <updated>2010-09-09T12:33:26+08:00</updated>
	  <published>2010-09-09T12:33:26+08:00</published>
		  <summary type="html"><![CDATA[			//ChatServer.java文件<br/>　　　　import java.io.*;<br/>　　　　import java.net.*;<br/>　　　　import java.util.*;<br/>　　　　public class ChatServer {<br/>　　　　boolean started = false;<br/>　　　　ServerSocket ss = null;<br/>　　　　List&lt;Client&gt; clients = newArrayList&lt;Client&gt;();<br/>　　　　public static void main(String[] args) {<br/>　　　　new ChatServer().start();<br/>　　　　}<br/>　　　　public void start() {<br/>　　　　try {<br/>　　　　ss = new ServerSocket(8888);<br/>　　　　started = true;<br/>　　　　} catch (BindException e) {<br/>　　　　System.out.println("端口使用中....");<br/>　　　　System.out.println("请关掉相关程序并重新运行服务器！");<br/>　　　　System.exit(0);<br/>　　　　} catch (IOException e) {<br/>　　　　e.printStackTrace();<br/>　　　　}<br/>　　　　try {<br/>　　　　while(started) {<br/>　　　　Socket s = ss.accept();<br/>　　　　Client c = new Client(s);<br/>　　　　System.out.println("a client connected!");<br/>　　　　new Thread(c).start();<br/>　　　　clients.add(c);<br/>　　　　//dis.close();<br/>　　　　}<br/>　　　　} catch (IOException e) {<br/>　　　　e.printStackTrace();<br/>　　　　} finally {<br/>　　　　try {<br/>　　　　ss.close();<br/>　　　　} catch (IOException e) {<br/>　　　　// TODO Auto-generated catch block<br/>　　　　e.printStackTrace();<br/>　　　　}<br/>　　　　}<br/>　　　　}<br/>　　　　class Client implements Runnable {<br/>　　　　private Socket s;<br/>　　　　private DataInputStream dis = null;<br/>　　　　private DataOutputStream dos = null;<br/>　　　　private boolean bConnected = false;<br/>　　　　public Client(Socket s) {<br/>　　　　this.s = s;<br/>　　　　try {<br/>　　　　dis = new DataInputStream(s.getInputStream());<br/>　　　　dos = new DataOutputStream(s.getOutputStream());<br/>　　　　bConnected = true;<br/>　　　　} catch (IOException e) {<br/>　　　　e.printStackTrace();<br/>　　　　}<br/>　　　　}<br/>　　public void send(String str) {<br/>　　　　try {<br/>　　　　dos.writeUTF(str);<br/>　　　　} catch (IOException e) {<br/>　　　　clients.remove(this);<br/>　　　　System.out.println("对方退出了！我从List里面去掉了！");<br/>　　　　//e.printStackTrace();<br/>　　　　}<br/>　　　　}<br/>　　　　public void run() {<br/>　　　　try {<br/>　　　　while(bConnected) {<br/>　　　　String str = dis.readUTF();<br/>　　　　System.out.println(str);<br/>　　　　for(int i=0; i&lt;clients.size(); i++) {<br/>　　　　Client c = clients.get(i);<br/>　　　　c.send(str);<br/>　　　　//System.out.println(" a string send !");<br/>　　　　}<br/><br/>　　　　<br/>　　　　}<br/>　　　　} catch (EOFException e) {<br/>　　　　System.out.println("Client closed!");<br/>　　　　} catch (IOException e) {<br/>　　　　e.printStackTrace();<br/>　　　　} finally {<br/>　　　　try {<br/>　　　　if(dis != null) dis.close();<br/>　　　　if(dos != null) dos.close();<br/>　　　　if(s != null) {<br/>　　　　s.close();<br/>　　　　//s = null;<br/>　　　　}<br/>　　　　} catch (IOException e1) {<br/>　　　　e1.printStackTrace();<br/>　　　　}<br/>　　　　}<br/>　　　　}<br/>　　　　}<br/>　　　　}<br/>　　　　//ChatClient.java文件<br/>　　　　import java.awt.*;<br/>　　　　import java.awt.event.*;<br/>　　　　import java.io.*;<br/>　　　　import java.net.*;<br/>　　　　public class ChatClient extends Frame {<br/>　　　　Socket s = null;<br/>　　　　DataOutputStream dos = null;<br/>　　　　DataInputStream dis = null;<br/>　　　　private boolean bConnected = false;<br/>　　　　TextField tfTxt = new TextField();<br/>　　　　TextArea taContent = new TextArea();<br/>　　　　Thread tRecv = new Thread(new RecvThread());<br/>　　　　public static void main(String[] args) {<br/>　　　　new ChatClient().launchFrame();<br/>　　　　}<br/>　　public void launchFrame() {<br/>　　　　setLocation(400, 300);<br/>　　　　this.setSize(300, 300);<br/>　　　　add(tfTxt, BorderLayout.SOUTH);<br/>　　　　add(taContent, BorderLayout.NORTH);<br/>　　　　pack();<br/>　　　　this.addWindowListener(new WindowAdapter() {<br/>　　　　@Override<br/>　　　　public void windowClosing(WindowEvent arg0) {<br/>　　　　disconnect();<br/>　　　　System.exit(0);<br/>　　　　}<br/>　　　　});<br/>　　　　tfTxt.addActionListener(new TFListener());<br/>　　　　setVisible(true);<br/>　　　　connect();<br/>　　　　tRecv.start();<br/>　　　　}<br/>　　　　public void connect() {<br/>　　　　try {<br/>　　　　s = new Socket("127.0.0.1", 8888);<br/>　　　　dos = new DataOutputStream(s.getOutputStream());<br/>　　　　dis = new DataInputStream(s.getInputStream());<br/>　　　　System.out.println("connected!");<br/>　　　　bConnected = true;<br/>　　　　} catch (UnknownHostException e) {<br/>　　　　e.printStackTrace();<br/>　　　　} catch (IOException e) {<br/>　　　　e.printStackTrace();<br/>　　　　}<br/>　　　　}<br/>　　　　public void disconnect() {<br/>　　　　try {<br/>　　　　dos.close();<br/>　　　　dis.close();<br/>　　　　s.close();<br/>　　　　} catch (IOException e) {<br/>　　　　e.printStackTrace();<br/>　　　　}<br/><br/>　　　　}<br/>　　private class TFListener implements ActionListener {<br/>　　　　public void actionPerformed(ActionEvent e) {<br/>　　　　String str = tfTxt.getText().trim();<br/>　　　　//taContent.setText(str);<br/>　　　　tfTxt.setText("");<br/>　　　　try {<br/>　　　　//System.out.println(s);<br/>　　　　dos.writeUTF(str);<br/>　　　　dos.flush();<br/>　　　　//dos.close();<br/>　　　　} catch (IOException e1) {<br/>　　　　e1.printStackTrace();<br/>　　　　}<br/>　　　　}<br/>　　　　}<br/>　　　　private class RecvThread implements Runnable {<br/>　　　　public void run() {<br/>　　　　try {<br/>　　　　while(bConnected) {<br/>　　　　String str = dis.readUTF();<br/>　　　　//System.out.println(str);<br/>　　　　taContent.setText(taContent.getText() + str + '\n');<br/>　　　　}<br/>　　　　} catch (SocketException e) {<br/>　　　　System.out.println("退出了，bye!");<br/>　　　　} catch (EOFException e) {<br/>　　　　System.out.println("推出了，bye - bye!");<br/>　　　　} catch (IOException e) {<br/>　　　　e.printStackTrace();<br/>　　　　}<br/>　　　　}<br/>　　　　}<br/>　　　　}					]]></summary>
	  <link rel="alternate" type="text/html" href="http://www.zhangyongjun.com/blog/default.asp?id=4926" /> 
	  <id>http://www.zhangyongjun.com/blog/default.asp?id=4926</id> 
  </entry>	
		
</feed>