关于作者

姓名:

性别:男

出生日期:--

地区:上海

联系电话:

QQ:--

婚否:未婚
用户名:Birdy
笔名:Steel.Yin
地区: 上海
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



好友博客

访问统计:
文章个数:105
评论个数:34
留言条数:0




Powered by BlogDriver 2.1

随堂笔记

 

每一天我的周围都在发生一些事情,新知心情,个种滋味尽在心头,为了不让这些生活的点滴随时间流逝而淡忘,愿能通过键盘记录我的生活、我的成长

文章

如何利用门户网页提高访问量
zz http://qq45460.blog.hexun.com/6237837_d.html

现在,在一些网管中,流传着这样一个神话,只要将网站提交到数百个搜索引擎,访
    问量就会大增。结果真是这样吗?
      请看一组统计数据,95%以上的人通过搜索结果中前六个链接,查看他们寻找的内容;
    排名在前10位的站点,比11到30位的站点,得到的访问量多78%;前30名站点得到的访问
    量,占整个搜索结果的90%以上;排在30位以后的站点,几乎无人光顾。1997年12月,
    Yahoo一个月内处理了5500万人次检索,一个拥有一两个重要关键字较好排名的网站,每
    天据此可产生几千甚至几十万的访问量,而排在后面的网站,却大打折扣。
      因此,你的目标,不仅仅是成功注册,还要取得好的排名。那么,怎样才能获得靠前
    的排名呢?
      使用门户网页,是比较可行的方法,它将一个网页(网站)的内容,分散、摘编到多
    个网页上,并针对不同搜索引擎的排序规则,进行专门设计,当然,最重要的是,将它们
    分别提交到各搜索引擎。只要你不违反前述规则,多数搜索引擎还是乐于接受的,因为它
    们认为,只要网页中没有虚假的关键字,这甚至更有利于人们检索网上资源。
      但是制作门户网页,并不是件很轻松的事情,它需要大量的时间和精力。原因之一,
    要摸索各个搜索引擎的排序算法,这可不是一蹴而就的!原因之二,需要制作大量门户
    网页。对于每个希望取得好的排名的关键字,都要单独制作一个门户网页,而要取得最好
    效果,一般应选择10到50个与网页主题密切相关的关键字。另外,在一个搜索引擎上排
    名很好的网页,在另一个搜索引擎上,可能排在后面,所以,同一个关键字,还要针对
    各个搜索引擎,设计不同的门户网页。例如,有个关键字“free”,希望它在AltaVista、
    HotBot、Lycos、Infoseek和Excite这五个顶级搜索引擎中(Yahoo除外,它不接受门户
    网页)取得好的排名,那么,就必须针对每个搜索引擎,制作五个有关“free”的门户
    网页。如果要注册的搜索引擎更多,加之,有几十个关键字,工作量就可想而知了。但
    是,只要能让我们辛辛苦苦建造的网站名扬天下,吃这点苦也算不了什么。
      至于具体如何设计制作门户网页,涉及的内容较多,有人甚至还专门写了书,限于
    篇幅,这里无法详述。只能概括介绍一般要素及一种简易方法:
      首先,你应该明白前面已经提到的,搜索引擎不同,其排序的标准也不一样,各自的
    算法也不同,而且一般搜索网站对此都是秘而不宣的。但是,它们大多数会考虑以下因
    素,来决定网页的排序:
      关键字的出现位置。是在网页标题上、META标记中,还是网页正文中?
      关键字的出现频率。所搜索的关键字的出现次数。注意!那种简单重复关键字的作法
    是无效的,因为语法结构是否正确、关键字所占比重是否合适,也是一个控制标准。
      关键字的匹配程度。是完全相同,还是部分相同?尤其是当搜索对象为短语的时候。
      那么,以哪些地方出现的关键字为准呢?主要有以下部位:
      标题标记:< TITLE>文本< /TITLE>
      META标记:< META NAME="Description" CONTENT="网页简述">
    < META NAME="Keywords" CONTENT="关键字">
      大标题标记:< H1>文本< /H1>等
      链接标记:< A HREF="http://yourcompany.com/page.htm">文本< /A>
      网页正文:< BODY>文本< /BODY>
      ALT标记: < IMG SRC="1.gif" BORDER=0 ALT="关键字">
      注释标记:< !--文本-->
      输入标记:< INPUT TYPE="HIDDEN" NAME="HIDDEN" VALUE="关键字">
      网址: http://www.关键字.com/关键字.htm
      至于以上各处关键字,在某个搜索引擎排序算法中的重要程度,你可以通过以下方法
    大致知道。在搜索引擎上查询关键字,查看搜索结果,找出排在第一位的网页(无重定
    向设计的),观察其源代码。然后,参照这个网页,设计自己的门户网页。具体作法,
    根据参照网页,在关键字出现的各个部位适量添加关键字,使它们出现得总是比原网页
    稍微多一点点,但切不可贪多,以免被视为作弊。另外,请注意,大多数搜索引擎似乎
    更偏爱短小的网页,因此,还要使你的门户网页比当前的参考页更短小一点。
      总之,就目前来说,门户网页肯定是网站宣传的有力工具之一。但从技术和道德上说,
    它们也是有争议的,如果滥用,也可能弊大于利。


- 作者: Steel.Yin 2006年11月1日, 星期三 23:40  回复(0) |  引用(0) 加入博采

网页编辑中双引号的输出

今天想输出双引号,搜了搜发现有几种方法:

对于JavaScript可以使用转义字符'\',如  \" 即可

对于VBScript使用连续两个双引号,如 ""

- 作者: Steel.Yin 2006年07月10日, 星期一 03:01  回复(0) |  引用(0) 加入博采

妹子的blog

今天在妹子的blog上看了她的丽江之行,看她玩的好开心,让我这个喜欢旅游的人又蠢蠢欲动了:)骑马被她说成骑驴看着我都笑晕了,给个链接 http://yvonne-deng.spaces.msn.com

- 作者: Steel.Yin 2006年07月6日, 星期四 00:13  回复(0) |  引用(0) 加入博采

显示器分辨率变而层位置不变
层的定位 一般我们都是在800*600分辨率下做页面,如果页面设置了居中对齐方式,那在1024*768等不同分辨率下,层的位置就会有很大偏差,这里提供一个简单的方法 在里加如下script function pageinit() { var xxx=(window.screen.width-800)/2+565; Layer1.style.left=xxx; } :) 

<script language=javascript> function pageinit() { var xxx=(window.screen.width-800)/2+565; Layer1.style.left=xxx; } </script>

这段代码可以放在任何地方。其中565这个值,是在800*600状态的层的实际位置。

xxx是变量名,可以随便取。
<layer>中的其他属性不变,将left及其值去掉就行了。
运行pageinit()可以使用的方法:页面下载时<body onload=pageinit()> 或者直接在连接上做<a href="#" onmouseover=pageinit()> 其他任何事件都行。

- 作者: Steel.Yin 2006年06月26日, 星期一 01:46  回复(0) |  引用(0) 加入博采

ASP操作Excel技术总结

http://www.blueidea.com/tech/program/2006/3547.asp

一、环境配置
二、ASP对Excel的基本操作
三、ASP操作Excel生成数据表
四、ASP操作Excel生成Chart图
五、服务器端Excel文件浏览、下载、删除方案
六、附录正文

一、环境配置

服务器端的环境配置从参考资料上看,微软系列的配置应该都行,即:
1.Win9x+PWS+Office
2.Win2000Professional+PWS+Office
3.Win2000Server+IIS+Office
目前笔者测试成功的环境是后二者。Office的版本没有特殊要求,考虑到客户机配置的不确定性和下兼容特性,建议服务器端Office版本不要太高,以防止客户机下载后无法正确显示。

服务器端环境配置还有两个偶然的发现是:

1.笔者开发机器上原来装有金山的WPS2002,结果Excel对象创建始终出现问题,卸载WPS2002后,错误消失。

2.笔者开发ASP代码喜欢用FrontPage,结果发现如果FrontPage打开(服务器端),对象创建出现不稳定现象,时而成功时而不成功。扩展考察后发现,Office系列的软件如果在服务器端运行,则Excel对象的创建很难成功。
服务器端还必须要设置的一点是COM组件的操作权限。在命令行键入“DCOMCNFG”,则进入COM组件配置界面,选择MicrosoftExcel后点击属性按钮,将三个单选项一律选择自定义,编辑中将Everyone加入所有权限。保存完毕后重新启动服务器。
客户端的环境配置没发现什么特别讲究的地方,只要装有Office和IE即可,版本通用的好象都可以。

二、ASP对Excel的基本操作

1、建立Excel对象
setobjExcelApp=CreateObject("Excel.Application")
objExcelApp.DisplayAlerts=false不显示警告
objExcelApp.Application.Visible=false不显示界面

2、新建Excel文件
objExcelApp.WorkBooks.add
setobjExcelBook=objExcelApp.ActiveWorkBook
setobjExcelSheets=objExcelBook.Worksheets
setobjExcelSheet=objExcelBook.Sheets(1)

3、读取已有Excel文件
strAddr=Server.MapPath(".")
objExcelApp.WorkBooks.Open(strAddr&"\Templet\Table.xls")
setobjExcelBook=objExcelApp.ActiveWorkBook
setobjExcelSheets=objExcelBook.Worksheets
setobjExcelSheet=objExcelBook.Sheets(1)

4、另存Excel文件
objExcelBook.SaveAsstrAddr&"\Temp\Table.xls"

5、保存Excel文件
objExcelBook.Save(笔者测试时保存成功,页面报错。)

6、退出Excel操作
objExcelApp.Quit一定要退出
setobjExcelApp=Nothing

三、ASP操作Excel生成数据表

1、在一个范围内插入数据
objExcelSheet.Range("B3:k3").Value=Array("67","87","5","9","7","45","45","54","54","10")
2、在一个单元格内插入数据
objExcelSheet.Cells(3,1).Value="InternetExplorer"
3、选中一个范围
4、单元格左边画粗线条
5、单元格右边画粗线条
6、单元格上边画粗线条
7、单元格下边画粗线条
8、单元格设定背景色
9、合并单元格
10、插入行
11、插入列

四、ASP操作Excel生成Chart图

1、创建Chart图
objExcelApp.Charts.Add
2、设定Chart图种类
objExcelApp.ActiveChart.ChartType=97
注:二维折线图,4;二维饼图,5;二维柱形图,51
3、设定Chart图标题
objExcelApp.ActiveChart.HasTitle=True
objExcelApp.ActiveChart.ChartTitle.Text="AtestChart"
4、通过表格数据设定图形
objExcelApp.ActiveChart.SetSourceDataobjExcelSheet.Range("A1:k5"),1
5、直接设定图形数据(推荐)
objExcelApp.ActiveChart.SeriesCollection.NewSeries
objExcelApp.ActiveChart.SeriesCollection(1).Name="=""333"""
objExcelApp.ActiveChart.SeriesCollection(1).Values="={1,4,5,6,2}"
6、绑定Chart图
objExcelApp.ActiveChart.Location1
7、显示数据表
objExcelApp.ActiveChart.HasDataTable=True
8、显示图例
objExcelApp.ActiveChart.DataTable.ShowLegendKey=True

五、服务器端Excel文件浏览、下载、删除方案

浏览的解决方法很多,“Location.href=”,“Navigate”,“Response.Redirect”都可以实现,建议用客户端的方法,原因是给服务器更多的时间生成Excel文件。
下载的实现要麻烦一些。用网上现成的服务器端下载组件或自己定制开发一个组件是比较好的方案。另外一种方法是在客户端操作Excel组件,由客户端操作服务器端Excel文件另存至客户端。这种方法要求客户端开放不安全ActiveX控件的操作权限,考虑到通知每个客户将服务器设置为可信站点的麻烦程度建议还是用第一个方法比较省事。

删除方案由三部分组成:

A:同一用户生成的Excel文件用同一个文件名,文件名可用用户ID号或SessionID号等可确信不重复字符串组成。这样新文件生成时自动覆盖上一文件。
B:在Global.asa文件中设置Session_onEnd事件激发时,删除这个用户的Excel暂存文件。
C:在Global.asa文件中设置Application_onStart事件激发时,删除暂存目录下的所有文件。
注:建议目录结构\Src代码目录\Templet模板目录\Temp暂存目录

六、附录

出错时Excel出现的死进程出现是一件很头疼的事情。在每个文件前加上“OnErrorResumeNext”将有助于改善这种情况,因为它会不管文件是否产生错误都坚持执行到“Application.Quit”,保证每次程序执行完不留下死进程。

补充两点:

1、其他Excel具体操作可以通过录制宏来解决。
2、服务器端打开SQL企业管理器也会产生问题。

<%
OnErrorResumeNextstrAddr=Server.MapPath(".")setobjExcelApp=CreateObject("Excel.Application")
objExcelApp.DisplayAlerts=false
objExcelApp.Application.Visible=false
objExcelApp.WorkBooks.Open(strAddr&"\Templet\Null.xls")
setobjExcelBook=objExcelApp.ActiveWorkBook
setobjExcelSheets=objExcelBook.Worksheets
setobjExcelSheet=objExcelBook.Sheets(1)objExcelSheet.Range("B2:k2").Value=Array("Week1","Week2","Week3","Week4","Week5","Week6","Week7",
"Week8","Week9","Week10")
objExcelSheet.Range("B3:k3").Value=Array("67","87","5","9","7","45","45","54","54","10")
objExcelSheet.Range("B4:k4").Value=Array("10","10","8","27","33","37","50","54","10","10")
objExcelSheet.Range("B5:k5").Value=Array("23","3","86","64","60","18","5","1","36","80")
objExcelSheet.Cells(3,1).Value="InternetExplorer"
objExcelSheet.Cells(4,1).Value="Netscape"
objExcelSheet.Cells(5,1).Value="Other"objExcelSheet.Range("b2:k5").Select

objExcelApp.Charts.Add
objExcelApp.ActiveChart.ChartType=97
objExcelApp.ActiveChart.BarShape=3
objExcelApp.ActiveChart.HasTitle=True
objExcelApp.ActiveChart.ChartTitle.Text=
"Visitorslogforeachweekshowninbrowserspercentage"
objExcelApp.ActiveChart.SetSourceDataobjExcelSheet.Range("A1:k5"),1
objExcelApp.ActiveChart.Location1
'objExcelApp.ActiveChart.HasDataTable=True
'objExcelApp.ActiveChart.DataTable.ShowLegendKey=TrueobjExcelBook.
SaveAsstrAddr&"\Temp\Excel.xls"objExcelApp.Quit
setobjExcelApp=Nothing
%>
<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN">
<HTML>
<HEAD>
<TITLE>NewDocument</TITLE>
<METANAME="Generator"CONTENT="MicrosoftFrontPage5.0">
<METANAME="Author"CONTENT="">
<METANAME="Keywords"CONTENT="">
<METANAME="Description"CONTENT="">
</HEAD>
<BODY>
</BODY>
</HTML>

- 作者: Birdy 2006年06月22日, 星期四 00:05  回复(0) |  引用(0) 加入博采

.NET架构的核心开发技术
 不可否认,应用软件的开发正在经历一次巨变——将最终增强开发人员的生产力并开启一道通向全新概念的应用程序的大门。

  新型的开发模式正逐渐被推广,将分发软件演变成一种服务还有待于所有开发人员的共同努力,而互联网却将彻底改变应用程序的开发模式和配置方式。

  传统上,软件开发人员通过集成本地系统服务的方式开发应用程序。这种模型使开发人员有权使用一整套丰富的开发资源,精确控制应用程序的性能。

   如今,开发人员在很大程度上已挣脱了这种模式的束缚,致力于构建具有复杂结构的n层系统,这种系统能将网络中各处的众多的应用程序进行集成,并大大提升 应用程序的价值。这样,开发人员便可集中精力挖掘软件独特的商业价值,而不必日夜为如何构建基本结构伤脑筋了。令人欣喜的局面将应运而生:软件投放市场的 时间大大缩短、开发人员的编程效率明显提高,最为根本的是开发出质量上乘的软件。

  我们正在进入计算机发展的下一个阶段——基于 Internet的阶段,特别是基于Internet核心技术——XML扩充标记语言。尽管多层应用程序开发将焦点集中在建造大型企业级应用程序上,但现 在XML使得能够创建可用于任何人、任何场所的大型应用程序。它扩大了应用程序的使用范围。这样,软件就不是只能从CD上安装的某种东西,而是一种服务 ——就像呼叫服务或者计费电视一样,可以通过通信媒体来预订。

  这一切,是通过将紧密联接的、高效的n层计算技术与面向消息的、松散 联接的Web概念相结合来实现的。我们将这种计算风格称为Web Service(Web服务),它的出现标志着人类已经迈入应用程序开发技术的新纪元。Web服务是一种应用程序,它可以使用标准的互联网协议,像超文本 传输协议(HTTP)和XML,将功能纲领性地体现在互联网和企业内部网上。

  我们也可将Web服务视作Web上的组件编程。

   从理论上讲,开发人员通过调用Web应用编程接口(API),将Web服务集成进他们的应用程序,就像调用本地服务一样。两者区别在于前者能够通过 Internet发送到某个远程系统的服务上。例如,像微软护照(Microsoft Passport)这样的服务,可以给开发人员提供应用程序身份确认的功能。通过对护照服务编程,开发人员就可以利用护照服务的基础体系,实现维护用户数 据库,确信服务开启和运行以及正确地备份等等功能。

  ■松散联接

  跨越网络的分布应用程序逻辑的概念并不是一个新名词,但跨越Web的分布和集成应用程序逻辑的概念却是。

   此前,像微软的DCOM (Distributed Component Object Model )、Object Management Group公司的CORBA (Common Object Request Broker Architecture )以及Sun公司的RMI(Remote Method Invocation )这些分布式对象模型被称为分布应用程序逻辑。运用这些系统结构,虽然服务放在远程系统上,开发人员仍然可以像原来本机编程那样维护和丰富应用程序的功 能。

  但这种系统的问题是不能扩展到Internet。因为该体系的基础是服务器上的客户端和服务器的紧密联结。这意味着两者必须是 同质的基础体系,但也就常常意味着这种系统是非常脆弱的,如果有任何一端接口发生变化,另一端程序必然就会被中断。举个例子,如果服务器应用程序的接口改 变了,那么客户端也将会失效。

  开发中要求有一个紧密联接的系统这本身没有错,而且许多应用程序也一直就是建立在这些系统上的。但最 终,随着时间的流逝,这种模型是不会扩展的。因为众多公司企业要求相互沟通,这很难保证会有一个统一的系统,同样也很难保证,你的客户的服务器会有你所需 要的完全一致的系统,你甚至都不可能猜想到它所用的是什么操作系统、什么对象模型和什么编程语言。

  相反,Web服务的联接非常松 散。这就意味者你可以在联接的任何一端任意改变接口,而应用程序可以不受影响地照常工作。从技术上说,这主要是由于使用了拥有稳固性能的基于消息的异步技 术,如像HTTP、SMTP等Web标准协议。而且最重要的是,XML可以帮助实现其通用性。

  作为一个宏伟的计划,.NET的路还很长。今后的发展无论是崎岖坎坷还是一片光明,在对新技术和IT产业的推动上,微软都是功不可没的。

   消息系统将通信的基本单元打包进自描述的、运用于网络通信层的包(被称做消息)。消息系统和分布式对象系统的关键区别在于,发送者需要对接收者的系统了 解多少。使用分布式的对象系统,发送者需要帮助接收者考虑许多问题,比如应用程序将如何激活和卸载、调用的是什么接口等等。

  另一方面,消息系统在通讯层上达成协议。发送者只需考虑的是接收者能够知道信息正被发送。发送方不需要了解一旦消息被收到后将会如何处理,也不需要对发送方和接收方之间作任何考虑。

   在通讯层上达成协议的优势是显而易见的。例如,协议能够使接收方随时作修改而无须中断发送方,只要该协议始终明白是同一条消息。接收方不用中断任何当前 应用程序,可以自由升级和改进。更进一步说,就是发送方不用要求任何特殊的软件就可以和接收方交谈,只要他发送的是符合格式的信息,接收方就可以作出应 答。

  ■XML的通讯基础:SOAP

  建造跨越Web的 Web服务的工作和异步系统的关键是使用统一的数据说明格式,这就是XML。特别说明的是,Web服务器在三方面需要XML来实现:基础语言、服务说明以及服务发现。

   ● SOAP:系统在底层需要有统一语言,特别地,应用程序相互通讯需要建立一套规则来说明如何表示不同数据类型(如整数和数组),如何表示命令(如进行数据 处理)。同时,应用程序在需要时还可以扩充这种语言。简单对象存取协议SOAP(Simple Object Access Protocol),这是XML的一种实现,代表了一组如何表示和扩充数据和命令的规则集。

  ● WDSL(Web Services描述语言) :一旦应用程序有了如何表述数据和命令的基本规则,他们就需要如何描述可以接收的特定数据和命令。应用程序只是声明如何接收整数是不够的,他们必须用明确 的方法声明。如给你两个整数,把它们相乘。WDSL是一种XML语法,开发人员和开发工具可以用它来表示Web服务的功能。

  ● SOAP Discovery:最后需要一组规则来定位服务的描述——对于开发者和开发工具在什么地方可以发现一个Web服务。SOAP Discovery规范提供了一组规则让开发者和开发工具可以自动发现Web服务的描述。

  一旦这些准备好了,开发者可以方便地发现Web 服务,把它作为一个对象集成进他们的应用程序,并使应用程序和Web服务相互通讯。

  ■.NET框架:Web服务引擎

   很显然,许多基本结构都需实现上述进程对开发人员和用户的透明化。.NET框架(.NET Framework)提供此基本结构。从.NET框架角度看,所有组件都可以是Web服务,而Web服务也仅是一种组件。实际上,.NET框架提取出微软 组件对象模型(COM)的精华,将它们与松散联接计算的精华有机地结合在一起,生成了强大、高效的Web组件系统:简化程序员的“管道”操作,深入地集成 了安全性,引进了基于互联网的操作系统,极大地改善应用程序的可靠性和可扩展性。

  .NET框架由三个主要部分组成:通用语言运行库、一套层次结构的统一类库和一个被称为ASP+的高级ASP版本。

  有关.NET的许多东西让人印象深刻,尤其是微软充分传达出的对互联网作为未来主要技术平台的首肯,和在某些方面对公开的标准的欢迎。

  .NET的确牵动着每个人的猜测……

  1.通用语言运行库

   除了通用语言运行库的字面含义外,在开发阶段和运行过程中它还扮演着另一个角色。在组件运行时,运行库负责管理内存分配、启动和中止线程和进程、强化安 全系数,同时还调整任何该组件涉及到的其他组件的附件配置。在开发阶段,运行库的角色稍微有点变化:因为很多方面可以自动实现(例如内存管理等)。运行库 可以使开发过程变得非常简单,特别是同今天的COM编程相比更是如此。特别典型的是,像Reflection这样的特性可以极大地缩小开发人员将商业逻辑 转化成一个可重复使用的组件而不得不编写的代码数量。

  运行库对于编程语言来说并不是新鲜的东西。实际上每一种编程语言都已包含一个 运行库。Visual Basic开发系统有最明显的运行库(正规名字为VBRUN),Visual C++也有一个MSVCRT,此外,像Visual FoxPro、Jscript、SmallTalk、Perl、Python和Java等等都如此。.NET框架的关键角色就是它提供了一个跨所有编程语 言的统一环境。

  2.统一编程类

  .NET框架类为开发人员提供了一套可以使用的统一的面向对象、异步、层次结构 的可扩展类库。现在,C++的使用者使用Microsoft Foundation Classes,Java程序员使用Windows Foundation Classes,Visual Basic的用户使用Visual Basic APIs。微软用.NET框架统一了这些不同的框架。结果是,开发人员不用非去学多个框架来完成自己的工作。而且,通过创建一套跨编程语言的通用 API,.NET框架可以实现跨语言继承、纠错处理以及程序调试。实际上,从JScript 到C++的所有编程语言,对于.Net框架都是相互等同的,开发人员可以自由地选择他们想使用的任何语言。

  .NET是一种全新的平台,它将对现有的所有代码产生影响。盖茨说:“微软所有的产品都会被涉及。我们的整个战略是围绕这个平台展开的。”

  3.ASP+

   ASP+是使用 .NET框架提供的类库构建而成的,它提供了一个Web应用程序模型,该模型由一组控件和一个基本结构组成。有了它,Web应用程序的构建变得非常容易。 开发人员可以直接使用ASP+控件集,该控件集封装了公共的、用于超文本标识语言(HTML)用户界面的各种小组件(诸如文本框、下拉选单等等)。实际 上,这些控件运行在Web服务器上,它们将用户界面转换成HTML格式后再发送给浏览器。在服务器上,控件负责将面向对象的编程模型呈现给Web开发人 员,这种编程模型能提供面向对象的编程技术拥有的丰富功能。ASP+还提供一些基本结构服务(诸如会话状态管理和进程循环),这些服务进一步减少了开发人 员要编写的代码量,并使应用程序的可靠性得到了大幅度提高。ASP+还允许开发人员将软件作为一项服务进行传送。通过使用ASP+ Web服务功能,ASP+开发人员只需进行简单的业务逻辑编程,而由ASP+基本结构负责通过SOAP传送服务。

  尽管ASP+还未正式发行,但它已在改进应用程序功能方面创造出了令人难以置信的奇迹:在现有基于ASP的应用程序性能基础上,性能优化了三倍之多,更为激动人心的是生产效率再度攀升。

  ■.NET框架的核心部分

  .NET框架有几个要素值得一提。首先是它的安全系统和配置系统。这两个系统协同工作,有力地遏止了运行不安全代码的可能性,并大幅度减少了号称“DLL Hell”的对应用程序进行配置时所面临的挑战。

  安全系统是一个高度细化、基于事实的系统,它赋予开发人员和管理员多种代码处理权限(而不仅仅是“on”或“off”)。将来,还会根据代码本身的核心要素来决定如何实施上述权限。

   例如,当.NET框架应用程序被下载到某一系统中时,它会申请一组权限(诸如对临时目录的写入权限)。运行时将收集有关应用程序的事实信息(诸如:它是 从何处下载的、是否用了有效签名、甚至它访问系统的准确程度),并按管理策略决定是否允许应用程序运行。运行时甚至还可告之应用程序它无法授权申请的所有 权限,并允许应用程序自行决定是否继续运行。

  有这种安全系统作保障,许多应用程序配置问题便会迎刃而解。开发人员和管理员(最终是 用户)所面临的最大挑战之一是版本的管理问题。如果在您新装了某个应用程序之后,一切都陷于瘫痪状态,而在这之前系统一直运行得非常良好,那么最大的可能 是新安装的应用程序重写了一些共享库,并极有可能修正了现有应用程序正使用的程序错误。这种情况出现的频率很高,以致人们将它称为:“DLL Hell”。

  .NET框架拥有的几项高级功能可以彻底消除“DLL Hell”现象。首先,它有一个非常强大的内部命名系统,能够有效地防止两个库因互相重名而被错当为对方的情况发生。除此之外,它还提供一项被称作 “side by side”配置的新功能。如果前例中新安装的应用程序确实重写了共享库,现有应用程序可对该库进行修复。等现有应用程序再次启动时,它会检查所有的共享文 件。如果发现文件被更改,同时这些更改又是不兼容的,则它可以请求运行时提取一个它可以使用的版本。得益于强大的安全系统,运行时可以安全地执行该操作, 这样应用程序就完成了本身的修复工作。

  ■后记

  人们总是喜欢不厌其烦地发表诸如“互联网改变了一切”的陈词。同 样地,在谈论互联网给人类带来的影响时,总是情不自禁地使用广告式的夸张语,以表达对互联网的推崇。不过,互联网的确彻底改变了应用程序的开发模式和配置 方式。将分发软件演变成一种服务还有待人们的共同努力,XML是实现这个梦想的重要手段。.NET框架是微软开发人员战略的核心内容,它旨在帮助开发人员 轻松地构建、配置和运行Web服务。

  总之,.NET的最先受益者,将是我们的开发人员。.NET的路还很长,今后的发展无论是崎岖坎坷还是一片光明,在对新技术和IT产业的推动上,微软都是功不可没的

- 作者: Birdy 2006年06月21日, 星期三 18:05  回复(0) |  引用(0) 加入博采

VC++.NET开发环境整合技巧
http://www.myfaq.com.cn/A/2004-05-26/136642.html

  1. 主窗口内的每一个子窗口都是可以dock的,dock在边上的子窗口在右上角有两个按扭,一个是关闭,一个是图钉。当图钉按下时,子窗口就不会再自动缩回 到边上,而且可以通过拖动子窗口的标题栏把它拉出来。我建议将所有不需要的子窗口都关掉,再将dock到底部和左边的所有子窗体也关掉,需要的子窗体全部 放到右边,然后把图钉拔起来,要看的时候把鼠标移过去就可以看到了,滑动出来的时候不会挡住代码,给代码编辑留下最大的空间。

   2. 工具条也具有和子窗口类似的dock属性,要关掉工具条,可以把它拖出来,然后关闭。工具条和菜单的每一项都可以设置,方法是在工具条或菜单条上单击右 键,然后在弹出菜单里点自定义,这时你可以通过在工具条和菜单条上拖动,很方便的完成自定义的部局。你还可以选中某一项后按右键,来设置这一项的详细属 性。我建议关掉所有的工具条,因为一般常用的命令都有快捷键,不常用的就用菜单吧,这样可以省出来地方给代码编辑。

  3. 键盘的快捷键设置可以在工具菜单->选项->环境->键盘里设置。上面有一些预设的键盘映射方案,你可以选择其中一项,然后在下面加以修改后另存为自己的方案。我强烈推荐使用Visual C++6.0的键盘映射方案,很顺手哈!

   4. 在工具菜单->选项->环境->字体和颜色里可以设置代码编辑中各类标识符的字体和颜色。在这里你可以把字体调大一点,因为默认的9号 字太小了,看不清楚。我的设置是11号幼圆。对于字体颜色的详细设置,你可以使用颜色后面的自定义,来选择你喜欢的颜色,我还是很喜欢整编代码五颜六色的 样子!

  一、代码编辑部分

  1. 如果一段代码的缩进很乱,空格、TAB一大堆杂乱无章,那么选中这一段代码,在编辑菜单->高级中按格式化选定内容。这一段代码就被自动整理好了。 如果一段代码中空格和TAB交错使用,但格式似乎是整齐的,你可以到编辑菜单->高级->查看空白,查看代码中的空格和TAB。

   2. 在工具菜单->选项->文本编辑器->C/C++->常规中把启动单击URL定位清除掉,这一项在C/C++代码编辑中没什么 用,反而会引起一些误会。再把行号勾上,我认为这虽然占一些空间,但是非常方便。在文本编辑器->C/C++->制表符中把制表符大小和缩进 大小都调整为4,这样有助于编译整齐的代码。如果你打开了行号,建议在文本编辑器->常规中,把选定内容的边距关掉,因为这就有点多此一举了。

  3. 在工具菜单->选项->项目->VC++目录中设置工程文件的路径。一般设置包含文件和库文件就可以了。

  4. 在代码编译窗口的上面有两个下拉列表框,左边的是可见域,右边的是函数,你可以通过这两个下拉框在一个很大的源文件中实现准确的定位。用好这个功能可以极大的提高编程效率。

  5. 大纲显示是一个非常好的功能,只是可能很多人都不习惯。可以在编辑->大纲显示->停止大纲显示来关掉它。如果想不在启动时就启用大纲显示,则可以在工具菜单->选项-> C/C++->格式设置中把打开文件时进入大纲模式去掉。

   6. 选中一段代码后按tab可以增加它的缩进;按住Alt可以竖选一段代码;鼠标放在行号栏或代码左边距上(如果你启用了)会变成向反方向的指针,这时你可以 选中对应的一行;选中代码后可以拖动选中的代码到合适的位置;按住Ctrl再按左右方向键可以移动光标并跳过关键字;Ctrl+Home和Ctrl+ End分别是到达文件顶部和底部;接住Shift再按方向键可以选中光标略过的字符,可以和Ctrl一起使用;Ctrl+A可以选中全部代码;Ctrl+=和Ctrl+-可以返回到你刚刚查看的代码的位置;可以利用括号匹配功能来帮助写完整的代码,括号匹配时会加粗显示,这一点可以在工具菜单->选项->环境->字体和颜色里设置。

  7. 查找和替换功能非常强大,可以选择使用通配符和正则表达式。由于篇幅关系,关于通配符和正则表达式的说明请参阅MSDN,我在此就不多说了。在文件中查找或替换,可以方便的编辑查找范围。你可以使用预定的几个查找范围,包括整个解决方案、VC++包含目录等,你也可以点后面的按扭来编辑详细的查找范围。对于文本文件的查找,VC++带的查找工具,要比Windows的文件查找那个效率高太多了。

  8. 按下面的顺序包含头文件

#define CRTDBG_MAP_ALLOC
#include <stdlib.h>
#include <crtdbg.h>

  然后在程序开始的时候写上:

_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );

   这样在调式程序结束后,内存泄露就会转储到输出子窗口的调试模式中。

  三、编译部分:

  1. 如果一个很大的工程,需要包含大量的系统文件,那么你可以把这些包含的头文件全部写到一个StdAfx.h的文件里, 然后再建一个StdAfx.cpp,里面就一句代码,#include “StdAfx.h”,接着在解决方案管理器->你的工程上单击右键,然后按属性->配置属性->C/C++->预编译头,把创 建/使用预编译头设为:创建预编译头,下面两向会自动填写,如果没有,那就填上StdAfx.h。然后把你的工程完全重新生成一编,再进入刚才的选项,把 创建/使用预编译头设为:设用预编译头。好了,你的工程现在的编译速度应该超极快了。

  2. 如果你的程序需要引入特定的库,那么可以在需要引用的源文件里写上:#pragma comment( lib, “xxx.lib” ) 这样就不需要到配置属性->链接器->输入里去设置了,这样还可以提高你的代码的兼容性。

  3. 如果你在写DLL,而且这个DLL是被另一个工程编译出来的EXE所使用的,但是这两个工程又不在同一个文件夹里,所以你只好每次都把新编译好的DLL复制到EXE的目录下再调试,如果某次你忘了更新,这可能就会浪费你很多的时间和精力。其实你可以写一个BAT文件,用Dos命令copy,完成你需要的拷贝任务,然后把这个BAT文件放到DLL的目录下,再进入配置属性->生成事件->生成后事件->命令行中填上你要执行的BAT文件名,在编译结束后就会自动执行拷贝任务了。

  4. 工具菜单->选项->环境->项目和解决方案中,可以把若生成完成时有错误,则显示任务列表窗口那一项勾上。这样在你编译结束,发现错误后,会自动弹出任务列表,然后你双击某一项任务,就会定位到出错的那一行代码上。

  四. 资源部分

  1. 编辑对话框时,选中一个控件,然后在属性子窗口中会列出它的所有的属性。按上面的闪电按钮,会列出它所有可用的事件,双击其中一个事件,就会跳转到相应的源文件中,这时你就可以为该控件的某一事件添加处理程序了。

  2. 在使用MFC编程时,属性子窗口会显示这个类可用的重写函数和事件处理程序,双击就可以编写代码。如果发现属性子窗口和代码不对应,可以在类视图中选择你需要编辑的类,或在代码编辑中单击右键按同步类视图。

  3. 一个图标文件其实是一个图标包,里面可以包含很多个大小、颜色均不一样的图标,在VC.net的图标编译器中也可以任意新建、删除、修改图标。在图像菜单中的新建图象类型、当前图标图像类型、删除图像类型可以很方便的完成此功能。

  4. 菜单编辑时,在菜单项的Caption属性中输入-,该菜单项会自动变成分隔符。

  五,调试部分

  1. 在调试菜单->窗口子菜单中,你可以打开这些都很有用的调试辅助窗口。下面讲述的窗口都可以在这里打开。

  2. 在代码编辑的最左边单击左键,会为这一行添加断点。右击这个断点可以修改这个断点的属性,比如设置这个经过这个断点多少回再停下,或着是一个条件判断语句为true时这个断点再停下等等。断点窗口可以对源文件中的断点进行更加详细的配置和管理。

  3. 自动窗口和局部变量里你可查看到几乎所有当前你需要查看的变量的值,并且在这里你可以修改这个变量的值。

  4. 寄存器窗口可以查看所有寄存器的状态。在这个窗口中右击,打开你需要查看的寄存器。

  5. 调用堆栈,这个在出错时非常有用。比如内存访问出错,然后停到了delete源文件中的一行,这时你就可以通过堆栈来向上查找看是哪一个真正的出错源语句。

  6. 命令窗口,在这里可以写VC++预定义命令,甚至可以编写部分C++代码。比如p = 5;这完全是可以的,具体可用的命令请参阅MSDN。

   7. 监视窗口,在这里输入你需要查看的变量名称,它的值就会马上显示在后面。如果是一个对象,点前面的+号,它的成员就会列到下面。如果有一个数组int a[6],你可以输入:a,6,这样你就可以查看这个数组中所有元素的值了。还可以转换格式,比如token,x。更详细复杂的功能,具体请参阅 MSDN。

  五. 关于VisualC++6.0模式键盘映射模式下的常用快捷键

  常规文本编辑部分略

  格式化选定内容:Ctrl+K,Ctrl+F
  向前定位:Ctrl+=
  向后定位:Ctrl+-
  查找:Ctrl+F
  在文件中查找:Ctrl+Shift+F
  替换Ctrl+H:
  在文件中替换:Ctrl+Shift+H
  转换为大写:Ctrl+Shift+U
  转换为小写:Ctrl+U
  注释选定内容:Ctrl+K,Ctrl+C
  取消注释:Ctrl+K,Ctrl+U
  打开/关闭断点:F9
  清除所有断点:Ctr+Shift+F9
  全部编译:F7
  单元编译:Ctrl+F7
  单步跟踪:F10
  进入函数:F11
  运行到光标处:Ctrl+F10
  跳出函数:Shift+F11
  运行调试:F5
  停止调试:Shift+F5
  重新启动调试:Ctrl+Shift+F5
  运行不调试:Ctrl+F5
  打开/关闭书签:Ctrl+K,Ctrl+K
  上一个书签:Ctrl+K,Ctrl+P
  下一个书签:Ctrl+K,Ctrl+N
  清除所有书签:Ctrl+K,Ctrl+L
  打开属性窗口:Alt+Enter
  上一篇文档:Ctrl+Tab
  下一篇文档:Ctrl+Shift+Tab
  打开项目:Ctrl+Shift+O
  打开文件:Ctrl+O
  保存:Ctrl+S
  全部保存:Ctrl+Shift+S
  新建文件:Ctrl+N
  全屏显示:Shift+Alt+Enter

- 作者: Birdy 2006年06月21日, 星期三 17:26  回复(0) |  引用(0) 加入博采

运行机制及MFC类结构
http://www.myfaq.com.cn/A/2004-11-24/136649.html

摘要


  本讲先来通过一个简单的MFC应用程序来介绍"类"的有关概念,然后分析其运行机制以及基本MFC类层次结构,最后使用项目模板所提供的MFC应用程序向导来创建一个单文档程序TextViewer。


  一个简单的MFC应用程序


  在现在的"面向对象"程序设 计中,我们经常会听说过"类"和"对象"的概念。那么什么是"类"呢?"类"的实质上是一种新的复杂数据类型。说它"新",是因为它不同于C语言中的 char、int、float等基本数据类型,说它"复杂",是因为它不仅可以包含各种基本类型的数据,而且还可以包含处理这些数据的函数。


  MFC使用"类"来编写Windows应用程序,例如下面的过程:


  (1) 单击"开始"页面中的"新建项目",或者打开"文件"菜单中的"新建",选择"项目"命令,都将弹出"新建项目"对话框。


  (2) 在左侧的"项目类型"窗格中,选中"Visual C++项目"。在右侧的"模板"窗格中,拖动窗格右侧的滚动条显示其他模板,然后选中"Win32 项目"。


  (3) 在"名称"文本框中,输入项目名称"Ex_1_SimpMFC",单击"确定"按钮,弹出"Win32 应用程序向导"对话框。


  (4) 单击左侧的"应用程序设置"。选中"应用程序类型"中的"Windows 应用程序",在"附加选项"中选中"空项目",结果如图1所示,单击"完成"按钮。


图1 Win32 应用程序设置


  (5) 在"解决方案资源管理器"中,右击项目名称Ex_1_SimpMFC,从弹出的快捷菜单中选择"添加",然后选择"添加新项",弹出"添加新项"对话框。


  (6) 在右侧的"模板"窗格中选中"C++文件",在"名称"文本框中输入SimpMFC,单击"打开"按钮。


  (7) 键入如图2所示的代码。



图2 SimpMFC.cpp文件内容


  (8) 在"解决方案资源管理器"标签中,右击顶层的项目名"Ex_1_SimpMFC",从弹出的快捷菜单中选择"属性"菜单项,弹出如图3所示的"Ex_1_SimpMFC 属性页"对话框。



图3 Ex_1_SimpMFC的属性页对话框


  (9) 单击"MFC的使用",然后单击右边的下拉按钮,从弹出的下拉选择列表选择"在共享DLL中使用MFC",单击"确定"按钮。


  (10) 打开"调试"菜单,选择"开始执行(不调试)",或按Ctrl + F5,运行程序,结果如图4所示。



图4 项目Ex_1_SimpMFC运行的结果






  运行机制及MFC类结构


  1.代码分析


  在图2中,包含文件afxwin.h是使用MFC类库的头文件。class是定义类的关键字,class的后面是用户定义的类名,即CSimpApp。需要说明和是:通常用大写的C字母开始的标识符作为类名,C用来表示类(Class),以与函数及其他数据类型相区别。


  类体中定义的函数或变量,都称为该类的"成员",其中变量称为"成员变量",函数称为"成员函数"。成员可被声明成public、private。对于public类成员来说,它们是公有的,能被类外面的程序访问;对于private类成员来说,它们是私有的,只能由类中的函数所使用,而不能被外面的程序所访问。


  在"public:"或"private:"后面定义的所有成员都是公有或私有的,直到下一个"public:"或"private:"出现为止。若 成员前面没有类似"public:"或"private:"的声明,则所定义的成员是private(私有),这是类的默认处理。关键字public和 private可以在类中出现多次,且前后的顺序没有关系。


  类名冒号后面的是用来定义类的继承,其格式如下:


class 派生类名 : 继承方式 基类名
{
派生类的成员
};


  其中,被继承的类称为基类(base class),在基类上建立的新类称为派生类(derived class)。继承方式有三种:public(公有)、private(私有)及protected(保护),若继承方式没有指定,则被指定为缺省的 public方式。继承方式决定了派生类的继承基类属性的使用权限,public继承方式能够使用基类的所有共有成员。


  从代码中可以看出,类CSimpApp是从应用程序类CWinApp派生而来。而类CMainFrame是从框架窗口类CFrameWnd派生而来。


  在面向对象的程序设计中,类有函数重载、运算符重载和虚函数等,这些称为类的多样性。


  所谓"函数重载",是指在类中或同一个作用域中,允许有多个同名的函数存在,但同名的各个函数的形参必须有区别:形参的个数不同,或者形参的个数相同,但参数类型有所不同。


  所谓"运算符重载",就是赋予已有的运算符多重含义。


  所谓"虚函数",它是指在函数名前面加上virtual关键字的成员函数,如成员函数InitInstance就是被声明成了虚函数。虚函数也是能使一个函数具有多种不同的版本,只不过虚函数的不同版本是在基类和派生类中进行定义的。这样系统就会根据相应的类对象来决定调用的是派生类CSimpApp的InitInstance()函数中的代码,还是基类InitInstance()函数中的代码。


  在CMainFrame类中,我们还看到了与该类名相同的成员函数CMainFrame(),这个函数称为该类的"构造函数"。每个类都有一个构造函数,如果我们没有指定,系统就会自动使用默认的构造函数。构造函数的最大特点是在对象建立时它会被自动执行,因此用于变量、对象的初始化代码一般放在构造函数中。在定义构造函数时,不能指定函数返回值的类型,也不能指定为void类型。


  在CMainFrame()构造函数中的Create函数是用来创建窗口,它的参数依次用来指定类名、窗口标题、窗口样式和窗口大小。其中,预定义样 式WS_OVERLAPPEDWINDOW用来创建一个常规窗口,CRect是一个矩形的数据类,用来确定窗口的大小和位置。


  与构造函数相对应的是析构函数。析构函数是另一种特殊的C++成员函数,它只是在类名称前面加上一个"~"符号。每一个类只有一个析构函数,没有任何参数,也不返回任何值。


  在类定义时,成员函数既可以在类中定义,也可以在类外定义。但在类外定义时,必须用作用域运算符"::"来通知编译系统该函数所属的类。例如,InitInstance函数就是在类CSimpApp外面定义的。


  代码中,m_pMainWnd是MFC中的一个全局指针变量。MessageBox()是窗口基类CWnd的一个成员函数,用来弹出一个对话框窗口,显示参数指定的短信息,这里是"你好,欢迎进入MFC世界!"。





  2.运行机制


  在程序中,当定义一个类对象时,它会自动调用相应的构造函数。所谓"类对象",就是用该类定义的"变量",这个"变量"又称为类的一个实例。例如,theApp就是类CSimpApp的一个对象。


  MFC正是利用类的这种"自动调用相应的构造函数"特性,使得WinMain()函数的调用变成了应用程序框架内部的调用,所以我们在代码中看不到每个Windows程序所必须有的WinMain()函数。


  当应用程序运行到"CSimpApp theApp;"时,系统就会先调用基类CWinApp构造函数,进行一系列的内部初始化操作,然后自动调用CSimpApp的虚函数InitInstance(),该函数会进一步调用相应的函数来完成主窗口的构造和显示工作。下面来看看上述程序中InitInstance的执行过程。


  首先执行的是:


m_pMainWnd = new CMainFrame;


  该语句用来创建从CFrameWnd类派生而来的用户框架窗口CMainFrame类对象,继而调用该类的构造函数,使得Create函数被调用,完成了窗口创建工作。


  然后执行后面两句:


m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow();


  用作窗口的显示和更新。接下来调用:


m_pMainWnd->MessageBox("你好,欢迎进入MFC世界!");


  最后返回TRUE,表示窗口创建成功。


  由于应用程序类CWinApp是用来调用WinMain以及实例的初始化,因此每一个MFC应用程序有且只能一个这样的应用程序类,且需要一个全局的对象实例,如上述程序中的theApp,当然也可换一个对象名。


  InitInstance()完成初始化工作之后,接下来就是调用基类CWinApp的成员函数Run(),执行应用程序的消息循环,即重复执行接收消息并转发消息的工作。当Run()检查到消息队列为空时,将调用基类CWinApp的成员函数OnIdle进行空闲时的后台处理工作。若消息队列为空且又没有后台工作要处理时,则应用程序一直处于等待状态,一直等到有消息为止。


  当程序结束后,调用基类CWinApp的成员函数ExitInstance(),完成终止应用程序的收尾工作。这就是MFC应用程序的运行机制。


- 作者: Birdy 2006年06月21日, 星期三 15:20  回复(0) |  引用(0) 加入博采

ActiveX Automation
 一、概述

   我们在编写程序,开发软件的过程中如果能利用已有的程序的功能,那么可以大大减轻开发过程中程序员的工作量,同时达到事半功倍的效果。例如在工程中,许 多软件需要文字处理功能,虽然MFC提供了一些方法,但是具体实现起来既费事,又有一定的困难,如果我们可以直接使用OFFICE提供的功能,岂不美哉! 要实现这一目的,只需要利用ActiveX Automation 技术就可以轻松实现。本文主要讲述了自动化的概念,并通过一个操作Word文档的例子来帮助读者理解VC编程中如何实现自动化。

  二、自动化

  1.自动化的概念

   在Windows程序开发中,自动化是基于COM/DCOM之上的技术:它可以使一个应用程序来操纵另外一个程序中的对象,使用该程序提供的丰富的功 能;或者是一个应用程序通过提供一些对象及对象的方法和属性来允许另外一个程序使用它提供的各种功能。其中,根据程序是受惠者还是施惠者这一原则,将提供 对象和对象属性方法的应用程序称为自动化服务器端;使用对象属性方法的应用程序叫作自动化的客户端。自动化服务器让其它程序告诉它做些什么,它揭示的函数 和数据称为方法(Methods)和属性(Properties)。例如Microsoft Office套件中的成员Word、Excel等都是自动化服务器。根据自动化的客户端和服务器端的不同位置,又可以将自动化分为两类:

  1)如果作为服务器端和客户端的两个不同的应用程序都在同一台计算机上,叫作本地自动化;

  2)如果作为服务器端和客户端的两个不同的应用程序是基于网络的,分别处于不同的计算机上,叫作远程自动化。

   需要读者注意的是,由于利用了COM技术,客户端无法直接获得服务器端的对象来实现对它的访问,它必须通过获取一个指向接口的指针来使用对象提供的功 能。这个接口称为IDispatch,它是一个简化的使用多种不同语言的特殊接口(包括象VB这样不能使用指针的语言)。这部分内容读者可以在下面的程序 实现过程中细细体味。

  说到自动化,不能不提一下ActiveX控件,它其实是在进程中装入的极小自动化服务器。这意味着它们的执行速 度极快,它们原来被称为OLE自定义控件,用来替代VB和VC中使用的16位的VBX控件。由于ActiveX控件通常被保存为.OCX文件,所以又称它 为OCX控件。因为控件是一个小型化的自动化服务器,它们需要在自动化客户端使用,我们又将这时的客户端应用程序称为容器应用程序。ActiveX控件除 了属性和方法外,还包含事件(events),当一些事情需要容器应用程序注意时,控件才会触发一个事件,如用户的单击等。

  2.自动化中的数据类型

   在实现自动化编程中,最重要的一个问题是程序员要明白在自动化的客户端和服务器端数据是如何传递的。如何提供一个统一安全的机制来实现数据传递呢?在 VC开发平台上,它提供了一个叫VARIANT的数据类型来解决这个问题。该数据类型有两部分组成,第一部分为数据的类型,第二部分才是具体的数据的数 值。在VARIANT数据类型的基础上,VC提供了ColeVariant类,它对VARIANT数据类型进行了封装,这意味着在所有使用VARIANT 的地方都可以使用ColeVariant类的对象。在操作日期和货币变量时,VC又提供了两个类:ColeCurrency和ColeDateTime, 具体的内容,读者可以参考MSDN。



  三、操作Word2000的例子

   本文的例子演示了如何操作Word2000实现自动化,这个例子主要是为了辅助解释说明Visual C++编程中怎样实现自动化,帮助读者对自动化的实现过程有一个感性的认识,所以为了简单起见,该程序的功能是仅仅选择一个Word2000的*.Doc 文档,并将它的内容都在该程序的"视"中显示出来。为了达到这个目的,就需要启动Word2000打开用户所选择的文件,进行全选和剪贴板操作,然后将数 据粘贴到"视"中。

  在这个例子的具体实现中,我们的应用程序为自动化的客户端,Word2000为自动化的服务器端。首先生成一个新 的单文档应用程序,给该项目起个名字为"kk",视的基类选择CEditView,由于Office中的许多操作是由VBA语言来实现的,所以我们在使用 自动化操作Word2000的过程中,为了清楚Word2000的工作过程,我们要对VBA有所了解,这些知识可以通过在Word中录制宏来实现。录制宏 的步骤如下:启动Word2000,选择工具菜单下的录制宏子菜单,为一个新的宏起个名字为Macro1,开始录制宏,这时候窗口出现一个浮动工具条,点 击上面的按钮可以停止或暂停宏的录制。下面是实现打开一个Word2000文档、全部选择文档内容并将数据存放到剪贴板上的操作的宏代码:

' Sub Macro1()
'' 宏在 02-5-1 由 LiuTao 录制
'
Documents.Open FileName:="基于Visual C.doc", ConfirmConversions:=False, _
ReadOnly:=False, AddToRecentFiles:=False, PasswordDocument:="", _
PasswordTemplate:="", Revert:=False, WritePasswordDocument:="", _
WritePasswordTemplate:="", Format:=wdOpenFormatAuto
Selection.WholeStory
Selection.Copy
End Sub

  查看宏代码可以点击Word2000中工具菜单下的Visual Basic 编辑器。从上面的代码中可以看出对Word2000的这几个操作用到了Documents、Selection这两个自动化服务器端显示出来的对象和它们的方法。
为 了操作Word2000,需要使用它的类型库,这可以在Msword9.olb文件中找到,这个文件通常情况下位于Microsoft Office的安装目录下面。利用Visual C++中的ClassWizard可以方便的向应用程序添加新的类型库,在程序中启动ClassWizard ,选择Add class…. \From a type library …\C:\OFFICE\msword 9.olb,在弹出的对话框中选择_Application,_Documents,Selection,这样就可以为客户端程序程序中使用到的每个 Word2000对象建立相应的C++类。这些类的定义和实现分别在msword9.h和msword9.cpp文件中给出。

  为了使我们生成的项目支持自动化,为此我们要在项目中的StdAfx.h的文件末尾添加上下面一行:#include "afxdisp.h";在应用程序的InitInstance函数的开始添加下面的调用:

if (CoInitialize(NULL)!=0)
{
AfxMessageBox("初始化COM支持库失败!");
exit(1);
}

   首先通过COleDispatchDriver的成员函数CreateDispatch()创建一个Word2000的Applicaion对象,然后 通过COleDispatchDriver的成员函数AttachDispatch()将Documents和Selection对象与 Application对象提供的IDispatch接口关联起来,在程序对上述对象使用完毕后,要使用COleDispatchDriver的成员函数 ReleaseDispatch()来释放对象和接口之间的连接。

  有了上面的准备工作,下面给出如何实现上述操作目标的具体代码,该程序在Windows Me环境下,Visual C++6.0开发平台上编译通过,运行正常。

void CKkView::OnMenuAutoDisplay()
{
// TODO: Add your command handler code here
static char BASED_CODE szFilter[]="Word Files(*doc)|*.DOC||";
CFileDialog fd(true,NULL,NULL,OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter,NULL);
CString strFilePath;//用来保存打开的文件名;
if(fd.DoModal()==IDOK)
strFilePath=fd.GetPathName();//获取要打开的Word文档的名字;
_Application m_App;//定义Word提供的应用程序对象;
Documents m_Docs;//定义Word提供的文档对象;
Selection m_Sel;//定义Word提供的选择对象;
m_Docs.ReleaseDispatch();
m_Sel.ReleaseDispatch();
m_App.m_bAutoRelease=true;
if(!m_App.CreateDispatch("Word.Application"))
{
AfxMessageBox("创建Word2000服务失败!");
exit(1);
}
//下面是定义VARIANT变量;
COleVariant varFilePath(strFilePath);
COleVariant varstrNull("");
COleVariant varZero((short)0);
COleVariant varTrue(short(1),VT_BOOL);
COleVariant varFalse(short(0),VT_BOOL);
m_Docs.AttachDispatch(m_App.GetDocuments());//将Documents类对象m_Docs和Idispatch接口关联起来;
m_Docs.Open(varFilePath,varFalse,varFalse,varFalse,
varstrNull,varstrNull,varFalse,varstrNull,
varstrNull,varTrue,varTrue,varTrue);
//打开Word文档;
m_Sel.AttachDispatch(m_App.GetSelection());//将Selection类对象m_Sel和Idispatch接口关联起来;
m_Sel.WholeStory ();//选择文档中的全部内容;
m_Sel.Copy();//将数据拷贝到剪贴板
this->GetEditCtrl( ).Paste ();//将数据粘贴到程序的"视"中;
m_Docs.ReleaseDispatch();//断开关联;
m_Sel.ReleaseDispatch();
}

  本文主要讲述了基于自动化技术来操作Word,实现自动化的客户端的实现思想,为读者起到抛砖引玉的作用,读者可以在此基础上,实现对Word、Excel、PowerPoint等服务器端进行更复杂的操作。



- 作者: Birdy 2006年06月21日, 星期三 10:10  回复(0) |  引用(0) 加入博采

Visual C++.NET 2003中的代码优化
概要:这篇文章介绍了Visual C++.NET 2003中的代码优化。另外,有些读者可能对VC.NET 2002的优化不太了解,所以我们会简短介绍一下全程优化(Whole Program Optimization)。最后我们用一些例子充分表现一下VC.NET的优化性能,并对其讨论。

  前言

  人们在使用一个新的编程工具时总会感到缺乏自信,本文试图让你对VC的代码优化有更直观的感觉,希望你能通过阅读本文从VC中"得到"更多的东西。

  Visual C++ .NET 2003

  VC.NET 2003不仅带来了两个新的优化选项,它还改进了VC.NET 2002中一些优化的性能。

  第一个新增选项是"/G7",它告诉编译器对Intel Pentium 4和AMD Athlon处理器进行优化。

   使用"/G7"选项编译的程序,当我们和VC.NET 2002生成的代码比较时发现,它通常能使典型的程序的运行速度提高5到10个百分点,如果使用了大量浮点代码甚至能提高10到15个百分点。而提高的优 化程度可能很高也可能较低,在一些使用最新CPU和"/G7"选项的测试中,甚至提高了20%的性能。

  使用"/G7"选项不代表生成 的代码只能运行在Intel Pentium 4和AMD Athlon处理器上。这些代码仍可以运行在老的CPU上,只是在性能表现上可能有"小小的惩罚"。另外,我们观察到一些程序使用"/G7"后在AMD Athlon上运行的比用Intel Pentium 4更慢。

  当没使用"/Gx"选项时,编译器会默认使用"/GB"选项,此时为 "blended"优化模式。在VC.NET 2002和VC.NET 2003中,"/GB"代表"/G6",即为Intel Pentium Pro, Pentium II, Pentium III处理器优化。

  这儿有一个例子,它展示了做与常整数乘法时使用Pentium 4和"/G7"的优化效果,下面是源代码:

int i;

// Do something that assigns a value to i.

return i*15;

  当使用"/G6"时,生成了目标代码:

mov eax, DWORD PTR _i$[esp-4]
imul eax, 15

  当使用"/G7"时,生成了更快(可惜更长)的代码,它没用imul(乘)指令,在Pentium 4上执行只需要14个周期。目标代码如下:

mov ecx, DWORD PTR _i$[esp-4]
mov eax, ecx
shl eax, 4
sub eax, ecx

   第二个优化选项是"/arch:[argument]",用它可对SSE或SSE2优化,生成使用Streaming SIMD Extensions (SSE) 和 Streaming SIMD Extensions 2 (SSE2) 指令集的程序。当使用"/arch:SSE"选项时,目标代码只能运行在支持SSE指令(如:CMOV, FCOMI, FCOMIP, FUCOMI, FUCOMIP)的CPU上。当使用"/arch:SSE2"选项时,目标代码只能运行在支持SSE2指令集的CPU上。

  相比于"/G7",使用了SSE或SSE2优化的程序,一般能减少2-3%的运行时间,个别测试中甚至能减少5%的运行时间。

  使用"/arch:SSE"可得到以下效果:

  1、在使用单精度浮点数时,使用SSE指令对其处理。

  2、使用CMOV指令,它最早被Pentium Pro支持。

  3、使用FCOMI, FCOMIP, FUCOMI, FUCOMIP指令,它们也是最早被Pentium Pro支持的。

  使用"/arch:SSE2"的话,可以得到所有"/arch:SSE"选项的效果,另外还有以下几个效果:

  1、在使用双精度浮点数时,使用SSE2指令对其处理。

  2、使SSE2指令集做64位切换。(原文:Making use of SSE2 instructions for 64-bit shifts)

  还有其它的好处,在同时使用"/arch:SSE"或"/arch:SSE2” 和 "/GL"(全程优化)选项选项时,编译器会对浮点参数和浮点返回值做函数调用规则优化。

  上面说的几点优化特性已经包括于VC.NET 2003里了。另外还有一点就是能消除"死参数"--从没被用过的参数。比如:

int
f1(int i, int j, int k)
{
return i + k;
}

int
main()
{
int n = a+b+c+d;
m = f1(3, n, 4);
return 0;
}

  在函数f1()中,第二个参数从没被使用过。当我们用"/GL"(全程优化)选项时,编译器将产生如下目标代码来调用f1():

mov eax, 4
mov ecx, 3
call ?f1@@YAHHHH@Z
mov DWORD PTR ?m@@3HA, eax

  在这个例子里,变量"n"从没被运算,只有两个参数被f1()使用,所以只传递那两个参数(并且它们是从寄存器传过去的,这比使用栈传更快)。另外,编译这个例子时要禁止内联(inlining),否则函数f1()就不存在了,而直接给m赋予值7。



  Visual C++ .NET 2002

   VC.NET 2002引入了全程优化(Whole Program Optimization,缩写为WPO)的概念,"/GL"选项代表使用全程优化。全程优化意味着:编译器在.obj文件中存放的是代码的中间表达而不 是目标代码,在连接时连接器对其优化处理并生成真正的目标代码。

  全程优化的一个主要好处在于我们可以跨越源文件进行函数内联,这将大大提高程序的性能。还有一个好处在于编译器可以跟踪内存和寄存器的使用,以便优化使函数调用的开销更小。

  下面的代表展示了全程优化的表现:

// File 1
extern void func (int *, int *);
int g, h;
int
main()
{
int i = 0;
int j = 1;
g = 5;
h = 6;
func(&I, &j);
g = g + i;
h = h + i;
return 0;
}

// File 2
extern int g;
extern int h;
void
func(int *pi, int *pj)
{
*pj = g;
h = *pi;
}

  当不使用"/GL"选项时,生成了如下代码:

sub esp, 8
lea eax, DWORD PTR _j$[esp+8]
push eax
lea ecx, DWORD PTR _i$[esp+12]
push ecx
mov DWORD PTR _i$[esp+16], 0
mov DWORD PTR _j$[esp+16], 1
mov DWORD PTR ?g@@3HA, 5
mov DWORD PTR ?h@@3HA, 6
call ?func@@YAXPAH0@Z
mov eax, DWORD PTR _i$[esp+16]
mov edx, DWORD PTR ?g@@3HA
mov ecx, DWORD PTR ?h@@3HA
add edx, eax
add ecx, eax
mov DWORD PTR ?g@@3HA, edx
mov DWORD PTR ?h@@3HA, ecx
xor eax, eax
add esp, 16
ret 0

  当使用了"/GL"时,你会看到下面的代码,现在的代码短多了。注意编译这个例子时同样要注意关掉内联优化。

sub esp, 8
lea ecx, DWORD PTR _j$[esp+8]
lea edx, DWORD PTR _i$[esp+8]
mov DWORD PTR _i$[esp+8], 0
mov DWORD PTR ?g@@3HA, 5
mov DWORD PTR ?h@@3HA, 6
call ?func@@YAXPAH0@Z
mov DWORD PTR ?g@@3HA, 5
xor eax, eax
add esp, 8
ret 0

  表现优化的最好例子

  VC编译器包括两个主要的优化参数,"/O1"和"/O2"。"/O1"代表最小尺寸,选了它编译器认为用了以下选项。

  1./Og 全局优化,比如经常用到的变量使用寄存器保存,或者循环内的计算优化

  2./Os 程序(exe或dll)尺寸优化优先于代码速度优化

  3./Oy 使用帧指针,以提高函数调用速度

  4./Ob2 编译器“觉得”应该使用内联的函数,都使用内联

  5./GF 使用只读字符串池

  6./Gy 告诉编译器将各个函数按打包格式编译

  "/O2"选项代表最快速度,它基本上与"/O1"相同,只是用"/Ot"(更快的代码)代替了"/Os"。另外还有"/Oi"代表了展开内联函数。

  一般来说,对小程序使用最快优化,对大程序使用最小尺寸优化,这是因为尺寸大的程序通常能导致加载缓慢,CACHE命中率低,系统频繁切换分布内存等问题。使用最小尺寸优化,编译不再展开循环,也不会采用更长的代码。

  在选择了主要优化选项后,用profile去寻找"热区"是一个好办法,这样你可以对程序不同部分做最适当的优化。比如如果你用最小尺寸优化后,用profile发现有几个函数执行的很频繁,那你就可以把那几个函数按最快速度优化。


  VC编译器可以对特定函数进行优化选项!

  比如,如果你发现fiddle()函数被调用的频率很高,那你就可以让编译器只对这个函数进行最快速度优化,这样:

#pragma optimize("t", on)
int fiddle(S *p)
{
…;
}
#pragma optimize("", on)

  除了"/O1"和"/O2"以外,还有"/Ox"选项,它很与"/O2"效果相同,而"/Ox"与"/Os"组合则与"/O1"效果相同。我们推荐使用"/O1"和"/O2",而不是用"/Ox"。

  至此,我们讨论了"/G7","/arch"和"/GL"优化选项。

  除了上面介绍的,VC还提供了两个:

  1./GA 优化静态线程局部存储。(不要用于DLL project,用了也没效果)

  2./Gr 使用__fastcall作默认调用规则,这代表头两个参数会用寄存器传送(如果参数能装进寄存器)。

  另外的一个选项是"/opt:ref",用它可以通知连接器,在连接时去掉没被调用的函数和没被使用的数据。用"/opt:icf"选项能合并相同函数(比如你的程序可能通过模板展开了好几遍),这时优化也能减小程序的尺寸。

  Visual C++ .NET中的优化改进

  这儿有3个重要的优化选项,你可以把它们用在VC.NET 2003的项目中。虽然VC.NET 2002也提供了这些选项,但VC.NET 2003对它们做了性能上的改进。

  下表简要的描述了它们,如果你想了解更详细的内容,请查阅VC所带的文档。

选项效果
/RTC1使用无优化的Debug模式,编译器插入动态检测代码以帮助你发现程序中的错误。比如你没有初始化的内存,或者你把__stdcall和__cdecl弄混了。
/GS加入检测静态缓冲区(栈)溢出的代码,黑客就不能覆盖函数返回的地址以执行恶意代码。
注意:这不意味着你可以高枕无忧,你仍要留心编写安全的代码!
/Wp64 检测生成64位代码的问题,通过它你可以发现移植到64位环境下你的代码可能出现的问题。

  结论

  VC.NET 2003引入了两个新的优化选项,同时也改进了VC.NET 2002中的几个优化的性能,希望你能通过VC.NET 2003的优化选项来提高你程序的质量。

- 作者: Birdy 2006年06月21日, 星期三 09:56  回复(0) |  引用(0) 加入博采