<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-34947833</id><updated>2011-11-28T07:56:32.336+08:00</updated><category term='Vista'/><category term='搞笑'/><category term='Firefox'/><category term='Project Management'/><category term='无功'/><category term='java'/><category term='plugin'/><category term='ajax'/><category term='DB2'/><category term='Google toolbar'/><category term='drupal'/><category term='COM+'/><category term='电力'/><category term='Debug'/><category term='Firefox 3'/><category term='Interface'/><category term='Firefox 2'/><category term='delphi'/><title type='text'>Jason's Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>70</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-34947833.post-2663510872486974206</id><published>2008-11-02T21:42:00.001+08:00</published><updated>2008-11-02T21:44:33.008+08:00</updated><title type='text'>[转]5分钟看明白美国金融危机爆发的原因！</title><content type='html'>　 一。 杠杆。目前，许多投资银行为了赚取暴利，采用20－30倍杠杆操作，假设一个银行A自身资产为30亿，30倍杠杆就是900亿。也就是说，这个银行A以 30亿资产为抵押去借900亿的资金用于投资，假如投资盈利5％，那么A就获得45亿的盈利，相对于A自身资产而言，这是150％的暴利。反过来，假如投 资亏损5％，那么银行A赔光了自己的全部资产还欠15亿。&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;　　二。 CDS合同。由于杠杆操作高风险，所以按照正常的规定，银行不运行进行这样的冒险操作。所以就有人想出一个办法，把杠杆投资拿去做“保险”。这种保险就叫 CDS。比如，银行A为了逃避杠杆风险就找到了机构B。机构B可能是另一家银行，也可能是保险公司，诸如此类。A对B说，你帮我的贷款做违约保险怎么样， 我每年付你保险费5千万，连续10年，总共5亿，假如我的投资没有违约，那么这笔保险费你就白拿了，假如违约，你要为我赔偿。A想，如果不违约，我可以赚 45亿，这里面拿出5亿用来做保险，我还能净赚40亿。如果有违约，反正有保险来赔。所以对A而言这是一笔只赚不赔的生意。B是一个精明的人，没有立即答 应A的邀请，而是回去做了一个统计分析，发现违约的情况不到1％。如果做一百家的生意，总计可以拿到500亿的保险金，如果其中一家违约，赔偿额最多不过 50亿，即使两家违约，还能赚400亿。A,B双方都认为这笔买卖对自己有利，因此立即拍板成交，皆大欢喜。&lt;br /&gt;　　　　&lt;br /&gt;　　三。 CDS市场。B做了这笔保险生意之后，C在旁边眼红了。C就跑到B那边说，你把这100个CDS卖给我怎么样，每个合同给你2亿，总共200亿。B想，我 的400亿要10年才能拿到，现在一转手就有200亿，而且没有风险，何乐而不为，因此B和C马上就成交了。这样一来，CDS就像股票一样流到了金融市场 之上，可以交易和买卖。实际上C拿到这批CDS之后，并不想等上10年再收取200亿，而是把它挂牌出售，标价220亿；D看到这个产品，算了一 下，400亿减去220亿，还有180亿可赚，这是“原始股”，不算贵，立即买了下来。一转手，C赚了20亿。从此以后，这些CDS就在市场上反复的抄， 现在CDS的市场总值已经抄到了62万亿美元。&lt;br /&gt;　　　　&lt;br /&gt;　　四。 次贷。上面 A,B,C,D,E,F....都在赚大钱，那么这些钱到底从那里冒出来的呢？从根本上说，这些钱来自A以及同A相仿的投资人的盈利。而他们的盈利大半来 自美国的次级贷款。人们说次贷危机是由于把钱借给了穷人。笔者对这个说法不以为然。笔者以为，次贷主要是给了普通的美国房产投资人。这些人的经济实力本来 只够买自己的一套住房，但是看到房价快速上涨，动起了房产投机的主意。他们把自己的房子抵押出去，贷款买投资房。这类贷款利息要在8％－9％以上，凭他们 自己的收入很难对付，不过他们可以继续把房子抵押给银行，借钱付利息，空手套白狼。此时A很高兴，他的投资在为他赚钱；B也很高兴，市场违约率很低，保险 生意可以继续做；后面的C,D,E,F等等都跟着赚钱。&lt;br /&gt;　　　　&lt;br /&gt;　　五。次贷危机。房价涨到一定的程度就涨不上去了，后面没人 接盘。此时房产投机人急得像热锅上的蚂蚁。房子卖不出去，高额利息要不停的付，终于到了走头无路的一天，把房子甩给了银行。此时违约就发生了。此时A感到 一丝遗憾，大钱赚不着了，不过也亏不到那里，反正有B做保险。B也不担心，反正保险已经卖给了C。那么现在这份CDS保险在那里呢，在G手里。G刚从F手 里花了300亿买下了100个CDS，还没来得及转手，突然接到消息，这批CDS被降级，其中有20个违约，大大超出原先估计的1％到2％的违约率。每个 违约要支付50亿的保险金，总共支出达1000亿。加上300亿CDS收购费，G的亏损总计达1300亿。虽然G是全美排行前10名的大机构，也经不起如 此巨大的亏损。因此G濒临倒闭。&lt;br /&gt;　　　　&lt;br /&gt;　　六。金融危机。如果G倒闭，那么A花费5亿美元买的保险就泡了汤，更糟糕的是，由 于A采用了杠杆原理投资，根据前面的分析，A赔光全部资产也不够还债。因此A立即面临破产的危险。除了A之外，还有A2，A3,...,A20，统统要准 备倒闭。因此G,A,A2,...,A20一起来到美国财政部长面前，一把鼻涕一把眼泪地游说，G万万不能倒闭，它一倒闭大家都完了。财政部长心一软，就 把G给国有化了，此后A,...,A20的保险金总计1000亿美元全部由美国纳税人支付。&lt;br /&gt;　　　　&lt;br /&gt;　　七。美元危机。上面讲 到的100个CDS的市场价是300亿。而CDS市场总值是62万亿，假设其中有10％的违约，那么就有6万亿的违约CDS。这个数字是300亿的200 倍。如果说美国政府收购价值300亿的CDS之后要赔出1000亿。那么对于剩下的那些违约CDS，美国政府就要赔出20万亿。如果不赔，就要看着 A20,A21,A22等等一个接一个倒闭。无论采取什么措施，美元大贬值已经不可避免。&lt;br /&gt;　　　　&lt;br /&gt;　　以上计算所用的假设和数字同实际情况会有出入，但美国金融危机的严重性无法低估。&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-2663510872486974206?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/2663510872486974206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=2663510872486974206' title='45 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2663510872486974206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2663510872486974206'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/11/5.html' title='[转]5分钟看明白美国金融危机爆发的原因！'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>45</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-3441912594952174492</id><published>2008-10-30T13:47:00.001+08:00</published><updated>2008-10-30T13:48:49.064+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='搞笑'/><title type='text'>卖猪男如何引发了经济危机(转贴)</title><content type='html'>一男赶集卖猪，天黑遇雨，二十头猪未卖成，到一农家借宿。&lt;br /&gt;少妇说：家里只一人不便。&lt;br /&gt;男：求你了大妹子，给猪一头。&lt;br /&gt;女：好吧，但家只有一床。&lt;br /&gt;男：我也到床上睡，再给猪一头。&lt;br /&gt;女：同意。&lt;br /&gt;半夜男与女商量，我到你上面睡，女不肯。&lt;br /&gt;男：给猪两头。&lt;br /&gt;女允，要求上去不能动。&lt;br /&gt;少顷，男忍不住，央求动一下，女不肯。&lt;br /&gt;男：动一下给猪两头。女同意。&lt;br /&gt;男动了八次停下，女问为何不动？&lt;br /&gt;男说猪没了。&lt;br /&gt;女小声说：要不我给你猪……&lt;br /&gt;天亮后，男吹着口哨赶30头（含少妇家的10头）猪赶集去了……&lt;br /&gt;&lt;br /&gt;哈佛导师评论：要发现用户潜在需求，前期必须引导，培养用户需求，因此产生的投入是符合发展规律的。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;（加强篇）&lt;br /&gt;另一男得知此事，决意如法炮制，遂赶集卖猪，天黑遇雨，二十头猪未卖成，到一农家借宿&lt;br /&gt;&lt;span class="fullpost"&gt;&lt;br /&gt;少妇说：家里只一人不便。&lt;br /&gt;男：求你了大妹子，给猪一头&lt;br /&gt;女：好吧，但家只有一床。&lt;br /&gt;男：我也到床上睡，再给猪一头。&lt;br /&gt;女：同意。&lt;br /&gt;半夜男商女，我到你上面睡，女不肯。&lt;br /&gt;男：给猪两头。&lt;br /&gt;女允，要求上去不能动。&lt;br /&gt;少顷，男忍不住，央求动一下，女不肯。&lt;br /&gt;男：动一下给猪两头。女同意。&lt;br /&gt;男动了七次停下，女问为何不动？&lt;br /&gt;男说：完事了～～～女：......&lt;br /&gt;天亮后，男低著头赶2头猪赶集去了......&lt;br /&gt;&lt;br /&gt;哈佛导师评论：要结合企业自身规模进行谨慎投资，谨防资金链断裂问题&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;又一男得知此事，决意如法炮制兼吸取教训，遂先用一头猪去换一粒伟哥，事必，天亮后，男吹着口哨赶38头（含少妇家的18头）猪赶集去了……&lt;br /&gt;&lt;br /&gt;哈佛导师评论：企业如果获得金融资本的帮助，自身经营能力将得到倍增。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;知道此法男多，伟哥供不应求，逐渐要2头，3头猪换一粒伟哥。&lt;br /&gt;&lt;br /&gt;哈佛导师评论：这就是通货膨胀。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;当猪价格涨到16粒一棵的时候，哈佛导师评论：该男已经进入边际成本，除了拥有对自身能力的自信和未来良好愿望以外，实际现猪流已经为零。&lt;br /&gt;但换猪男越来越多，卖伟哥的决定，扩展生产能力，推出一种次级伟哥，如果你缺一头猪，只要你承诺可以到该女房中一夜，就可以先借，事成后补交猪款，这个方法大大促进了伟哥销售。&lt;br /&gt;&lt;br /&gt;哈佛导师评论：这就是贷款，让企业可以根据未来的收益选择借支流动资金&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;伟哥专卖店后来在即使你一头猪都没有，只要你承诺可以到该女房中一夜，就可以先借，事成后补交猪款。&lt;br /&gt;&lt;br /&gt;哈佛导师评论：这就是金融创新，让现在的人花未来的钱，反正等你老了未来的钱你也花不动。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;消息一出，换猪男越来越多，有人找伟哥专卖店，这个项目太好了，我们把它变成优质基金，对外销售债卷，你们也就可以分享我的收益，如何？&lt;br /&gt;&lt;br /&gt;结果伟哥专卖店觉得甚好，于是该公司把换猪男分三类，一类是拿现猪换的，一类是一部分现猪贷的，一类是完全没有现猪借的，发行三种债卷。大家踊跃而上。纷纷购买伟哥专卖店的债卷，伟哥专卖店生意太好，就把债卷销售外包给另外一家公司运作，该公司也一并大发其财，公司越做越大，甚至可以脱离实际伟哥销售情况来发行，给自己和伟哥专卖店带来巨大的现金收益。&lt;br /&gt;&lt;br /&gt;哈佛导师评论：这就是专业的人做专业的事，从实体经营到资本运作，经济进入了更高的层次。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;为了防止自己债卷未来有损失，该公司决定给它买上保险，这样债卷销售就更容易，因为一旦债卷出现问题，还可以获得保险公司的赔付，哇，债券公司销售这下子太好了，保险公司也获得巨大平白无故的保险收入。&lt;br /&gt;&lt;br /&gt;哈佛导师评论：这就是风险对冲，策略联盟，提高了企业的抗风险能力，也保护了消费者利益。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;换猪男太多，排长队等待，该女无法承受，说老娘不干了，我搬家，一时间有无数拥有伟哥的欠猪男。&lt;br /&gt;&lt;br /&gt;哈佛导师评论：这是个别现象，属于市场的正常波动，不会影响整个经济。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;结果该女迟迟不肯搬回。一部分欠猪男没有收入，只好赖帐，结果大量债卷到期无法换现猪吃，债卷公司一看，一粒伟哥16头猪，这哪里还得起，宣布倒闭&lt;br /&gt;&lt;br /&gt;哈佛导师评论：这是次贷危机，不会影响整个金融行业。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;哪里晓得债卷公司还把债卷上了保险，保险公司一看，这哪里赔得起，于是也宣布要倒闭。&lt;br /&gt;&lt;br /&gt;哈佛导师评论：这是金融危机，还不会影响整个实体经济。&lt;br /&gt;&lt;br /&gt;————————————&lt;br /&gt;&lt;br /&gt;后文：据说该女已搬到中国定居。&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-3441912594952174492?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/3441912594952174492/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=3441912594952174492' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3441912594952174492'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3441912594952174492'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/10/blog-post_30.html' title='卖猪男如何引发了经济危机(转贴)'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-300883009250935035</id><published>2008-10-17T23:29:00.003+08:00</published><updated>2008-10-20T16:42:20.733+08:00</updated><title type='text'>为何法电视台转向</title><content type='html'>近日国内媒体报道法电视二台开始揭露达赖的真实面目，认为可能是法国、乃至欧洲对达赖舆论转向的风向标。各种分析都有，包括法国国家利益，奥运期间外媒对中国的了解等等。对这种转向，国人当然欢迎，但是，也不要忘了，西方人的现实主义。为什么法电视二台要等到达赖哥哥去世，达赖动手术之后才开始转向呢？&lt;span style="font-weight: bold;"&gt;我想更重要的是，达赖的利用价值已经不大了，法国人为了现实的利益，终于开始了转向的第一步。&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-300883009250935035?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/300883009250935035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=300883009250935035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/300883009250935035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/300883009250935035'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/10/blog-post_17.html' title='为何法电视台转向'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-390499963974672328</id><published>2008-10-06T22:09:00.003+08:00</published><updated>2009-01-12T05:32:02.526+08:00</updated><title type='text'>Netbeans 的字体、默认语言和默认编码</title><content type='html'>默认时，netbeans的字体确实非常难看，于是我通过"工具", "选项"中的字体和颜色，将缺省字体改为了Courier New, 这样字体好看多了，但是输入汉字的时候变成了乱码。于是从网上找相关资料，原来可以通过下面的方式修改：&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;找到netbeans所用JDK的文件夹，例如：D:\Java\jdk\jdk1.6.0_07\jre\lib&lt;/li&gt;&lt;li&gt;复制文件fontconfig.properties.src为fontconfig.properties&lt;/li&gt;&lt;li&gt;修改fontconfig.properties, 将其中的sequence.monospaced.***中的内容换个顺序，也就是将alphabetic放到Chinese-***之前。&lt;/li&gt;&lt;li&gt;保存后，运行netbeans&lt;/li&gt;&lt;/ol&gt;确认你的netbeans的缺省字体为：Monospaced 13。这时就好看多了，与Courier New显示效果一样，而且汉字也不会变成乱码了。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;修改netbeans的默认语言和编码&lt;/span&gt;&lt;br /&gt;netbeans的默认配置文件：&lt;br /&gt;C:\Program Files\NetBeans 6.0.1\etc\netbeans.conf&lt;br /&gt;主要的修改就是 netbeans_default_options 选项，&lt;br /&gt;对于我而言，具体有用的参数有：&lt;br /&gt;a. --locale en_US&lt;br /&gt;将locale定义为英语，则启动界面就是英文的了;&lt;br /&gt;b. -J-Dfile.encoding=UTF-8&lt;br /&gt;这个是java的选项，定义文件的默认编码为utf8;&lt;br /&gt;c. --laf javax.swing.plaf.metal.MetalLookAndFeel&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-390499963974672328?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/390499963974672328/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=390499963974672328' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/390499963974672328'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/390499963974672328'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/10/netbeans.html' title='Netbeans 的字体、默认语言和默认编码'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-3160484722240679309</id><published>2008-10-06T21:12:00.002+08:00</published><updated>2008-10-06T21:16:53.250+08:00</updated><title type='text'>施明德谈马英九</title><content type='html'>&lt;a href="http://news.ifeng.com/taiwan/1/200810/1006_351_817853.shtml"&gt;施明德首次公开谈马英九&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;这基本价值，你要追求什么样的价值，我想在他一生当中，你在追求这些价值的时候，&lt;span style="font-weight:bold;"&gt;如果一个敢坚持价值的人，他不忌讳异议，他遇山开路，遇河架桥，遇到危险挺住它，遇到压力我就面对它&lt;/span&gt;，但是他经常很在意媒体。你看媒体反对的时候，他马上变来变去，马上往这边、又这边。&lt;br /&gt;&lt;br /&gt;施明德：我想，我不想来评论蔡英文，我对一个“政党”或者一个“政治领袖”，我总有几个标准是我恒久以来认为的。&lt;span style="font-weight:bold;"&gt;这个“政党”它有没有引领大方向的智慧，应该告诉我们大方向在哪里？“政治领袖”你要具备这样的大方向的智慧，“政党”你要说出你要把人民带到哪一个方向去。第二个坚守大原则的气节，就是压力来你能不能扛得住，诱惑来的时候你能不能拒绝。然后第三个，你用人，这我是认为是非常重要的。第四个你要鼓舞人民的信心，不管是谁，人都有好坏，“国家”有好坏，好的时候你怎么让它能够胜不骄，坏的时候你怎么鼓舞士气，这个是很重要的。&lt;/span&gt;好，我讲民进党到今天，我一直看不出来，看不出来！&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;我认为，虽然他谈的是马英九和民进党，但所言对于做人，做事业同样适用。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-3160484722240679309?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/3160484722240679309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=3160484722240679309' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3160484722240679309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3160484722240679309'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/10/blog-post.html' title='施明德谈马英九'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-2904191283923001172</id><published>2008-10-06T10:01:00.003+08:00</published><updated>2008-10-06T10:38:27.455+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Project Management'/><title type='text'>Using blogger as a project menagement platform</title><content type='html'>Nowadays, there are lots of softwares or tools for project management. In this article, however, I will introduce a method to manage project just by Blogger!&lt;br /&gt;&lt;br /&gt;We know Blogger.com are amazing blogger platform to write blog, share with friends and interact with friends. Thanks Blogger.com for providing us the powerful, totally free platform.  Then, how to manage project throght blogger.com? Let's figure it out!&lt;br /&gt;&lt;br /&gt;Commonly, the project management should have two major function:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;project wiki&lt;br /&gt;&lt;/li&gt;&lt;li&gt;project issue management&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;The wiki is the easy way to present project requirement, information, how-to-do, and other information. Blogger can be act as wiki easily. Create your blogger as project wiki, label it with project name and other information, such as: Myproject, requirement, design, etc...&lt;br /&gt;&lt;br /&gt;Other people in the project team could view all the project information through these labels, and can comment on it. So this is wiki feature.&lt;br /&gt;&lt;br /&gt;The issue management is also a blog article. We create a blog with label "Bug" as an issue.  when the issue has been fixed, we label this blog "Fixed". when it has been reopen, we fixed it with "reopen" and so on.&lt;br /&gt;&lt;br /&gt;Thus, we using label to manange project wiki and issues. Threre are also some skills to help us using blog  as a project menagement platform:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;prject name can be a label.&lt;/li&gt;&lt;li&gt;if the project are private, you can manage who can read your blog by blogger settings.&lt;/li&gt;&lt;li&gt;if you have many projects and every project has its different authority strategy, you can create a blog site for every project.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;By using blogger as a project menagement platform, there are some benefits:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;free to use&lt;/li&gt;&lt;li&gt;fully extends to many projects&lt;/li&gt;&lt;li&gt;more tricks of blogger you can use&lt;/li&gt;&lt;/ol&gt;This is just a begining, we will find more function or tricks to manage project through blogger. Thank Blogger.com and thank you for reading, if you have something to say, comments are welcome!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-2904191283923001172?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/2904191283923001172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=2904191283923001172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2904191283923001172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2904191283923001172'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/10/using-blogger-as-project-menagement.html' title='Using blogger as a project menagement platform'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-8456586999141446318</id><published>2008-05-07T20:58:00.004+08:00</published><updated>2008-05-29T21:41:17.103+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='COM+'/><category scheme='http://www.blogger.com/atom/ns#' term='Debug'/><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Vista'/><title type='text'>Delphi2007 Vista 下的COM+调试</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_Ed2oWHNGofs/SCGoETwRUaI/AAAAAAAAATk/7Z5xgjtWHe0/s1600-h/DelphiVistaComDebug.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://2.bp.blogspot.com/_Ed2oWHNGofs/SCGoETwRUaI/AAAAAAAAATk/7Z5xgjtWHe0/s320/DelphiVistaComDebug.jpg" alt="" id="BLOGGER_PHOTO_ID_5197620236937941410" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;"C:\Windows\system32\vsjitdebugger.exe" C:\Windows\system32\dllhost.exe /ProcessID:{1CE65B89-9CED-4BB2-A514-A54DE7A5B0A5}&lt;br /&gt;&lt;br /&gt;备注：Delphi7 Just in time debug:  "...Delphi7\bin\bordbg70.exe" -aeargs %ld %ld&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-8456586999141446318?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/8456586999141446318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=8456586999141446318' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8456586999141446318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8456586999141446318'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/05/delphi2007-vista-com.html' title='Delphi2007 Vista 下的COM+调试'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_Ed2oWHNGofs/SCGoETwRUaI/AAAAAAAAATk/7Z5xgjtWHe0/s72-c/DelphiVistaComDebug.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-8399002706150034743</id><published>2008-04-30T09:20:00.001+08:00</published><updated>2008-04-30T09:20:59.639+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='无功'/><category scheme='http://www.blogger.com/atom/ns#' term='电力'/><title type='text'>电力专业英文单词翻译</title><content type='html'>&lt;a href="http://www.52data.cn/Article/dlzt/200712/26875.html"&gt;电力专业英文单词翻译&lt;/a&gt;: "电力系统 power system&lt;br /&gt;发电机 generator&lt;br /&gt;励磁 excitation&lt;br /&gt;&lt;br /&gt;励磁器 excitor&lt;br /&gt;电压 voltage&lt;br /&gt;电流 current&lt;br /&gt;&lt;br /&gt;升压变压器 step-up transformer&lt;br /&gt;母线 bus&lt;br /&gt;变压器 transformer&lt;br /&gt;&lt;br /&gt;空载损耗 no-load loss&lt;br /&gt;铁损 iron loss&lt;br /&gt;铜损 copper loss&lt;br /&gt;&lt;br /&gt;空载电流 no-load current&lt;br /&gt;有功损耗 active loss&lt;br /&gt;无功损耗reactive loss&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;输电系统 power transmission system&lt;br /&gt;高压侧 high side&lt;br /&gt;输电线 transmission line&lt;br /&gt;&lt;br /&gt;高压 high voltage&lt;br /&gt;低压 low voltage&lt;br /&gt;中压 middle voltage&lt;br /&gt;&lt;br /&gt;功角稳定 angle stability&lt;br /&gt;稳定 stability&lt;br /&gt;电压稳定 voltage stability&lt;br /&gt;&lt;br /&gt;暂态稳定 transient stability&lt;br /&gt;电厂 power plant&lt;br /&gt;能量输送 power transfer&lt;br /&gt;&lt;br /&gt;交流 AC&lt;br /&gt;直流 DC&lt;br /&gt;电网 power system&lt;br /&gt;&lt;br /&gt;落点 drop point&lt;br /&gt;开关站 switch station&lt;br /&gt;调节 regulation&lt;br /&gt;&lt;br /&gt;高抗 high voltage shunt reactor&lt;br /&gt;并列的 apposable&lt;br /&gt;裕度 margin&lt;br /&gt;&lt;br /&gt;故障 fault"&lt;br /&gt;&lt;br /&gt;电流继电器 &lt;br /&gt;  current relay  &lt;p&gt;   电压继电器 &lt;br /&gt;  voltage relay &lt;/p&gt; &lt;p&gt;   跳闸继电器 &lt;br /&gt;  tripping relay &lt;/p&gt; &lt;p&gt;   合闸继电器 &lt;br /&gt;  closing relay &lt;/p&gt; &lt;p&gt;   中间继电器 &lt;br /&gt;  intermediate relay &lt;/p&gt; &lt;p&gt;   时间继电器 &lt;br /&gt;  time relay &lt;/p&gt; &lt;p&gt;   零序电压继电器 &lt;br /&gt;  zero-sequence voltage relay &lt;/p&gt; &lt;p&gt;   差动继电器 &lt;br /&gt;  differential relay &lt;/p&gt; &lt;p&gt;   闭锁装置 &lt;br /&gt;  locking device &lt;/p&gt; &lt;p&gt;   遥控 &lt;br /&gt;  telecontrol &lt;/p&gt; &lt;p&gt;   遥信 &lt;br /&gt;  telesignalisation &lt;/p&gt; &lt;p&gt;   遥测 &lt;br /&gt;  telemetering &lt;/p&gt; &lt;p&gt;   遥调 &lt;br /&gt;  teleregulation &lt;/p&gt; &lt;p&gt;   断路器 &lt;br /&gt;  breaker,circuit breaker &lt;/p&gt; &lt;p&gt;   少油断路器 &lt;br /&gt;  mini-oil breaker,oil-mini-mum breaker &lt;/p&gt; &lt;p&gt;   高频滤波器 &lt;br /&gt;  high-frequency filter &lt;/p&gt; &lt;p&gt;   组合滤波器 &lt;br /&gt;  combined filter &lt;/p&gt; &lt;p&gt;   常开触点 &lt;br /&gt;  normally opened contaact &lt;/p&gt; &lt;p&gt;   常闭触点 &lt;br /&gt;  normally closed contaact &lt;/p&gt; &lt;p&gt;   并联电容 &lt;br /&gt;  parallel capacitance &lt;/p&gt; &lt;p&gt;   保护接地 &lt;br /&gt;  protective earthing &lt;/p&gt; &lt;p&gt;   熔断器 &lt;br /&gt;  cutout,fusible cutout &lt;/p&gt; &lt;p&gt;   电缆 &lt;br /&gt;  cable &lt;/p&gt; &lt;p&gt;   跳闸脉冲 &lt;br /&gt;  tripping pulse &lt;/p&gt; &lt;p&gt;   合闸脉冲 &lt;br /&gt;  closing pulse &lt;/p&gt; &lt;p&gt;   一次电压 &lt;br /&gt;  primary voltage &lt;/p&gt; &lt;p&gt;   二次电压 &lt;br /&gt;  secondary voltage &lt;/p&gt; &lt;p&gt;   并联电容器 &lt;br /&gt;  parallel capacitor &lt;/p&gt; &lt;p&gt;   无功补偿器 &lt;br /&gt;  reactive power compensation device &lt;/p&gt; &lt;p&gt;   消弧线圈 &lt;br /&gt;  arc-suppressing coil &lt;/p&gt; &lt;p&gt;   母线 &lt;br /&gt;  Bus,busbar &lt;/p&gt; &lt;p&gt;   三角接法 &lt;br /&gt;  delta connection &lt;/p&gt; &lt;p&gt;   星形接法 &lt;br /&gt;  Wye connection &lt;/p&gt; &lt;p&gt;   原理图 &lt;br /&gt;  schematic diagram &lt;/p&gt; &lt;p&gt;   一次系统图 &lt;br /&gt;  primary system diagram &lt;/p&gt; &lt;p&gt;   二次系统图 &lt;br /&gt;  secondary system diagram &lt;/p&gt; &lt;p&gt;   两相短路 &lt;br /&gt;  two-phase short circuit &lt;/p&gt; &lt;p&gt;   三相短路 &lt;br /&gt;  three-phase short circuit &lt;/p&gt; &lt;p&gt;   单相接地短路 &lt;br /&gt;  single-phase ground short circuit &lt;/p&gt; &lt;p&gt;   短路电流计算 &lt;br /&gt;  calculation of short circuit current &lt;/p&gt; &lt;p&gt;   自动重合闸 &lt;br /&gt;  automatic reclosing &lt;/p&gt; &lt;p&gt;   高频保护 &lt;br /&gt;  high-freqency protection &lt;/p&gt; &lt;p&gt;   距离保护 &lt;br /&gt;  distance protection &lt;/p&gt; &lt;p&gt;   横差保护 &lt;br /&gt;  transverse differential protection &lt;/p&gt; &lt;p&gt;   纵差保护 &lt;br /&gt;  longitudinal differential protection &lt;/p&gt; &lt;p&gt;   线路保护 &lt;br /&gt;  line protection &lt;/p&gt; &lt;p&gt;   过电压保护 &lt;br /&gt;  over-voltage protection &lt;/p&gt; &lt;p&gt;   母差保护 &lt;br /&gt;  bus differential protection &lt;/p&gt; &lt;p&gt;   瓦斯保护 &lt;br /&gt;  Buchholtz protection &lt;/p&gt; &lt;p&gt;   变压器保护 &lt;br /&gt;  transformer protection &lt;/p&gt; &lt;p&gt;   电动机保护 &lt;br /&gt;  motor protection &lt;/p&gt; &lt;p&gt;   远方控制 &lt;br /&gt;  remote control &lt;/p&gt; &lt;p&gt;   用电量 &lt;br /&gt;  power consumption &lt;/p&gt; &lt;p&gt;   载波 &lt;br /&gt;  carrier &lt;/p&gt; &lt;p&gt;   故障 &lt;br /&gt;  fault &lt;/p&gt; &lt;p&gt;   选择性 &lt;br /&gt;  selectivity &lt;/p&gt; &lt;p&gt;   速动性 &lt;br /&gt;  speed &lt;/p&gt; &lt;p&gt;   灵敏性 &lt;br /&gt;  sensitivity &lt;/p&gt; &lt;p&gt;   可靠性 &lt;br /&gt;  reliability &lt;/p&gt; &lt;p&gt;   电磁型继电器 &lt;br /&gt;  electromagnetic &lt;/p&gt; &lt;p&gt;   无时限电流速断保护 &lt;br /&gt;  instantaneously over-current protection &lt;/p&gt; &lt;p&gt;   跳闸线圈 &lt;br /&gt;  trip coil &lt;/p&gt; &lt;p&gt;   工作线圈 &lt;br /&gt;  operating coil &lt;/p&gt; &lt;p&gt;   制动线圈 &lt;br /&gt;  retraint coil &lt;/p&gt; &lt;p&gt;   主保护 &lt;br /&gt;  main protection &lt;/p&gt; &lt;p&gt;   后备保护 &lt;br /&gt;  back-up protection &lt;/p&gt; &lt;p&gt;   定时限过电流保护 &lt;br /&gt;  definite time over-current protection &lt;/p&gt; &lt;p&gt;   三段式电流保护 &lt;br /&gt;  the current protection with three stages &lt;/p&gt; &lt;p&gt;   反时限过电流保护 &lt;br /&gt;  inverse time over-current protection &lt;/p&gt; &lt;p&gt;   方向性电流保护 &lt;br /&gt;  the directional current protection &lt;/p&gt; &lt;p&gt;   零序电流保护 &lt;br /&gt;  zero-sequence current protection &lt;/p&gt; &lt;p&gt;   阻抗 &lt;br /&gt;  impedance &lt;/p&gt; &lt;p&gt;   微机保护 &lt;br /&gt;  Microprocessor Protection&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-8399002706150034743?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/8399002706150034743/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=8399002706150034743' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8399002706150034743'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8399002706150034743'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/04/blog-post_30.html' title='电力专业英文单词翻译'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-4902153282397382324</id><published>2008-04-26T20:02:00.001+08:00</published><updated>2008-04-26T20:02:56.265+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><title type='text'>DLL 應用 - 設計可抽換的模組</title><content type='html'>&lt;h1&gt;&lt;a href="http://sun.cis.scu.edu.tw/%7Enms9115/articles/delphi/PluginDLL/PluginDLL.htm"&gt;DLL 應用 - 設計可抽換的模組&lt;/a&gt;&lt;/h1&gt;                            &lt;p&gt;作者：&lt;a href="mailto:huanlin_tsai@yahoo.com"&gt;蔡煥麟&lt;br /&gt;&lt;/a&gt;日期：Jan-2-2001　&lt;/p&gt; &lt;p&gt;&lt;b&gt;摘要：&lt;/b&gt;介紹以 DLL     來切割應用程式的實作方式，其中包含介面程式設計的技巧以及運用      Design Patterns 來解決設計上的問題。&lt;/p&gt;     &lt;h2&gt;前言&lt;/h2&gt;              &lt;p&gt;DLL（Dynamic Link Library，動態聯結函式庫）就目前來講已經不是什麼了不得的技術，坊間書籍隨手撿一本視窗程式設計或 Delphi 的書籍都可以找到 DLL                           的相關說明，少這一篇也不算少，之所以寫這篇文章，一方面是給自己的學習心得作個記錄，一方面也提供給有需要的人參考；而本文的主題－－設計動態載入的模組－－說穿了也只是提供一個把 Form 包在 DLL     裡面的實作方法，儘管如此，我還是希望你能在其中發現一些比較不一樣的東西。&lt;/p&gt;   &lt;p&gt; 由於現有關於 DLL 的文件資料已經很多，在此不多做重複，因此在閱讀本文時會需要一些 DLL 的基礎知識或者 DLL 的撰寫經驗，這樣閱讀起來會比較輕鬆。以下就重點式地列出一些基礎觀念：&lt;/p&gt;                             &lt;ul&gt;&lt;li&gt;靜態連結與動態連結的差異。&lt;/li&gt;&lt;li&gt;了解如何宣告 DLL 輸出函式（exported functions）以及如何在外部呼叫它們。&lt;/li&gt;&lt;li&gt;各種呼叫慣例（calling conventions）的差異。&lt;/li&gt;&lt;li&gt;何謂 DLL hell（&lt;a href="http://sun.cis.scu.edu.tw/%7Enms9115/articles/delphi/PluginDLL/PluginDLL.htm#%E8%A8%BB1"&gt;1&lt;/a&gt;）以及它對應用程式的維護有何影響。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt; DLL 在使用上又有靜態與動態載入的區別，所謂「靜態載入的 DLL」意指在編譯時期已經確定要連結的 DLL 是哪一個，而且會在行程初始化的階段就被載入，Delphi 的 VCL packages 即屬此類。動態載入的 DLL 則是執行時期需要時才載入，在程式撰寫上比靜態載入的方式麻煩些，但較有彈性，且應用程式啟動的速度也較快。&lt;/p&gt;                           &lt;p&gt;本文所要討論的就是以動態載入的 DLL                       來實作可抽換的應用程式模組。&lt;/p&gt;     &lt;h2&gt;以 DLL 切割應用程式&lt;/h2&gt;                          &lt;p&gt; 一般來說，使用 DLL 有下列優點：&lt;/p&gt;                           &lt;ul&gt;&lt;li&gt;節省記憶體。多個應用程式使用同一個 DLL 時，該 DLL 只會被載入一次，甚至可以用到時才載入 DLL，且用完立即釋放。&lt;/li&gt;&lt;li&gt;程式碼重複使用，可讓不同的程式語言使用。&lt;/li&gt;&lt;li&gt;應用程式模組化，可降低應用程式的複雜度，程式更新維護時較方便。&lt;/li&gt;&lt;li&gt;可支援設計多國語言的應用程式。你可以把每一種語言的字串資源分別存放在一個 DLL 裡面，程式執行時便可以動態切換程式所使用的語言。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;但也會一些困難必須克服，當我們要將應用程式切割成數個                       DLL 模組的時候，通常會碰到以下幾個問題：&lt;/p&gt;                         &lt;ol&gt;&lt;li&gt;DLL 如何輸出（export） VCL 物件？&lt;/li&gt;&lt;li&gt;如何將一個 Form 包在 DLL 裡面以供外部使用？&lt;/li&gt;&lt;li&gt;DLL 之間如何共享變數？&lt;/li&gt;&lt;/ol&gt; &lt;p&gt; 基本上，如果你撰寫成 package                        的形式就沒有上述問題了，但你可能會遇到其他麻煩，例如：名稱衝突的問題，這包括了型態、單元名稱、函式名稱的衝突，在此之前我也曾試著以 package                     的方式來撰寫可抽換的模組，但名稱衝突的問題令我覺得蠻困擾。我也曾在另一份文件中提及此事，以下這段文字是從該文轉貼上來的（&lt;a href="http://sun.cis.scu.edu.tw/%7Enms9115/articles/delphi/PluginDLL/PluginDLL.htm#%E8%A8%BB2"&gt;2&lt;/a&gt;）：&lt;/p&gt; &lt;p&gt; &lt;span style="color:#000080;"&gt; 「在撰寫幾個 package 的測試程式之後，我還是沒有將 package 應用在實際的專案開發中，而仍然使用 DLL，其最主要的原因，正是 package 優於 DLL 之處－－可以共享變數。這項功能的立意很好，但也帶來了另一些限制，主要是名稱衝突的問題，使得共用的 unit 一定要放在 package 裡面，否則當兩個 package 包含了相同的 unit，其中一個就無法載入，我們覺得這會造成麻煩。另外，由於其他的小組成員對於 package 的使用不熟，容易出 trouble（例如：project 要加入 .dcp 之類的），這也是考量之一。」&lt;/span&gt;&lt;/p&gt;                           &lt;p&gt; 在 DLL 之間共享變數的問題可以透過記憶體映射檔（memory-mapped file）來解決，你可以在文後所附的參考資料中找到相關資訊，這裡就不贅述。而在 DLL 中輸出 VCL 物件（例如：string）時得注意以下幾點：&lt;/p&gt;                           &lt;ul&gt;&lt;li&gt;在 DLL 和其用戶端程式的 Uses 子句裡頭的第一個單元必須是 ShareMem。&lt;/li&gt;&lt;li&gt;BORLNDMM.DLL 必須跟著你的應用程式一起發佈。&lt;/li&gt;&lt;li&gt;如果你修改了輸出物件的類別定義而使得原有物件的記憶體佈局改變，比如說加入一個 Integer 型態的私有成員，用戶端程式就必須重新編譯，如果使用舊的用戶端程式來呼叫新的 DLL 函式，應用程式就會發生錯誤甚至導致當機。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt; 與其隨時注意這些規則，也許選擇可以完全避開這些問題的方法會比較好，我的意思是使用 Windows 的標準型別來傳遞資料，例如要傳遞字串，就用 PChar 來代替 string。對其他較為複雜的結構，可以使用介面來解決，這意味著兩件事情：&lt;/p&gt;                         &lt;ol&gt;&lt;li&gt;輸出的型態是個抽象類別（abstract class）或介面（interface）。&lt;/li&gt;&lt;li&gt;物件應由 DLL 來建立（用戶端程式不知道物件的記憶體佈局）。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt; 符合了以上的規則，對於如何將 Form 物件包在 DLL 裡面的問題也就迎刃而解，稍後就會講到這部分如何實作。&lt;/p&gt;                           &lt;table bg border="1" width="100%" style="color:#008080;"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td width="100%"&gt;&lt;span style="color:#ffffff;"&gt;介 面（interface）在物件導向的領域裡是一個很重要的觀念，它描述了服務提供者和使用者之間的權責，或者說定義了兩個物件之間溝通的方式，通常這個 溝通方式一經制定就不會修改（理想狀況下），因此介面亦可視為物件之間的合約。以 OOP 的角度來看，介面就是一組公開的方法（public methods），跟類別不同之處是它沒有 private 及 protected 等存取等級的區別，不可以包含資料成員，也沒有實作的程式碼，它就只是很單純的....呃...介面。在一個複雜的系統裡面，這種單純顯得特別珍貴，常常 得經過一番深思熟慮之後才能萃取出較為抽象的成分，這不但有助於你在設計時以比較抽象的層次去思考，同時設計出來的介面也比較能夠再拿來重複使用。以用戶 端的角度來看，介面把系統背後的複雜度隱藏了起來，用戶端就只需專注在它需要的部分，使用上會比較容易。&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;h2&gt;設計可抽換的模組&lt;/h2&gt;              &lt;p&gt;所謂可抽換的模組，就是指在程式執行時動態地載入與釋放的模組，對於規模較龐大，功能較複雜的應用程式來說，將應用程式切割成數個獨立運作的模組有以下優點：&lt;/p&gt; &lt;ul&gt;&lt;li&gt;應用程式部署的組態更加彈性（例如：有些模組僅包裝於某種版本中）。 &lt;/li&gt;&lt;li&gt;減少應用程式每次更新版本的檔案大小。 &lt;/li&gt;&lt;li&gt;有利於明確劃分小組成員的權責。 &lt;/li&gt;&lt;li&gt;有效地降低單一程式的複雜度，程式較易於維護。 &lt;/li&gt;&lt;/ul&gt; &lt;p&gt; 以下會一步步實作出一個具體而微的範例，你可以把這個範例視為一個基礎的框架（framework），稍加修改就可以運用於實際的專案開發上面。&lt;/p&gt; &lt;h3&gt;描述需求&lt;/h3&gt;              &lt;p&gt;讓我們來簡單地分析一下應用程式的需求，假設原本的開發方式是將所有的程式單元編譯連結成一個可執行檔，現在要將應用程式的各個功能切割為獨立的模組，例如：&lt;/p&gt; &lt;pre&gt;&lt;span style="font-size:100%;"&gt;                     +--- 客戶資料維護作業（Customer.DLL）&lt;br /&gt;主程式（Main.exe）---+--- 產品資料維護作業（Employee.DLL）&lt;br /&gt;                    +--- 訂單資料維護作業（Orders.DLL）&lt;/span&gt;&lt;/pre&gt; &lt;p&gt; 其中每個 DLL 都是在使用者執行該項功能的時候才動態載入，而且每個 DLL 裡面至少包含一個 Form，為了有別於一般的 DLL，以下就以 plugin 稱之。我們預期各 plugin DLL 所包含的 Form 會有一些共同的屬性和行為，因此把這些共同點放到一個基礎視窗類別裡面，讓其他 Form 繼承自這個基礎類別。它們的關係看起來像這樣：&lt;/p&gt;    &lt;p&gt; &lt;img src="http://sun.cis.scu.edu.tw/%7Enms9115/articles/delphi/PluginDLL/figure1.jpg" border="0" height="312" width="634" /&gt;&lt;/p&gt;    &lt;p&gt; 每一個維護作業都需要開啟一個視窗，因此主程式的責任之一便是建立並顯示 DLL 裡面的視窗。我們希望每一個維護作業的視窗關閉後才能執行另一個維護作業，所以使用 ShowModal 的方式顯示視窗。做一些簡單的分析之後，可以得到主程式在執行每項作業時所需的共同步驟：&lt;/p&gt;                           &lt;ol&gt;&lt;li&gt;載入指定的 plugin DLL。 &lt;/li&gt;&lt;li&gt;建立並顯示 plugin DLL 裡面的 Form 物件。 &lt;/li&gt;&lt;li&gt;釋放 Form 物件。 &lt;/li&gt;&lt;li&gt;釋放 plugin DLL。 &lt;/li&gt;&lt;/ol&gt; &lt;p&gt; 其中載入與是釋放 plugin DLL 的工作由主程式負責，而前面有提過 DLL 中的物件必須由 DLL 自己來建立，因此建立、顯示以及釋放 Form 物件的工作都由 plugin DLL 來負責提供函式，主程式只要在適當時機去呼叫它們就行了。&lt;/p&gt;                           &lt;h3&gt;主程式&lt;/h3&gt;               &lt;p&gt; 在主程式中加入一個執行 plugin 的方法，此方法需要一個參數指定 DLL 的檔名以便將其載入執行，像這樣：&lt;/p&gt;                           &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;procedure&lt;/b&gt; TMainForm.RunPlugin(&lt;b&gt;const&lt;/b&gt; FileName: string);&lt;br /&gt;&lt;b&gt;var&lt;/b&gt;&lt;br /&gt; ADllHandle: THandle;&lt;br /&gt; APlugin: IPlugin;&lt;br /&gt; AFormHandle: THandle;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; ADllHandle := SafeLoadLibrary(FileName);&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; ADllHandle &lt;&gt; 0 &lt;b&gt;then&lt;/b&gt;&lt;br /&gt; &lt;b&gt;begin&lt;/b&gt;&lt;br /&gt;   APlugin := DllCreatePlugin(ADllHandle, Application.Handle);&lt;br /&gt;   &lt;b&gt;try&lt;/b&gt;&lt;br /&gt;     AFormHandle := APlugin.CreateForm(Handle);&lt;br /&gt;     APlugin.ShowModalForm;&lt;br /&gt;     APlugin := &lt;b&gt;nil&lt;/b&gt;;&lt;br /&gt;     FreeLibrary(ADllHandle);&lt;br /&gt;   &lt;b&gt;except&lt;/b&gt;&lt;br /&gt;     FreeLibrary(ADllHandle);&lt;br /&gt;     &lt;b&gt;raise&lt;/b&gt;;&lt;br /&gt;   &lt;b&gt;end&lt;/b&gt;;&lt;br /&gt; &lt;b&gt;end&lt;/b&gt;&lt;br /&gt; &lt;b&gt;else&lt;/b&gt;&lt;br /&gt;   ShowMessage('&lt;/span&gt;無法載入函式庫&lt;span style="font-family:Courier New;"&gt;: ' + FileName);&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;p&gt; 從以上程式碼可以看出主程式載入 DLL 之後會呼叫 DllCreatePlugin 來建立 plugin                           物件並且取得其介面參考，接著主程式就利用該介面參考來存取 plugin                     物件提供的服務，包括建立視窗，顯示視窗等等。很明顯地，IPlugin                     介面是主程式和 plugin DLL 之間溝通的橋樑，而且 IPlugin 介面至少要提供下列方法：&lt;/p&gt;                           &lt;p&gt;   CreateForm - 建立 Form 物件&lt;br /&gt;                             ShowModalForm - 顯示視窗&lt;br /&gt;                             DestroyForm - 摧毀 Form 物件&lt;/p&gt;                           &lt;p&gt; 眼尖的讀者可能會發現，上面的程式中並沒有呼叫 DestroyForm，而且也沒有呼叫類似 DllDestroyPlugin 的函式來摧毀 plugin 物件，這些物件什麼時候會被釋放掉？&lt;br /&gt;                          &lt;br /&gt;它們是自動被釋放掉的。由於 Form 物件的建立是透過 plugin 物件來完成，所以我打算把摧毀 Form 物件的責任交給 plugin 物件，也就是當 plugin 物件摧毀時會自動將 Form 物件一併釋放掉；而為了簡化摧毀 plugin 物件的動作，我讓 plugin 物件具有自動參考計數的能力，這麼一來只要該物件沒有人使用它（物件的參考計數為 0）就會自動釋放掉了，做法很簡單，只要讓實作 IPlugin 的類別繼承自 TInterfaceObject 就行了，其他細節都由 VCL 幫我們完成了。&lt;/p&gt;                           &lt;table bg border="1" width="100%" style="color:#008080;"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td width="100%"&gt;&lt;span style="color:#ffffff;"&gt;LoadLibrary 與 FreeLibrary                             也有自己的參考計數，並且用它來決定是否載入及釋放                             DLL。也就是說重複呼叫 LoadLibrary('A.DLL') 並不會將 A.DLL                             載入兩次，第二次的呼叫只會遞增參考計數而已；同樣的，FreeLibrary                             會遞減 DLL 的參考計數，直到計數為 0 才會真正將 DLL                             釋放掉。&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; 接著看 DllCreatePlugin 函式：&lt;/p&gt;                           &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;type&lt;/b&gt;&lt;br /&gt; TCreatePluginFunc = &lt;b&gt;function&lt;/b&gt; (hApp: THandle): IPlugin; &lt;b&gt;stdcall&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;const&lt;/b&gt;&lt;br /&gt; SDllCreatePluginFuncName = '&lt;span style="color:#ff00ff;"&gt;CreatePlugin&lt;/span&gt;';&lt;br /&gt;&lt;br /&gt;&lt;b&gt;implementation&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;resourcestring&lt;/b&gt;&lt;br /&gt; sErrorLoadingDLL = '&lt;/span&gt;無法載入模組&lt;span style="font-family:Courier New;"&gt;!';&lt;br /&gt; sErrorDllProc = '&lt;/span&gt;無法呼叫 &lt;span style="font-family:Courier New;"&gt;DLL &lt;/span&gt;函式&lt;span style="font-family:Courier New;"&gt;: %s';&lt;br /&gt;&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; DllCreatePlugin(hLib, hApp: THandle): IPlugin;&lt;br /&gt;&lt;b&gt;var&lt;/b&gt;&lt;br /&gt; pProc: TFarProc;&lt;br /&gt; CreatePluginFunc: TCreatePluginFunc;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; pProc := GetProcAddress(hLib, PChar(SDllCreatePluginFuncName));&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; pProc = &lt;b&gt;nil&lt;/b&gt; &lt;b&gt;then&lt;/b&gt;&lt;br /&gt;   &lt;b&gt;raise&lt;/b&gt; Exception.CreateFmt(sErrorDllProc, [SDllCreatePluginFuncName]);&lt;br /&gt; CreatePluginFunc := TCreatePluginFunc(pProc);&lt;br /&gt; Result := CreatePluginFunc(hApp);&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;p&gt; DllCreatePlugin 會嘗試從指定的 DLL 模組中呼叫函式 'CreatePlugin'                     來建立 plugin 物件，並且傳回 plugin 物件的介面參考，參數 hLib 是 DLL 代碼，而                     hApp 則直接傳遞給 DLL 的CreatePlugin 函式，這個參數的作用稍後會解釋。&lt;/p&gt;                           &lt;p&gt; 至此主程式所需的程式碼大致上已經完成了，接下來看看 DLL 的 CreatePlugin 函式。&lt;/p&gt;                           &lt;h3&gt;DLL 的輸出函式&lt;/h3&gt;                           &lt;p&gt; 我們的 plugin DLL 只有輸出一個函式供外界呼叫，就是前面提到的 CreatePlugin，其函式原型為：&lt;/p&gt;                           &lt;p&gt;&lt;b&gt; function&lt;/b&gt; CreatePlugin(hApp: THandle): IPlugin; &lt;b&gt;export&lt;/b&gt;; &lt;b&gt;stdcall&lt;/b&gt;;&lt;/p&gt;                          &lt;p&gt; CreatePlugin 函式會建立 TPlugin 物件並且傳回 IPlugin 介面的參考。由於 plugin 物件僅需被建立一次，我們可以用一個全域變數實作出簡單的                 &lt;span style="color:#ff00ff;"&gt; Singleton&lt;/span&gt;（&lt;a href="http://sun.cis.scu.edu.tw/%7Enms9115/articles/delphi/PluginDLL/PluginDLL.htm#%E8%A8%BB3"&gt;3&lt;/a&gt;）：&lt;/p&gt;         &lt;pre&gt;&lt;b&gt;&lt;span style="font-family:Courier New;"&gt;var&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt; g_PluginIntf: IPlugin = &lt;b&gt;nil&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;implementation&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; CreatePlugin(hApp: THandle): IPlugin;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; Application.Handle := hApp; &lt;span style="color:#000080;"&gt;// &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000080;"&gt;讓 &lt;span style="font-family:Courier New;"&gt;EXE &lt;/span&gt;與 &lt;span style="font-family:Courier New;"&gt;DLL &lt;/span&gt;使用同一個 &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="color:#000080;"&gt;application handle.&lt;/span&gt;&lt;b&gt;&lt;br /&gt; if&lt;/b&gt; g_PluginIntf = &lt;b&gt;nil&lt;/b&gt; &lt;b&gt;then&lt;/b&gt;&lt;br /&gt;   g_PluginIntf := TPlugin.Create; &lt;span style="color:#000080;"&gt;// TPlugin &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000080;"&gt;的物件參考計數 &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="color:#000080;"&gt;= 1&lt;/span&gt;&lt;br /&gt; Result := g_PluginIntf;           &lt;span style="color:#000080;"&gt;// TPlugin &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000080;"&gt;的物件參考計數 &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="color:#000080;"&gt;= 2&lt;/span&gt;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;p&gt; CreatePlugin 需要傳入一個參數 hApp，代表呼叫者程序的 Application 物件的 Handle，通常是傳入 Application.Handle，好讓主程式和 DLL 的 Application 物件能夠「同步」。之所以要這麼做是因為當你的 DLL 專案未使用 "Build with runtime package" 選項時，執行檔和載入的 DLL 會各自有一個 Application 物件，但是只有執行檔的 Application 物件有連結一個視窗，DLL 則沒有，因此 DLL 的 Application.Handle 屬性總是為 0。若少了這個同步的動作，那麼當 DLL 的 Form 開啟時，你會在桌面的工作列上看到多了一個視窗按鈕，看起來就像執行了另一個應用程式一樣，我們不希望看到這種情形。&lt;/p&gt;                           &lt;p&gt;  當然啦，如果你的主程式和 DLL 都使用 "Build with runtime packages"                           來建立（你應該這麼做），就不需要這個同步動作了（想想看為什麼？）。&lt;/p&gt; &lt;p&gt;程式碼裡面有兩行關於物件參考計數的註解，是想要表達介面程式設計的一個基本觀念：當一個介面參考在函式之間以                          pass by value 的方式傳遞時會遞增物件的參考計數（pass by                          reference 則不會）。此觀念有助於你正確掌握物件的壽命。&lt;/p&gt;                         &lt;p&gt; 最後別忘了還要把這輸出函式加到專案原始碼的 exports 子句裡頭：&lt;/p&gt;                           &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;exports&lt;/b&gt;&lt;br /&gt; CreatePlugin;&lt;/span&gt;&lt;/pre&gt; &lt;h3&gt;IPlugin 介面與 TPlugin 類別&lt;/h3&gt;                           &lt;p&gt; IPlugin 介面定義如下：&lt;/p&gt;                           &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;IPlugin = &lt;b&gt;interface&lt;/b&gt;&lt;br /&gt;['{D3F4445A-C704-42BC-8283-822541668919}']    &lt;span style="color:#000080;"&gt;// &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000080;"&gt;按 &lt;/span&gt;&lt;span style="font-family:Courier New;color:#000080;"&gt;Ctrl+Shift+G &lt;/span&gt;&lt;span style="color:#000080;"&gt;產生 &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="color:#000080;"&gt;GUID&lt;/span&gt;&lt;br /&gt; &lt;b&gt;function&lt;/b&gt; CreateForm(hMainForm: THandle): THandle;&lt;br /&gt; &lt;b&gt;procedure&lt;/b&gt; DestroyForm;&lt;br /&gt; &lt;b&gt;function&lt;/b&gt; ShowModalForm: Integer;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;p&gt; 其實以上函式也可以寫成一般的 DLL 函式，當作是 DLL 的介面，之所以另外定義這個介面，一方面是希望簡化 DLL 本身的介面，另一方面也可以集中管理程式碼，以後如果需要增加介面方法的話，只要加在 IPlugin 介面裡面就好了，不用把現有的 DLL 原始碼一個個找出來修改，這也有助於簡化 DLL 的撰寫以及日後的維護工作。&lt;/p&gt;                           &lt;table bg border="1" width="100%" style="color:#008080;"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td width="100%"&gt;&lt;span style="color:#ffffff;"&gt;介面不包含實作，實作必須由類別來提供。&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; 接著定義一個 TPlugin 類別來實作 IPlugin 介面：&lt;/p&gt;                           &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;TPlugin = &lt;b&gt;class&lt;/b&gt;(TInterfacedObject, IPlugin)&lt;br /&gt;&lt;b&gt;private&lt;/b&gt;&lt;br /&gt; FForm: TForm;&lt;br /&gt;&lt;b&gt;public&lt;/b&gt;&lt;br /&gt; &lt;b&gt;destructor&lt;/b&gt; Destroy; override;&lt;br /&gt;&lt;br /&gt; &lt;b&gt;function&lt;/b&gt; CreateForm(hMainForm: THandle): THandle;&lt;br /&gt; &lt;b&gt;procedure&lt;/b&gt; DestroyForm;&lt;br /&gt; &lt;b&gt;function&lt;/b&gt; ShowModalForm: Integer;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;p&gt; 在 IPlugin 中加上 GUID 以及讓 TPlugin 繼承自 TInterfacedObject 的目的，是為了讓物件擁有 Interfaced RTTI 以及自動參考計數的能力，這樣我們的 TPlugin 物件就會在沒有任何人使用它時自動釋放掉。私有成員 FForm 記錄了此 plugin 物件所建立的視窗的參考，以便控制其壽命，其型態也可以視需要改成 TBaseForm，那麼你的 TBaseForm 的設計得盡量不要經常修改，或者說設計得抽象一些，讓這些核心的類別在比較抽象的層次上面運作。&lt;/p&gt;                           &lt;p&gt;各個方法的名稱皆可望文生義，程式碼也很簡單，相信你可以猜個八九不離十，這裡就不一一列出，比較值得一提的是                     CreateForm 函式與解構元 Destroy，分述如下：&lt;/p&gt;                        &lt;h4&gt;TPlugin.CreateForm - 使用類別參考來建立物件 &lt;/h4&gt;                        &lt;p&gt;在 CreateForm 函式裡面，建立 Form                     物件的那行程式是這麼寫的：&lt;/p&gt;     &lt;pre&gt;  &lt;span style="font-family:Courier New;"&gt;FForm := &lt;span style="color:#ff00ff;"&gt;g_ConcreteClass&lt;/span&gt;.Create(Application);&lt;/span&gt;&lt;/pre&gt;     &lt;p&gt;其中 g_ConcreteClass 是一個全域變數，其定義為：&lt;/p&gt;                        &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;var&lt;/b&gt;&lt;br /&gt; g_ConcreteClass: &lt;span style="color:#ff00ff;"&gt;TBaseFormClass&lt;/span&gt; := &lt;b&gt;nil&lt;/b&gt;;&lt;/span&gt;&lt;/pre&gt;     &lt;p&gt;而 TBaseFormClass 是一個類別參考型態（class-reference type），它跟                     TBaseForm 定義在同一個單元裡面：&lt;/p&gt;                        &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;type&lt;/b&gt;&lt;br /&gt; TBaseFormClass = &lt;b&gt;class&lt;/b&gt; &lt;b&gt;of&lt;/b&gt; TBaseForm;&lt;br /&gt;&lt;br /&gt; TBaseForm = &lt;b&gt;class&lt;/b&gt;(TForm)&lt;br /&gt; .....&lt;br /&gt; &lt;b&gt;end&lt;/b&gt;;&lt;/span&gt;&lt;/pre&gt;     &lt;p&gt;也就是說我們用一個類別參考型態的變數 g_ConcreteClass                    來記錄欲實體化的類別型態，因此在建立 Form                    物件之前還必須先設定 g_ConcreteClass 才行，如此 TPlugin 才能以正確的                     Form 類別來進行實體化的動作。&lt;/p&gt;                        &lt;p&gt;您或許會想為什麼要這麼麻煩，直接寫成像                     TCustomerForm.Create 這樣不就好了嗎？&lt;/p&gt;                        &lt;p&gt;簡單地說，是基於維護的考量。由於在整個 TPlugin                     的實作裡面，日後唯一可以能會經常變動的就是要被實體化的                     Form 類別，使用類別參考使我們免於在 TPlugin                     的實作程式碼裡面把類別型態寫死，以後如果要實體化其他的                     Form 類別，只要修改 g_ConcreteClass                     這個變數就行了，不用再費一番搜尋及替換文字的功夫，還得擔心有沒有哪裡沒有改到；換句話說，我們等於使用類別參考來讓編譯器幫我們完成這個替換文字的動作，而且保證不會遺漏任何地方。&lt;/p&gt;     &lt;table bg border="1" width="100%" style="color:#008080;"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td width="100%"&gt;&lt;span style="color:#ffffff;"&gt;我交替使用了「建立物件」與「實體化」兩種詞彙，其實它們指的是同一件事情：建立某個類別的實體（instance）。&lt;/span&gt;&lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;此技巧對於團隊開發也有好處，你只要公佈 TPlugin 和                     TBaseForm 兩個單元，然後告訴組員照下面兩個步驟做就行了：&lt;/p&gt;                       &lt;ol&gt;&lt;li&gt;從 TBaseForm 衍生一個新類別（可以利用 Delphi                         的物件寶庫來簡化這項工作）。&lt;/li&gt;&lt;li&gt;在這個新類別的單元的 Uses 子句裡加入 TPlugin                         類別所屬的單元，並且在初始化階段把類別名稱指定給                         g_ConcreteClass 變數。&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;在這個範例裡面，我們只有一個                     TBaseForm 的後代，叫做 TForm1，因此在 TForm1                     的單元裡面會有這一段：&lt;/p&gt;     &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;uses&lt;br /&gt;&lt;/b&gt;  DllExport;  &lt;span style="color:#000080;"&gt;// TPlugin &lt;/span&gt;&lt;/span&gt;&lt;span style="color:#000080;"&gt;類別實作放在這個單元裡面&lt;/span&gt;&lt;b&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;.....&lt;br /&gt;&lt;br /&gt;initialization&lt;/span&gt;&lt;/b&gt;&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt; g_ConcreteClass := TForm1;&lt;/span&gt;&lt;/pre&gt;     &lt;p&gt;　&lt;/p&gt;     &lt;h4&gt;TPlugin.Destroy&lt;/h4&gt;     &lt;p&gt;解構函式會呼叫 DestroyForm 使 Form                     物件一併釋放掉，並且還原 DLL 的 application handle：&lt;/p&gt;                        &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;destructor&lt;/b&gt; TPlugin.Destroy;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; DestroyForm;&lt;br /&gt; Application.Handle := g_DllAppHandle;&lt;br /&gt; &lt;b&gt;inherited&lt;/b&gt; Destroy;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;其中                       g_DllAppHandle 是一個全域變數，其宣告如下：&lt;/p&gt;                      &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;var&lt;/b&gt;&lt;br /&gt; g_DllAppHandle: THandle;&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;而我們必須在 DLL 初始化的時候將 DLL 本身的 application handle                       保存起來：&lt;/p&gt; &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;initialization&lt;/b&gt;&lt;br /&gt; g_DllAppHandle := Application.Handle;&lt;/span&gt;&lt;/pre&gt; &lt;p&gt;其實如果 DLL 專案有用 "Build with runtime package"                       選項的話，這個保存及還原 application handle                       的動作就可以免了。相反地，若不加上保存及還原的動作，而且                       DLL 專案不使用 "Build with runtime package" 選項的話，當 DLL                       被釋放時就會發生主視窗也被一併關閉的怪異情形。&lt;/p&gt; &lt;h3&gt;擅用原始的力量&lt;/h3&gt;             &lt;p&gt;到此重要的部分應該都已經提到了，您可能會發現我並沒有對                          TBaseForm 多做說明，原因是在這個範例程式中 TBaseForm              並沒有什麼特別之處，只是為日後擴充時預留的一個基礎類別，你也許會想要將各個模組共用的功能和視覺化介面集中在此類別以簡化各模組的撰寫工作，以及讓應用程式有一致的操作方式和行為，這部分每個人的需求不同，就請您自行發揮了。&lt;/p&gt; &lt;p&gt;如果你覺得以上的程式碼過於片段零散，無法獲得整體的概念，建議您直接看範例的原始碼，把範例程式執行一遍以觀察程式運作的過程，不了解的地方再回來文件裡尋找解釋，這樣也許會比較容易些。為了方便閱讀，我也把範例程式中比較重要的兩個單元分別列在表一和表二裡面了。&lt;/p&gt; &lt;table border="1" height="41" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td height="17" width="100%"&gt;列表一. DllUtils.pas&lt;/td&gt;                        &lt;/tr&gt;   &lt;tr&gt;     &lt;td height="12" width="100%"&gt;       &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;unit&lt;/b&gt; DllUtils;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;interface&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;uses&lt;/b&gt;&lt;br /&gt; Windows, Messages, SysUtils, Classes, Forms, Controls;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;type&lt;/b&gt;&lt;br /&gt; IPlugin = &lt;b&gt;interface&lt;/b&gt;&lt;br /&gt; ['{D3F4445A-C704-42BC-8283-822541668919}'] &lt;br /&gt;   &lt;b&gt;function&lt;/b&gt; CreateForm(hMainForm: THandle): THandle;&lt;br /&gt;   &lt;b&gt;procedure&lt;/b&gt; DestroyForm;&lt;br /&gt;   &lt;b&gt;function&lt;/b&gt; ShowModalForm: Integer;&lt;br /&gt; &lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt; TCreatePluginFunc = &lt;b&gt;function&lt;/b&gt; (hApp: THandle): IPlugin; &lt;b&gt;stdcall&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; DllCreatePlugin(hLib, hApp: THandle): IPlugin;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;implementation&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;resourcestring&lt;/b&gt;&lt;br /&gt; sErrorLoadingDLL = '&lt;/span&gt;無法載入模組&lt;span style="font-family:Courier New;"&gt;!';&lt;br /&gt; sErrorDllProc = '&lt;/span&gt;無法呼叫 &lt;span style="font-family:Courier New;"&gt;DLL &lt;/span&gt;函式&lt;span style="font-family:Courier New;"&gt;: %s';&lt;br /&gt;&lt;br /&gt;&lt;b&gt;const&lt;/b&gt;&lt;br /&gt; SDllCreatePluginFuncName = 'CreatePlugin';&lt;br /&gt;&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; DllCreatePlugin(hLib, hApp: THandle): IPlugin;&lt;br /&gt;&lt;b&gt;var&lt;/b&gt;&lt;br /&gt; pProc: TFarProc;&lt;br /&gt; CreatePluginFunc: TCreatePluginFunc;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; Result := &lt;b&gt;nil&lt;/b&gt;;&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; hLib = 0 &lt;b&gt;then&lt;/b&gt;&lt;br /&gt;   Exit;&lt;br /&gt; pProc := GetProcAddress(hLib, PChar(SDllCreatePluginFuncName));&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; pProc = &lt;b&gt;nil&lt;/b&gt; &lt;b&gt;then&lt;/b&gt;&lt;br /&gt;   &lt;b&gt;raise&lt;/b&gt; Exception.CreateFmt(sErrorDllProc, [SDllCreatePluginFuncName]);&lt;br /&gt; CreatePluginFunc := TCreatePluginFunc(pProc);&lt;br /&gt; Result := CreatePluginFunc(hApp);&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;.&lt;/span&gt;&lt;/pre&gt;     &lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt; 　&lt;/p&gt;     &lt;table border="1" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td width="100%"&gt;列表二. DllExport.pas&lt;/td&gt;                        &lt;/tr&gt;   &lt;tr&gt;     &lt;td width="100%"&gt;       &lt;pre&gt;&lt;span style="font-family:Courier New;"&gt;&lt;b&gt;unit&lt;/b&gt; DllExport;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;interface&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;uses&lt;/b&gt; Windows, Classes, Forms, DllUtils, BaseFrm;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;type&lt;/b&gt;&lt;br /&gt; &lt;span style="color:#000080;"&gt;// Inherited from TInterfacedObject to be reference-counted.&lt;/span&gt;&lt;br /&gt; TPlugin = &lt;b&gt;class&lt;/b&gt;(TInterfacedObject, IPlugin)&lt;br /&gt; &lt;b&gt;private&lt;/b&gt;&lt;br /&gt;   FForm: TBaseForm;&lt;br /&gt; &lt;b&gt;public&lt;/b&gt;&lt;br /&gt;   &lt;b&gt;destructor&lt;/b&gt; Destroy; override;&lt;br /&gt;&lt;br /&gt;   &lt;b&gt;function&lt;/b&gt; CreateForm(hMainForm: THandle): THandle;&lt;br /&gt;   &lt;b&gt;procedure&lt;/b&gt; DestroyForm;&lt;br /&gt;   &lt;b&gt;function&lt;/b&gt; ShowModalForm: Integer;&lt;br /&gt; &lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; CreatePlugin(hApp: THandle): IPlugin; &lt;b&gt;export&lt;/b&gt;; &lt;b&gt;stdcall&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;exports&lt;/b&gt;&lt;br /&gt; CreatePlugin;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;var&lt;br /&gt;&lt;/b&gt;  g_ConcreteClass: TBaseFormClass := &lt;b&gt;nil&lt;/b&gt;;&lt;br /&gt; g_PluginIntf: IPlugin = &lt;b&gt;nil&lt;/b&gt;;&lt;br /&gt; g_DllAppHandle: THandle;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;implementation&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;uses&lt;/b&gt; Dialogs, SysUtils;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; CreatePlugin(hApp: THandle): IPlugin;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; hApp &lt;&gt; 0 &lt;b&gt;then&lt;/b&gt;&lt;br /&gt;   Application.Handle := hApp;     &lt;span style="color:#000080;"&gt;// Sync Application handle.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; g_PluginIntf = &lt;b&gt;nil&lt;/b&gt; &lt;b&gt;then&lt;/b&gt;&lt;br /&gt;   g_PluginIntf := TPlugin.Create;&lt;br /&gt; Result := g_PluginIntf;          &lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#000080;"&gt;{ TPlugin }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;destructor&lt;/b&gt; TPlugin.Destroy;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; DestroyForm;&lt;br /&gt; Application.Handle := g_DllAppHandle;&lt;br /&gt; &lt;b&gt;inherited&lt;/b&gt; Destroy;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; TPlugin.CreateForm(hMainForm: THandle): THandle;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; FForm = &lt;b&gt;nil&lt;/b&gt; &lt;b&gt;then&lt;/b&gt;&lt;br /&gt; &lt;b&gt;begin&lt;/b&gt;&lt;br /&gt;   Assert(g_ConcreteClass &lt;&gt; &lt;b&gt;nil&lt;/b&gt;, '&lt;/span&gt;未設定欲實體化的 &lt;span style="font-family:Courier New;"&gt;Form &lt;/span&gt;類別名稱&lt;span style="font-family:Courier New;"&gt;!');&lt;br /&gt;   FForm := g_ConcreteClass.Create(Application);&lt;br /&gt;   FForm.MainFormHandle := hMainForm;&lt;br /&gt; &lt;b&gt;end&lt;/b&gt;;&lt;br /&gt; Result := FForm.Handle;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;procedure&lt;/b&gt; TPlugin.DestroyForm;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; FForm &lt;&gt; &lt;b&gt;nil&lt;/b&gt; &lt;b&gt;then&lt;/b&gt;&lt;br /&gt; &lt;b&gt;begin&lt;/b&gt;&lt;br /&gt;   FForm.Release;&lt;br /&gt;   FForm := &lt;b&gt;nil&lt;/b&gt;;&lt;br /&gt; &lt;b&gt;end&lt;/b&gt;;&lt;br /&gt; Application.ProcessMessages;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;function&lt;/b&gt; TPlugin.ShowModalForm: Integer;&lt;br /&gt;&lt;b&gt;begin&lt;/b&gt;&lt;br /&gt; &lt;b&gt;if&lt;/b&gt; FForm = &lt;b&gt;nil&lt;/b&gt; &lt;b&gt;then&lt;/b&gt;&lt;br /&gt;   &lt;b&gt;raise&lt;/b&gt; Exception.Create('DllExoprt: &lt;/span&gt;視窗尚未建立&lt;span style="font-family:Courier New;"&gt;!');&lt;br /&gt; Result := FForm.ShowModal;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;initialization&lt;/b&gt;&lt;br /&gt; g_DllAppHandle := Application.Handle;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;end&lt;/b&gt;.&lt;/span&gt;&lt;/pre&gt;     &lt;/td&gt;   &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;　&lt;/p&gt;           &lt;h3&gt;範例程式&lt;/h3&gt;           &lt;p&gt;範例程式可以按此處下載：&lt;a href="http://sun.cis.scu.edu.tw/%7Enms9115/articles/delphi/PluginDLL/PluginDLL.zip"&gt;PluginDLL.zip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;下載壓縮檔並解開後，請先閱讀其中的 readme.txt。&lt;/p&gt;                      &lt;h3&gt;可改進之處&lt;/h3&gt;               &lt;p&gt; 你可以試著修改範例程式並強化它，使它可以當作實際開發專案的基礎框架，以下列出幾項可能的改進之處：&lt;/p&gt; &lt;ul&gt;&lt;li&gt;賦予 TBaseForm                  基本的資料處理能力，像是新增、修改、刪除...等。&lt;br /&gt;  &lt;/li&gt;&lt;li&gt;修改使之適用於 modeless form 及 MDI                  應用程式。這意味著釋放 DLL                  的時機也會改變，你可能會需要一個串列結構將載入的 DLL                  記錄起來，通常一個 TStringList 就可以做到。&lt;br /&gt;             &lt;/li&gt;&lt;li&gt;讓一個 plugin 物件可以建立並維護多個不同類型的 Form                物件。&lt;/li&gt;&lt;/ul&gt; &lt;blockquote&gt;   &lt;p&gt;你可能會希望一個 DLL 裡面可以提供多種 form             物件供主程式使用，這些 form           物件之間可能有某種程度的相似或相依關係。根據此需求我們可以整理出            plugin 物件具備以下兩個特性：&lt;/p&gt;            &lt;ol&gt;&lt;li&gt;plugin 物件可以建立多種不同類型的 form                物件，而它們都是繼承自基礎的表單類別 TBaseForm。&lt;/li&gt;&lt;li&gt;一個 DLL 裡面只需要一個 plugin 物件。&lt;/li&gt;&lt;/ol&gt;   &lt;p&gt;根據  [GHJV95] 書中的定義，&lt;span style="color:#ff00ff;"&gt;Abstract Factory&lt;/span&gt;           的用意是：&lt;/p&gt;           &lt;p&gt;&lt;span style="color:#000080;"&gt;「提供一個介面來建立同一族系或相依的物件，而毋須指明它們的具象類別（concrete           class）」&lt;/span&gt;&lt;/p&gt;    &lt;p&gt;而 Factory 通常也被實作成 Singleton，這些特性清楚地告訴我們           plugin 物件非常適合實作成一個 Factory。你可能需要在 TPlugin           類別裡面提供一個 RegisterClass           方法，這個方法取代了原先的類別參考型態，原本在           TBaseForm 子類別的單元裡設定 g_ConcreteClass 的敘述將會改成：&lt;/p&gt;          &lt;pre&gt;  &lt;span style="font-family:Courier New;"&gt;PluginFactory.RegisterClass(TForm1);&lt;/span&gt;&lt;/pre&gt;    &lt;p&gt;註冊過的類別資訊將會被記錄在一個串列裡面。主程式則可以在建立           form 物件時透過字串來指定要建立的 form           類別名稱，像這樣：&lt;/p&gt;    &lt;pre&gt;  &lt;span style="font-family:Courier New;"&gt;APlugin.CreateForm('TCustomerForm');&lt;/span&gt;&lt;/pre&gt;    &lt;p&gt;plugin 物件的 CreateForm          方法就會到串列中搜尋註冊過的類別，取得對應的類別參考並建立其實體（是不是有點像          COM 所做的事情？）。&lt;/p&gt;          &lt;p&gt;嗯，我想這樣的提示應該夠了，最重要的還是要自己實際去撰寫及除錯程式碼以獲得更深刻的體會，真能如此，這個          Design Pattern          就會完全融入你的知識體系裡面，以後不加思索便可以運用自如了。&lt;/p&gt;  &lt;/blockquote&gt; &lt;h2&gt; 結語&lt;/h2&gt;               &lt;p&gt;在這份文件裡面主要是介紹以 Delphi 來設計 plugin     模組的實作過程，其中運用了介面程式設計的技巧（包括介面的參考計數以及物件生命週期的控制）以及      Design Patterns    來解決設計時遭遇的問題，這也是學習的重點之一。&lt;/p&gt;       &lt;p&gt;在一個多人開發的專案裡，如果您的責任是設計主程式框架，當您要以 DLL    來切割應用程式時會怎麼做呢？這篇文章裡面展示了一種可能的設計方式，如果您有不同的想法或者對本文有任何建議，都很歡迎您來信指教。&lt;/p&gt; &lt;h3&gt; Delphi 的 DLL 記憶體漏洞&lt;/h3&gt;                       &lt;p&gt; 最後，雖然不是本文的主題，但也頗值得注意的，就是動態載入的 DLL 在釋放時會有 4K 的記憶體漏洞，而且 Delphi 5 和 6       都有這個問題，你可以閱讀下面兩份文件，其中有詳細的說明並提供解決之道：&lt;/p&gt;                  &lt;ul&gt;&lt;li&gt;Memory Lost And Found...And Release by Roy Nelson.&lt;br /&gt;                            &lt;a href="http://www.thedelphimagazine.com/samples/1328/1328.htm" target="_blank"&gt;      http://www.thedelphimagazine.com/samples/1328/1328.htm&lt;/a&gt;&lt;/li&gt;&lt;li&gt;VCL leak fix for dynamic DLLs by Dejan Maksimovic.&lt;br /&gt;         &lt;a href="http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16380" target="_blank"&gt;      http://codecentral.borland.com/codecentral/ccweb.exe/listing?id=16380&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;　&lt;/p&gt; &lt;table border="0" height="160" width="100%"&gt;   &lt;tbody&gt;&lt;tr&gt;     &lt;td height="74" valign="top" width="5%"&gt; &lt;a name="註1"&gt;註1&lt;/a&gt;. &lt;p&gt;　&lt;/p&gt;     &lt;/td&gt;     &lt;td height="74" width="95%"&gt; 由於 DLL 版本的更新可能使得原本叫用它的程式無法正常運作，因此以不同的檔名區分版本（例如：MFCxx.DLL），使得硬碟裡面必須保存同一種 DLL 的多個版本，即使使用者將應用程式移除了，卻不敢放心的移除相關的 DLL 檔案，以免其他應用程式因為缺少了這個檔案而無法運作，這種情況所形成的問題稱為 DLL hell。COM 的出現有解決此問題的企圖（透過執行時期詢問元件支援的介面），但似乎並不理想，直到 .NET 的問世而終於有了比較好的解決方案。 &lt;/td&gt;    &lt;/tr&gt;   &lt;tr&gt;     &lt;td height="54" valign="top" width="5%"&gt; &lt;a name="註2"&gt;註2&lt;/a&gt;.     &lt;/td&gt;     &lt;td height="54" width="95%"&gt; 可以到 &lt;a href="http://www.geocities.com/huanlin_tsai/" target="_blank"&gt; http://www.geocities.com/huanlin_tsai/&lt;/a&gt;                           的〔心得分享〕區找到相關文章。不可諱言，以上所說的難免摻雜了個人的因素，也許其他人在使用 package 時並未發生上述問題，而且使用 package                          的方式也有許多優點，在此僅將個人實際應用時的狀況與感覺描述出來，若有謬誤之處尚請各方不吝指正。&lt;/td&gt;       &lt;/tr&gt;   &lt;tr&gt;     &lt;td height="20" valign="top" width="5%"&gt; &lt;a name="註3"&gt;註3&lt;/a&gt;. &lt;/td&gt;     &lt;td height="20" width="95%"&gt; Singleton                   樣式：提供單一窗口來建立類別的實體，以確保只有一個類別的實體存在。參考        [GHJV95] 的書。&lt;/td&gt;                  &lt;/tr&gt; &lt;/tbody&gt;&lt;/table&gt; &lt;h2&gt;參考資料&lt;/h2&gt;              &lt;ul&gt;&lt;li&gt;Delphi 學習筆記。作者：錢達智。碁峰資訊，1998。&lt;/li&gt;&lt;li&gt;[Cantu2001] Marco Cantu. Mastering Delphi 6. SYBEX, 2001.&lt;/li&gt;&lt;li&gt;[Harmon2000] Eric Harmon. Delphi COM Programming. MTP, 2000.&lt;/li&gt;&lt;li&gt;[GHJV95] E. Gamma, R. Helm, R. Johnson, J. Vlissides. Design Patterns: Elements of Reusable Object-Oriented Software. Addison-Wesley, 1995. 中文版：物件導向設計模式，葉秉哲。培生，2001。&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;  &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-4902153282397382324?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/4902153282397382324/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=4902153282397382324' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4902153282397382324'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4902153282397382324'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/04/dll.html' title='DLL 應用 - 設計可抽換的模組'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-4607852861407102256</id><published>2008-04-26T16:00:00.001+08:00</published><updated>2008-04-26T16:00:56.054+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><title type='text'>Implementing Plug-Ins for Your Delphi Applications</title><content type='html'>&lt;h1&gt;&lt;a href="http://www.uil.net/uArticles/ImplementingPluginsforyou.html"&gt;Implementing Plug-Ins for Your Delphi Applications&lt;/a&gt;&lt;/h1&gt; &lt;p&gt;&lt;b&gt;By Tim Sullivan - &lt;a href="mailto:tim@uil.net"&gt;tim@uil.net&lt;/a&gt;&lt;/b&gt;  &lt;/p&gt;&lt;p&gt;Back in January, 1999, Delphi Informant ran an article on developing plugins for your Delphi applications. It covered some of the basics of that plugins are, how to make them, exporting fucntions, and so on. I was tremendously inspired, because a system I was (and still am) working on could (and did!) benefit greatly from such a technology. &lt;/p&gt;&lt;p&gt;However, the layout that was described had some pretty big flaws. First, it wasn't really OOP. Second, it was a little hairy to pass information back and forth. Finally, you had to write a lot of the initialization stuff yourself. There had to be a better way. &lt;/p&gt;&lt;p&gt;A quick overview of what a plugin is: Plugins are DLL files. They contain additional commands or other functionality that can add to your system. Often they add menu items or toolbuttons to your application. Simply the existance of a file can radically enhance your software. &lt;/p&gt;&lt;p&gt;There was. Step 1 was to create an abstract, base class for a plugin. The plugin should know a bit about the application (for example, having a copy of the Application variable could be useful). It should know a bit about itself: how many "commands" it has, what the name of the plugin was, the author, etc. After some fuddling, this is what I came up with: &lt;/p&gt;&lt;pre&gt;type&lt;br /&gt;   TuilPlugin = class(TObject)&lt;br /&gt;   private&lt;br /&gt;      FHostApplication : TApplication;&lt;br /&gt;      FFilename        : string;&lt;br /&gt;      FManager         : TComponent;&lt;br /&gt;   protected&lt;br /&gt;      { Protected declarations }&lt;br /&gt;   public&lt;br /&gt;      { Public declarations }&lt;br /&gt;      constructor Create;&lt;br /&gt;      destructor Destroy; override;&lt;br /&gt;      function GetAuthor : String; virtual; stdcall;&lt;br /&gt;      function GetDescription : String; virtual; stdcall;&lt;br /&gt;      function GetName : String; virtual; stdcall;&lt;br /&gt;      function Initialize(Manager : TComponent; HostApplication : TApplication; Filename : string) : Boolean; virtual; stdcall;&lt;br /&gt;      function GetNumCommands : Integer; virtual; stdcall;&lt;br /&gt;      procedure GetCommand(index : integer; var Caption, Hint, Data : string; var Bitmap : HBitmap; var Event : TNotifyEvent); virtual; stdcall;&lt;br /&gt;      procedure Configure; virtual; stdcall;&lt;br /&gt;&lt;br /&gt;      { properties }&lt;br /&gt;      property HostApplication : TApplication read FHostApplication;&lt;br /&gt;      property Filename : string read FFilename;&lt;br /&gt;      property Manager : TComponent read FManager;&lt;br /&gt;   end;  { TuilPlugin }&lt;/pre&gt;Most of the methods and properties are self explanatory. Each plugin publishes a number of commands (how many is returned by GetNumCommands). To get information about a specific command, a call to GetCommand will give you the command's caption, bitmap, hint and event. Notice the &lt;b&gt;stdcall&lt;/b&gt; after each of the methods. This is required by the dll in order for it to work properly.  &lt;p&gt;The second thing that needed to be done was to develop a loader component, which would take care of all the drudgery of creating, initializing, destroying and generally managing the plugins. Here's what I came up with: &lt;/p&gt;&lt;pre&gt;   TuilPluginManager = class(TComponent)&lt;br /&gt;   private&lt;br /&gt;      // Private declarations&lt;br /&gt;      FExtension       : String;&lt;br /&gt;      FPlugins         : TList;&lt;br /&gt;      FOnBeforeLoading : TNotifyEvent;&lt;br /&gt;      FOnAfterLoading  : TNotifyEvent;&lt;br /&gt;      FOnBeforeLoad    : TuilBeforeLoadEvent;&lt;br /&gt;      FOnAfterLoad     : TuilAfterLoadEvent;&lt;br /&gt;      FOnNewCommand    : TNewCommandEvent;&lt;br /&gt;   protected&lt;br /&gt;   [...]&lt;br /&gt;   public&lt;br /&gt;      // Public declarations&lt;br /&gt;      constructor Create(AOwner : TComponent); override;&lt;br /&gt;      destructor Destroy; override;&lt;br /&gt;      procedure LoadPlugin(Filename : string); virtual;&lt;br /&gt;      procedure LoadPlugins; virtual;&lt;br /&gt;      procedure UnloadPlugin(index : integer); virtual;&lt;br /&gt;      procedure GetLoadedPlugins(PluginList : TStrings); virtual;&lt;br /&gt;      property Plugins[index : integer] : TuilPlugin read GetPlugins; default;  // Public&lt;br /&gt;      property PluginCount : integer read GetPluginCount;&lt;br /&gt;   published&lt;br /&gt;      // Published properties and events&lt;br /&gt;      property Extension : String read GetExtension write SetExtension;  // Published&lt;br /&gt;      property Version : string read GetVersion write SetVersion;&lt;br /&gt;      property OnBeforeLoading : TNotifyEvent read FOnBeforeLoading write FOnBeforeLoading;&lt;br /&gt;      property OnAfterLoading : TNotifyEvent read FOnAfterLoading write FOnAfterLoading;&lt;br /&gt;      property OnBeforeLoad : TuilBeforeLoadEvent read FOnBeforeLoad write FOnBeforeLoad;&lt;br /&gt;      property OnAfterLoad : TuilAfterLoadEvent read FOnAfterLoad write FOnAfterLoad;&lt;br /&gt;      property OnNewCommand : TNewCommandEvent read FOnNewCommand write FOnNewCommand;&lt;br /&gt;   end;  // TuilPluginManager&lt;/pre&gt;The main meat procedure here is &lt;b&gt;LoadPlugin&lt;/b&gt;. It handles the actual loading and initialization of a plugin. LoadPlugins is useful as well, since it globally loads all the plugins in the application's folder. &lt;p&gt;All this is well and good, but how the heck do we make our OWN plugins? Actually, it's really simple.  &lt;/p&gt;&lt;p&gt;First, you want to create a descendant of the TuilPlugin class. Include (private) event handlers for each of the commands you want to export. &lt;/p&gt;&lt;pre&gt;type&lt;br /&gt;   TMyPlugin = class(TuilMyPlugin)&lt;br /&gt;      procedure Command1(Sender : TObject);&lt;br /&gt;      procedure Command2(Sender : TObject);&lt;br /&gt;   public&lt;br /&gt;      function GetAuthor : String; override; stdcall;&lt;br /&gt;      function GetDescription : String; override; stdcall;&lt;br /&gt;      function GetName : String; override; stdcall;&lt;br /&gt;      function Initialize(Manager : TComponent; HostApplication : TApplication; Filename : string) : Boolean; override; stdcall;&lt;br /&gt;      function GetNumCommands : Integer; override; stdcall;&lt;br /&gt;      procedure GetCommand(index : integer; var Caption, Hint, Data : string; var Bitmap : HBitmap; var Event : TNotifyEvent); override; stdcall;&lt;br /&gt;      procedure Configure; override; stdcall;&lt;br /&gt;   end;&lt;/pre&gt;The two most important methods you override are GetNumCommands and GetCommand. GetNumCommands is easy. In this case, we've got 2 commands we're exporting: &lt;pre&gt;function TMyPlugin.GetNumCommands : integer;&lt;br /&gt;begin&lt;br /&gt;   Result := 2;&lt;br /&gt;end;&lt;/pre&gt;GetCommand is a little trickier. You need to determine what command number you're getting, and return the appropriate information and event handler: &lt;pre&gt;procedure TupSamplePlugin.GetCommand(index : integer; var Caption, Hint, Data : string; var Bitmap : HBitmap; var Event : TNotifyEvent);&lt;br /&gt;begin&lt;br /&gt;  Caption := '';&lt;br /&gt;  Event := nil;&lt;br /&gt;  case index of&lt;br /&gt;    0 : begin&lt;br /&gt;           Caption := 'Command One';&lt;br /&gt;           Hint := 'Command One';&lt;br /&gt;           Data := '';&lt;br /&gt;           Event := CommandOne;&lt;br /&gt;                   Bitmap := 0;&lt;br /&gt;         end;&lt;br /&gt;    1 : begin&lt;br /&gt;           Caption := 'Command Two';&lt;br /&gt;           Hint := 'Command Two';&lt;br /&gt;           Data := '';&lt;br /&gt;           Event := CommandTwo;&lt;br /&gt;                   Bitmap := 0;&lt;br /&gt;         end;&lt;br /&gt;  end;&lt;br /&gt;end;&lt;/pre&gt;That's most of it, believe it or not. We have to export a RegisterPlugin procedure with our dll, and include ShareMem as the first unit in both the DLL and our application's .DPR files. &lt;p&gt;Because there is so much to make sure you do (Sharemem, stdcall, RegisterPlugin, and so on), I put together a Wizard that would make things a lot easier. &lt;/p&gt;&lt;p&gt;I've included the &lt;a href="http://www.uil.net/LIBS/uPlugin40.zip"&gt;complete source code&lt;/a&gt; for the system, including the wizard, available for free. If you are using Delphi 3, there is different code which you can get by &lt;a href="http://www.uil.net/LIBS/uPluginD3.zip"&gt;clicking here&lt;/a&gt;. Feel free to play with it and let me know what you think. I'm hoping that we can continue to improve the system as a community. Comments are welcome! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-4607852861407102256?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/4607852861407102256/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=4607852861407102256' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4607852861407102256'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4607852861407102256'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/04/implementing-plug-ins-for-your-delphi.html' title='Implementing Plug-Ins for Your Delphi Applications'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-5947231658329775778</id><published>2008-04-25T23:27:00.000+08:00</published><updated>2008-04-25T23:28:06.772+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='Interface'/><title type='text'>Delphi Basics: Interface command</title><content type='html'>&lt;a href="http://www.delphibasics.co.uk/RTL.asp?Name=Interface"&gt;The &lt;span style="color:#996600;"&gt;&lt;b&gt;Interface&lt;/b&gt;&lt;/span&gt; keyword is used in two different ways. &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;&lt;b&gt;Version 1&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;It starts the definition of external interface of a Unit. Declarations here are externally visible by other units. All of these declarations must be implemented in the &lt;b&gt;Implementation&lt;/b&gt; section.&lt;br /&gt;&lt;br /&gt;The &lt;b&gt;Uses&lt;/b&gt; statement, if present, must be at the start.&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff0000;"&gt;&lt;b&gt;Version 2&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;In Object Oriented programming, we often use &lt;b&gt;Abstract&lt;/b&gt; class methods in a base class as a placeholder. All derived classes must implement these methods.&lt;br /&gt;&lt;br /&gt;Taking this one step further, an Interface defines a grouping of just abstract properties and methods. It provides a template for a class to use to ensure consistency. It is like a class with only abstract methods. It has the benefits that classes can be based on one parent class, and implement one or more interfaces. It adds a predictable flavour of operation to each class that implements the interface.&lt;br /&gt;&lt;br /&gt;Take a look at the Delphi tutorial for more on this complex subject.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-5947231658329775778?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/5947231658329775778/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=5947231658329775778' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5947231658329775778'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5947231658329775778'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/04/delphi-basics-interface-command.html' title='Delphi Basics: Interface command'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-5559821784987352439</id><published>2008-04-25T22:57:00.000+08:00</published><updated>2008-04-25T22:58:34.422+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='delphi'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><title type='text'>Delphi Plugin Technology</title><content type='html'>Delphi 插件（Plug-ins）创建、调试与使用应用程序扩展（续）&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;        有没有使用过Adobe Photoshop？如果用过，你就会对插件的概念比较熟悉。对外行人来说，插件仅仅是从外部提供给应用程序的代码块而已（举个例子来说，在一个DLL中）。一个插件和一个普通DLL之间的差异在于插件具有扩展父应用程序功能的能力。例如，Photoshop本身并不具备进行大量的图像处理功能。插件的加入使其获得了产生诸如模糊、斑点，以及其他所有风格的奇怪效果，而其中任何一项功能都不是父应用程序自身所具有的。&lt;br /&gt;对于图像处理程序来说这很不错，可是为什么要花偌大的力气去完成支持插件的商业应用程序呢？假设，我们举个例子，你的应用程序要产生一些报表。你的客户肯定会一直要求更新或者增加新的报表。你可以使用一个诸如Report Smith的外部报表生成器，这是个不怎么样的解决方案，需要发布附加的文件，要对用户进行额外的培训，等等。你也可以使用QuickReport，不过这会使你身处版本控制的噩梦之中——如果每改变一次字体你就要Rebuild你的应用程序的话。&lt;br /&gt;         然而，只要你把报表做到插件中，你就可以使用它。需要一个新的报表吗？没问题，只要安装一个DLL，下次应用程序启动时就会看见它了。另外一个例子是处理来自外部设备（比如条形码扫描器）的数据的应用程序，为了给用户更多的选择，你不得不支持半打的各种设备。通过将每种设备接口处理例程写成插件，不用对父应用程序作任何变动就可以获得最大程度的可伸缩性。&lt;br /&gt;&lt;br /&gt;入门&lt;br /&gt;&lt;br /&gt;        在开始写代码之前最重要的事情就是搞清楚你的应用程序到底需要扩展哪些功能。这是因为插件是通过一个特定的接口与父应用程序交互的，而这个接口将根据你的需要来定义。在本文中，我们将建立3个插件，以便展示插件与父应用程序相交互的几种方式。&lt;br /&gt;        我们将把插件制作成DLL。不过，在做这项工作之前，我们得先制作一个外壳程序来载入和测试它们。显示的是加载了第一个插件以后的测试程序。第一个插件没有完成什么大不了的功能，实际上，它所做的只是返回一个描述自己的字符串。不过，它证明了很重要的一点——不管有没有插件应用程序都可以正常运行。如果没有插件，它就不会出现在已安装的插件列表中，但是应用程序仍然可以正常的行使功能。&lt;br /&gt;&lt;br /&gt;        我们的插件外壳程序与普通应用程序之间的唯一不同就在于工程源文件中出现在uses子句中的Sharemem单元和加载插件文件的代码。任何在自身与子DLL之间传递字符串参数的应用程序都需要Sharemem单元，它是DelphiMM.dll（Delphi提供该文件）的接口。要测试这个外壳，需要将DelphiMM.dll文件从Delphi\Bin目录复制到path环境变量所包含的路径或者应用程序所在目录中。发布最终版本时也需要同时分发该文件。&lt;br /&gt;        插件通过LoadPlugins过程载入到这个测试外壳中，这个过程在主窗口的FormCreate事件中调用。该过程使用FindFirst和FindNext函数在应用程序所在目录中查找插件文件。找到一个文件以后，就使用图3所示的LoadPlugins过程将其载入。&lt;br /&gt;{ 在应用程序目录下查找插件文件 }&lt;br /&gt;procedure TfrmMain.LoadPlugins; &lt;br /&gt;var &lt;br /&gt;  sr:     TSearchRec; &lt;br /&gt;  path:   string;&lt;br /&gt;  Found: Integer; &lt;br /&gt;begin&lt;br /&gt;  path := ExtractFilePath(Application.Exename); &lt;br /&gt;   try&lt;br /&gt;    Found := FindFirst(path + cPLUGIN_MASK, 0, sr); &lt;br /&gt;     while Found = 0 do begin&lt;br /&gt;      LoadPlugin(sr); &lt;br /&gt;      Found := FindNext(sr); &lt;br /&gt;     end;&lt;br /&gt;   finally&lt;br /&gt;    FindClose(sr); &lt;br /&gt;   end;&lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;{ 加载指定的插件 DLL. }&lt;br /&gt;procedure TfrmMain.LoadPlugin(sr: TSearchRec); &lt;br /&gt;var &lt;br /&gt;  Description:   string;&lt;br /&gt;  LibHandle:     Integer; &lt;br /&gt;  DescribeProc: TPluginDescribe; &lt;br /&gt;begin&lt;br /&gt;  LibHandle := LoadLibrary(Pchar(sr.Name)); &lt;br /&gt;   if LibHandle &lt;&gt; 0 then&lt;br /&gt;   begin&lt;br /&gt;    DescribeProc := GetProcAddress(LibHandle, &lt;br /&gt;                                   cPLUGIN_DESCRIBE); &lt;br /&gt;     if Assigned(DescribeProc) then&lt;br /&gt;       begin&lt;br /&gt;        DescribeProc(Description); &lt;br /&gt;        memPlugins.Lines.Add(Description); &lt;br /&gt;       end&lt;br /&gt;     else&lt;br /&gt;       begin&lt;br /&gt;        MessageDlg('File "' + sr.Name +&lt;br /&gt;'" is not a valid plug-in.', &lt;br /&gt;          mtInformation, [mbOK], 0); &lt;br /&gt;       end;&lt;br /&gt;   end&lt;br /&gt;   else&lt;br /&gt;    MessageDlg('An error occurred loading the plug-in "' +&lt;br /&gt;      sr.Name + '".', mtError, [mbOK], 0); &lt;br /&gt;end;&lt;br /&gt;&lt;br /&gt;        LoadPlugin方法展示了插件机制的核心。首先，插件被写成DLL。其次，通过LoadLibrary API它被动态的加载。一旦DLL被加载，我们就需要一个访问它所包含的过程和函数的途径。API调用GetProcAddress提供这种机制，它返回一个指向所需例程的指针。在我们这个简单的演示中，插件仅仅包含一个名为DescribePlugin的过程，由常数cPLUGIN_DESCRIBE指定（过程名的大小写非常重要，传递到GetProcAddress的名称必须与包含在DLL中的例程名称完全一致）。如果在DLL中没有找到请求的例程，GetProcAddree将返回nil，这样就允许使用Assigned函数测定返回值。&lt;br /&gt;        为了以一种易用的方式存储指向一个函数的指针，有必要为用到的变量创建一个特定的类型。注意，GetProcAddress的返回值被存储在一个变量中，DescribeProc，属于TpluginDescribe类型。下面是它的声明：&lt;br /&gt;type &lt;br /&gt;  TPluginDescribe = procedure(var Desc: string); stdcall;&lt;br /&gt;        由于过程存在于DLL内部，它通过标准调用转换编译所有导出例程，因此需要使用stdcall指示字。这个过程使用一个var参数，当过程返回的时候它包含插件的描述。&lt;br /&gt;        要调用刚刚获得的过程，只需要使用保存地址的变量作为过程名，后面跟上任何参数。就我们的例子而言，声明：&lt;br /&gt;DescribeProc(Description)&lt;br /&gt;将会调用在插件中获得的描述过程，并且用描述插件功能的字符串填充Description变量。&lt;br /&gt;&lt;br /&gt;构造插件&lt;br /&gt;&lt;br /&gt;        我们已经创建好了父应用程序，现在该轮到创建我们希望加载的插件了。插件文件是一个标准的Delphi DLL，所以我们从Delphi IDE中创建一个新DLL工程，保存它。由于导出的插件函数将用到字符串参数，所以要在工程的uses子句中把Sharemen单元放在最前面。列出的就是我们这个简单插件的工程源文件。&lt;br /&gt;uses&lt;br /&gt;  Sharemem, SysUtils, Classes, &lt;br /&gt;  main in 'main.pas'; &lt;br /&gt;  &lt;br /&gt;{$E plg.} &lt;br /&gt;  &lt;br /&gt;exports&lt;br /&gt;  DescribePlugin; &lt;br /&gt;  &lt;br /&gt;begin&lt;br /&gt;  &lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;        虽然插件是一个DLL文件，但是没有必要一定要给它一个.DLL的扩展名。实际上，一个原因就足以让我们有理由改变扩展名：当父应用程序寻找要加载的文件时，新的扩展名可以作为特定的文件掩模。通过使用别的扩展名（我们的例子使用了*.plg），你可以在一定程度上确信应用程序只会载入相应的文件。编译指示字$X可以实现这个改变，也可以通过Project Options对话框的Application页来设置扩展名。&lt;br /&gt;        第一个例子插件的代码是很简单的。显示了包含在一个新单元中的代码。注意，DescribePlugin原型与外壳应用程序中的TpluginDescribe类型相一致，使用附加的export保留字指定该过程将被导出。被导出的过程名称也将会出现在主工程源代码的exports段中（在中列出）。&lt;br /&gt;unit main; &lt;br /&gt;  &lt;br /&gt;interface&lt;br /&gt;  &lt;br /&gt;  procedure DescribePlugin(var Desc: string);&lt;br /&gt;     export; stdcall;&lt;br /&gt;  &lt;br /&gt;implementation&lt;br /&gt;  &lt;br /&gt;procedure DescribePlugin(var Desc: string);&lt;br /&gt;begin&lt;br /&gt;  Desc := 'Test plugin v1.00'; &lt;br /&gt;end;&lt;br /&gt;  &lt;br /&gt;end.&lt;br /&gt;&lt;br /&gt;        在测试这个插件之前，要先把它复制到主应用程序的路径下。最简单的办法就是在主目录的子目录下创建插件，然后把输出路径设置为主路径（Project Options对话框的Directories/Conditionals也可以作这个设置）。&lt;br /&gt;&lt;br /&gt;调试&lt;br /&gt;&lt;br /&gt;        现在介绍一下Delphi 3中一个较好的功能：从IDE中调试DLL的能力。在DLL工程中可以通过Run paramaters对话框指定某程序为宿主应用程序，这就是指向将调用DLL的应用程序的路径（在我们这个例子中，就是刚刚创建的测试外壳程序）。然后你就可以在DLL代码中设置断点并且按F9运行它——就像在一个普通应用程序中做的那样。Delphi会运行指定的宿主程序，并且，通过编译带有调试信息的DLL，把你指引到DLL代码内的断点处。&lt;br /&gt;//////////////////////////////////////////////////////////////////////&lt;br /&gt;Delphi 插件（Plug-ins）创建、调试与使用应用程序扩展（续）&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;作者：不详&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;文章来源：China ASP&lt;br /&gt;上一篇 下一篇  &lt;br /&gt; 相关文档：&lt;br /&gt;&lt;br /&gt;Delphi 插件（Plug-ins）创建、调试与使用应用程序扩展&lt;br /&gt;&lt;br /&gt;--------------------------------------------------------------------------------&lt;br /&gt;延伸父应用&lt;br /&gt;&lt;br /&gt;这个简单的插件不错，不过它不能做什么有用的事情。第二个例子就是纠正这个问题。这个插件的目标就是在父应用程序的主菜单中加入一个项目。这个菜单项目，当被单击时，就会执行插件内的一些代码。显示外壳程序的改进版，两个插件都已经加载。在这个版本的外壳程序中，一个名为Plug-in的新菜单项目，被添加到主菜单中。插件会在运行时加入一个菜单项。&lt;br /&gt;&lt;br /&gt;  为了实现这个目的，我们必须在插件DLL中定义第二个接口。现有的DLL只导出了一个过程，DescribePlugin。第二个插件将声明一个叫做InitPlugin的过程。不过，在这个过程可以在主应用程序中看到以前，必须修改LoadPlugin来配合它。&lt;br /&gt;所示的代码展示了改进的过程。&lt;br /&gt;procedure TfrmMain.LoadPlugin(sr: TSearchRec); &lt;br /&gt;var &lt;br /&gt;  Description:   string;&lt;br /&gt;  LibHandle:     Integer; &lt;br /&gt;  DescribeProc: TPluginDescribe; &lt;br /&gt;  InitProc:      TPluginInit; &lt;br /&gt;begin&lt;br /&gt;  LibHandle := LoadLibrary(Pchar(sr.Name)); &lt;br /&gt;   if LibHandle &lt;&gt; 0 then&lt;br /&gt;   begin&lt;br /&gt;     // 查找 DescribePlugin. &lt;br /&gt;    DescribeProc := GetProcAddress(LibHandle, &lt;br /&gt;                                   cPLUGIN_DESCRIBE); &lt;br /&gt;     if Assigned(DescribeProc) then&lt;br /&gt;     begin&lt;br /&gt;       // 调用 DescribePlugin. &lt;br /&gt;       DescribeProc(Description); &lt;br /&gt;      memPlugins.Lines.Add(Description); &lt;br /&gt;       // 查找 InitPlugin. &lt;br /&gt;      InitProc := GetProcAddress(LibHandle, cPLUGIN_INIT); &lt;br /&gt;       if Assigned(InitProc) then&lt;br /&gt;       begin&lt;br /&gt;        // 调用 InitPlugin. &lt;br /&gt;        InitProc(mnuMain); &lt;br /&gt;       end;&lt;br /&gt;     end&lt;br /&gt;     else&lt;br /&gt;     begin&lt;br /&gt;      MessageDlg('File "' + sr.Name +&lt;br /&gt;        '" is not a valid plugin.', &lt;br /&gt;        mtInformation, [mbOK], 0); &lt;br /&gt;     end;&lt;br /&gt;   end&lt;br /&gt;   else&lt;br /&gt;   begin&lt;br /&gt;    MessageDlg('An error occurred loading the plugin "' +&lt;br /&gt;      sr.Name + '".', mtInformation, [mbOK], 0); &lt;br /&gt;   end;&lt;br /&gt;end;&lt;br /&gt;  如你所见，当GetProcAddress第一次查找调用描述过程之后，又调用了一次GetProcAddress。这一次，我们要寻找的是常量cPLUGIN_INIT，定义如下：&lt;br /&gt;const&lt;br /&gt;  cPLUGIN_INIT = 'InitPlugin';&lt;br /&gt;返回值存储在TpluginInit类型的变量中，定义如下：&lt;br /&gt;type&lt;br /&gt;  TPluginInit = procedure(ParentMenu: TMainMenu); stdcall;&lt;br /&gt;当InitPlugin方法被执行时，父应用程序的主菜单被当作一个参数传递给它。这个过程可以按照自己的意愿修改菜单。由于所有GetProcAddress的返回值都用assigned测试，新版本的LoadPlugin过程仍然会加载不包含InitPlugin过程的第一个插件。在这个过程中第一次调用寻找DescribePlugin方法会通过，第二次寻找InitPlugin会无响应失败。&lt;br /&gt;  现在新的接口已经定义好了，可以为新的InitPlugin方法编写代码了。像原先一样，新插件的实现代码存在于一个单独的单元中。显示了修改过的包含InitPlugin方法的main.pas。&lt;br /&gt;unit main; &lt;br /&gt;  &lt;br /&gt;interface&lt;br /&gt;  &lt;br /&gt;uses Dialogs, Menus; &lt;br /&gt;  &lt;br /&gt;type&lt;br /&gt;  THolder = class&lt;br /&gt;   public&lt;br /&gt;     procedure ClickHandler(Sender: TObject); &lt;br /&gt;   end;&lt;br /&gt;  &lt;br /&gt;  procedure DescribePlugin(var Desc: string);&lt;br /&gt;     export; stdcall;&lt;br /&gt;  procedure InitPlugin(ParentMenu: TMainMenu); &lt;br /&gt;     export; stdcall;&lt;br /&gt;  &lt;br /&gt;var&lt;br /&gt;  Holder: THolder; &lt;br /&gt;  &lt;br /&gt;implementation&lt;br /&gt;  &lt;br /&gt;procedure DescribePlugin(var Desc: string);&lt;br /&gt;begin&lt;br /&gt;  Desc := 'Test plugin 2 - Menu test'; &lt;br /&gt;end;&lt;br /&gt;  &lt;br /&gt;procedure InitPlugin(ParentMenu: TMainMenu); &lt;br /&gt;var&lt;br /&gt;  i: TMenuItem; &lt;br /&gt;begin&lt;br /&gt;   // 创建新菜单项. &lt;br /&gt;  i := NewItem('Plugin &amp;amp;Test', scNone, False, True, &lt;br /&gt;               Holder.ClickHandler, 0, 'mnuTest'); &lt;br /&gt;  ParentMenu.Items[1].Add(i); &lt;br /&gt;end;&lt;br /&gt;  &lt;br /&gt;procedure THolder.ClickHandler; &lt;br /&gt;begin&lt;br /&gt;  ShowMessage('Clicked!'); &lt;br /&gt;end;&lt;br /&gt;  &lt;br /&gt;initialization&lt;br /&gt;  Holder := THolder.Create; &lt;br /&gt;  &lt;br /&gt;finalization&lt;br /&gt;  Holder.Free; &lt;br /&gt;  &lt;br /&gt;end.&lt;br /&gt;第二个插件的代码&lt;br /&gt;  很明显，对原始插件的第一个改变就是增加了InitPlugin过程。像原先一样，带有export关键字的原型被加入到单元顶端的列表中，过程名也被加入到工程源代码的exports子句列表中。这个过程使用NewItem函数创建一个新的菜单项，返回值是TmenuItem对象。新菜单项通过下列语句被加入到应用程序主菜单中：&lt;br /&gt;ParentMenu.Items[1].Add(I);&lt;br /&gt;  在测试外壳主菜单上的Items[1]是菜单项Plug-in，所以这个语句在Plugin菜单条上添加一个叫Plug-in Test的菜单项。&lt;br /&gt;  为了处理对新菜单项的响应，作为它的第五个参数，NewItem可以接受一个TNotifyEvent类型的过程，这个过程将在菜单项被点击时调用。不幸的是，按照定义，这种类型的过程是一个对象方法，然而在我们的插件中并没有对象。如果我们想用通常的指针来指向函数，那么得到的将只会是Delphi编译器的抱怨。所以，唯一的解决办法就是创建一个处理菜单点击的对象。这就是Tholder类的用处。它只有一个方法，是一个叫做ClickHandler的过程。一个叫做Holder的全局变量，在修改过的main.pas的var段中被声明为Tholder类型，并且在单元的initialization段中被创建。现在我们就有一个对象了，我们可以拿它的方法（Holder.ClickHandler）当作NewItem函数的参数。&lt;br /&gt;  搞了这一通，ClickHandler除了显示一个“Clicked!”消息对话框以外什么以没干。也许这不怎么有趣，不过它仍然证明了一点：插件DLL成功的修改了父应用的主菜单，表现了它的新用途。并且如同第一个例子一样，不管这个插件在不在应用程序都能执行。&lt;br /&gt;  由于我们创建了一个对象来处理菜单点击，那么在不再需要这个插件时，就要释放这个对象。修改后的单元中会在finalization段中处理这件事情。Finalization端时与initialization段相对应的，如果前面有一个initialization段，那么在应用程序终止时finalization段一定会得到执行。把下面的语句&lt;br /&gt;Holder.Free&lt;br /&gt;加到finalization段中，以确保Holder对象会被正确的释放。&lt;br /&gt;  显而易见，虽然这个插件只是修改了外壳应用的主菜单，但是它可以轻易地操纵传递到InitPlugin过程中的任何其他对象。如果有必要，插件也可以打开自己的对话框，向列表框（List boxes）和树状视图（tree views）中添加项目，或者在画布（canvas）中绘画。&lt;br /&gt;&lt;br /&gt;事件驱动的插件&lt;br /&gt;&lt;br /&gt;  到现在为止我们所描述的技术可以产生一种通用的扩展应用程序的方法。通过增加新菜单、窗体和对话框，就可以实现全新的功能而不必对父应用做任何修改。不过仍然有一个限制：这只是一种单侧（one-sided）机制。正如所看到的，系统依赖用户的某些操作才能启动插件代码，比如点击菜单或者类似的动作。代码运行起来以后，又要依靠另外一个用户动作来停止它，例如，关闭插件可能已经打开的窗体。克服这种缺陷的一种可行的方法就是使插件可以响应父应用中的动作——模仿在Delphi中工作地很好的事件驱动编程模型的确有效。&lt;br /&gt;在最后一个例子插件中，我们将创建一种机制，插件可以藉此响应父应用中产生的事件。通常情况下，可以通过判定需要触发哪些事件、在父应用中为每个事件创建一个Tlist对象来实现。然后每个Tlist对象都被传递到插件的初始化过程中，如果插件想在某个事件中执行动作，它就把负责执行的函数地址加入到对应的TList中。父应用在适当的时刻循环这些函数指针的列表，按次序调用每个函数。通过这种方法，就为多个插件在同一事件中执行动作提供了可能。&lt;br /&gt;应用程序产生的事件完全依赖于程序已确定的功能。例如，一个TCP/IP网络应用程序可能希望通过TclientSocket的onRead事件通知插件数据抵达，而一个图形应用程序可能对调色板的变化更感兴趣。&lt;br /&gt;  为了说明事件驱动的插件应答的概念，我们将创建一个用于限制主窗口最小尺寸的插件。这个例子有点儿造作，因为把这个功能做到应用程序里边会比这简单的多。不过这个例子的优点在语容易编码而且易于理解，而这正是本文想要做到的。&lt;br /&gt;  很明显，我们要做的第一件事情就是决定到底要产生哪些事件。在本例中，答案很简单：要限制一个应用程序窗口的尺寸，有必要捕获并且修改Windows消息WM_GETMINMAXSINFO。因此，要创建一个完成这项功能的插件，我们必须捕获这个消息并且在这个消息处理器中调用插件例程。这就是我们要创建的事件。&lt;br /&gt;  接下来我们要创建一个TList来处理这个事件。在主窗体的initialization段中将会创建lstMinMax对象，然后，创建一个消息处理器来捕获Windows消息WM_GETMINMAXINFO。&lt;br /&gt;{ 捕获 WM_GETMINMAXINFO. 为每个消息调用插件例程. }&lt;br /&gt;procedure TfrmMain.MinMaxInfo(var msg: TMessage); &lt;br /&gt;var&lt;br /&gt;  m: PMinMaxInfo;   file://在 Windows.pas 中定义. &lt;br /&gt;  i: Integer; &lt;br /&gt;begin&lt;br /&gt;  m := pointer(msg.Lparam); &lt;br /&gt;   for i := 0 to lstMinMax.count -1 do begin&lt;br /&gt;    TResizeProc(lstMinMax[i])(m.ptMinTrackSize.x, &lt;br /&gt;                              m.ptMinTrackSize.y); &lt;br /&gt;   end;&lt;br /&gt;end;&lt;br /&gt; WM_GETMINMAXINFO 的消息处理器&lt;br /&gt;  外壳应用的LoadPlugin过程必须再次修改以便调用初始化例程。这个新初始化函数把我们的TList当作参数接受，在其中加入修改消息参数的函数地址。图1显示了LoadPlugin过程的最终版本，它可以执行到目前为止所讨论的全部几个插件的初始化工作。&lt;br /&gt;{ 加载指定的插件DLL. }&lt;br /&gt;procedure TfrmMain.LoadPlugin(sr: TSearchRec); &lt;br /&gt;var&lt;br /&gt;  Description:   string;&lt;br /&gt;  LibHandle:     Integer; &lt;br /&gt;  DescribeProc: TPluginDescribe; &lt;br /&gt;  InitProc:      TPluginInit; &lt;br /&gt;  InitEvents:    TInitPluginEvents; &lt;br /&gt;begin&lt;br /&gt;  LibHandle := LoadLibrary(Pchar(sr.Name)); &lt;br /&gt;   if LibHandle &lt;&gt; 0 then&lt;br /&gt;   begin&lt;br /&gt;     // 查找 DescribePlugin. &lt;br /&gt;    DescribeProc := GetProcAddress(LibHandle, &lt;br /&gt;                                   cPLUGIN_DESCRIBE); &lt;br /&gt;     if Assigned(DescribeProc) then&lt;br /&gt;     begin&lt;br /&gt;       // 调用 DescribePlugin. &lt;br /&gt;       DescribeProc(Description); &lt;br /&gt;      memPlugins.Lines.Add(Description); &lt;br /&gt;       file://查找InitPlugin. &lt;br /&gt;      InitProc := GetProcAddress(LibHandle, cPLUGIN_INIT); &lt;br /&gt;       if Assigned(InitProc) then&lt;br /&gt;       begin&lt;br /&gt;        file://调用InitPlugin. &lt;br /&gt;        InitProc(mnuMain); &lt;br /&gt;       end;&lt;br /&gt;       // 为第三方插件查找 InitPluginEvents &lt;br /&gt;      InitEvents := GetProcAddress(LibHandle, &lt;br /&gt;                                   cPLUGIN_INITEVENTS); &lt;br /&gt;       if Assigned(InitEvents) then&lt;br /&gt;       begin&lt;br /&gt;        // 调用 InitPlugin. &lt;br /&gt;        InitEvents(lstMinMax); &lt;br /&gt;       end;&lt;br /&gt;     end&lt;br /&gt;     else&lt;br /&gt;     begin&lt;br /&gt;      MessageDlg('File "' + sr.Name +&lt;br /&gt;        '" is not a valid plugin.', &lt;br /&gt;        mtInformation, [mbOK], 0); &lt;br /&gt;     end;&lt;br /&gt;   end&lt;br /&gt;   else&lt;br /&gt;   begin&lt;br /&gt;    MessageDlg('An error occurred loading the plugin "' +&lt;br /&gt;      sr.Name + '".', mtInformation, [mbOK], 0); &lt;br /&gt;   end;&lt;br /&gt;end;&lt;br /&gt;图 1: LoadPlugin 的最终版本&lt;br /&gt;  最后一步是创建插件自身。如同前面的几个例子，插件展示一个标志自身的描述过程。它也带有一个初始化例程，在本例中只是接受一个TList作为参数。最后，它还包含一个没有引出（Export）的历程，叫做AlterMinTrackSize，它将修改传递给它的数值。图2显示了最终插件的完整代码。&lt;br /&gt;unit main; &lt;br /&gt;  &lt;br /&gt;interface&lt;br /&gt;  &lt;br /&gt;uses Dialogs, Menus, classes; &lt;br /&gt;  &lt;br /&gt;  procedure DescribePlugin(var Desc: string);&lt;br /&gt;     export; stdcall;&lt;br /&gt;  procedure InitPluginEvents(lstResize: TList); &lt;br /&gt;     export; stdcall;&lt;br /&gt;  procedure AlterMinTrackSize(var x, y: Integer); stdcall;&lt;br /&gt;  &lt;br /&gt;implementation&lt;br /&gt;  &lt;br /&gt;procedure DescribePlugin(var Desc: string);&lt;br /&gt;begin&lt;br /&gt;  Desc := 'Test plugin 3 - MinMax'; &lt;br /&gt;end;&lt;br /&gt;  &lt;br /&gt;procedure InitPluginEvents(lstResize: TList); &lt;br /&gt;begin&lt;br /&gt;  lstResize.Add(@AlterMinTrackSize); &lt;br /&gt;end;&lt;br /&gt;  &lt;br /&gt;procedure AlterMinTrackSize(var x, y: Integer); &lt;br /&gt;begin&lt;br /&gt;  x := 270; &lt;br /&gt;  y := 220; &lt;br /&gt;end;&lt;br /&gt;  &lt;br /&gt;end.&lt;br /&gt;图 2: 最终插件的代码&lt;br /&gt;  InitPluginEvents过程是这个插件的初始化例程。它接受一个TList作为参数。这个TList就是在父应用程序中创建的保存相应函数地址的列表。下面的语句：&lt;br /&gt;lstResize.Add(@AlterMinTrackSize);&lt;br /&gt;  把AlterMinTrackSize函数的地址加入到了这个列表中。它被声明为类型stdcall以便与其他过程相配，不过用不着export指示字。由于函数被直接通过它的地址调用，所以也就没有必要按照通常的方式把它从DLL中引出。&lt;br /&gt;所以，事件序列如下所列：&lt;br /&gt;1、 在应用程序初始化时，创建一个TList对象。&lt;br /&gt;2、 在启动时这个列表被传递到插件的初始化过程InitPluginEvents中。&lt;br /&gt;3、 插件过程把一个过程的地址加入到列表中。&lt;br /&gt;4、 每次窗口大小改变时所产生的Windows消息WM_GETMINMAXINFO被我们的应用程序所捕获。&lt;br /&gt;5、 该消息被我们的消息处理器TfrmMain.MainMaxInfo所处理，见图1。&lt;br /&gt;6、 消息处理器遍历列表并调用它所包含的函数，把当前的X和Y最小窗口尺寸作为参数传递。要注意，TList类只是存储指针，所以如果想用保存的地址做些什么事情的话，我们必须把指针转换成所需要的类型——在本例中，要转换成TresizeProc。&lt;br /&gt;TResizeProc = procedure (var x, y: Integer); stdcall;&lt;br /&gt;7、 插件过程AlterMinTrackSize（列表中的指针所指向的），接受X和Y值作为可变的var参数并且修改它们。&lt;br /&gt;8、 控制权返回到父应用的消息处理器，按照最小窗口尺寸的新值继续运行下去。&lt;br /&gt;9、 应用程序退出时TList会在主代码的finalization段被释放。&lt;br /&gt;结论&lt;br /&gt;&lt;br /&gt;  使用该体系结构时，可能利用Delphi提供的package功能是个不错的主意。在通常情况下，我不是一个分割运行时模块的狂热爱好者，但是当你认为任一包含大量代码的Delphi DLL超过200KB时，它就开始变得有意义了。&lt;br /&gt;  这篇文章应该还是有些用处的，至少它可以让你思考一些程序设计方面的问题，比如如何让它变得更加灵活。我知道如果我在以前的应用程序中使用一些这种技术的话，我就可以省掉在修改程序方面的好多工作。我并不想把插件作为一种通用的解决方案。很明显，有些情况下额外的复杂度无法验证其正确性，或者应用程序压根儿就不打算把自身搞成几块可扩展的单元。还有一些其它的方法也可以达成同样的效果。Delphi自身提供了一个接口来创作能集成到IDE中的模块，比起我所说明的技术这种方法更加面向对象（或者说更“干净”），而我也确信你可以在自己的应用中模仿这一技术。在运行时加载Delphi包也不是做不到的。探索一下这种可能性吧。&lt;br /&gt;  [本文所介绍的技术在Delphi 4下工作的很好。实际上，Delphi 4增加了工程选项，使这类应用程序加强DLL（application-plus-DLL）的开发变得更加容易了。]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-5559821784987352439?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/5559821784987352439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=5559821784987352439' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5559821784987352439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5559821784987352439'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/04/delphi-plugin-technology.html' title='Delphi Plugin Technology'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-3543508601291773442</id><published>2008-04-03T14:32:00.006+08:00</published><updated>2008-04-03T14:39:47.339+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firefox 2'/><category scheme='http://www.blogger.com/atom/ns#' term='Google toolbar'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox 3'/><title type='text'>Firefox 2 or Firefox 3? it's a problem.</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Ed2oWHNGofs/R_R6tRlrE5I/AAAAAAAAATY/EchA7Zlw1iI/s1600-h/firefox2.jpg"&gt;&lt;/a&gt;Firefox 3 beta 5 released today, but why Google toolbar doesn't support firefox3?&lt;br /&gt;My firefox2 always crash when popup a new window.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Firefox 2 or Firefox 3? it's a problem.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration: underline;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Ed2oWHNGofs/R_R6tRlrE5I/AAAAAAAAATY/EchA7Zlw1iI/s1600-h/firefox2.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://3.bp.blogspot.com/_Ed2oWHNGofs/R_R6tRlrE5I/AAAAAAAAATY/EchA7Zlw1iI/s320/firefox2.jpg" alt="" id="BLOGGER_PHOTO_ID_5184903989244400530" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-3543508601291773442?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/3543508601291773442/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=3543508601291773442' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3543508601291773442'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3543508601291773442'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/04/firefox-3-beta-5-released-but-google.html' title='Firefox 2 or Firefox 3? it&apos;s a problem.'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_Ed2oWHNGofs/R_R6tRlrE5I/AAAAAAAAATY/EchA7Zlw1iI/s72-c/firefox2.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-5521783969189422897</id><published>2008-04-03T13:47:00.000+08:00</published><updated>2008-04-03T13:48:55.302+08:00</updated><title type='text'>今天可以从国内访问了</title><content type='html'>今天可以从国内访问BlogSpot.com了，庆祝一下，不知道奥运过后还能不能继续访问。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-5521783969189422897?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/5521783969189422897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=5521783969189422897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5521783969189422897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5521783969189422897'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2008/04/blog-post.html' title='今天可以从国内访问了'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-4253428840044785354</id><published>2007-05-07T09:49:00.001+08:00</published><updated>2007-05-07T09:49:56.695+08:00</updated><title type='text'>Top 5 javascript frameworks�</title><content type='html'>&lt;a href="http://www.whenpenguinsattack.com/2007/04/24/top-5-javascript-frameworks/?articleid=890" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;» Top 5 javascript frameworks� - Jaslabs: High performance php &lt;/a&gt;&lt;br&gt;&lt;br&gt;&lt;div&gt;&lt;div&gt;&lt;p&gt;&lt;strong&gt; By Justin Silverton&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;5) Yahoo! User Interface Library&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.whenpenguinsattack.com/images/yahoolib.gif"&gt;&lt;/p&gt; &lt;p&gt;The Yahoo! User Interface (YUI) Library is a set of utilities and controls, written in JavaScript, for building richly interactive web applications using techniques such as DOM scripting, DHTML and AJAX. The YUI Library also includes several core CSS resources. All components in the YUI Library have been released as open source under a BSD license and are free for all uses. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;Two different types of components are available: Utilities and controls.  The YUI utilities simplify in-browser devolvement that relies on cross-browser DOM scripting, as do all web applications with DHTML and AJAX characteristics.  The YUI Library Controls provide highly interactive visual design elements for your web pages. These elements are created and managed entirely on the client side and never require a page refresh. &lt;/p&gt; &lt;p&gt;utilities available:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Animation:&lt;/strong&gt; Create &amp;quot;cinematic effects&amp;quot; on your pages by animating the position, size, opacity or other characteristics of page elements. These effects can be used to reinforce the user&amp;#39;s understanding of changes happening on the page. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Browser History Manager:&lt;/strong&gt; Developers of rich internet applications want bookmarks to target not just pages but page states and they want the browser&amp;#39;s back button to operate meaningfully within their application&amp;#39;s screens. Browser History Manager provides bookmarking and back button control in rich internet applications. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Connection Manager:&lt;/strong&gt; This utility library helps manage XMLHttpRequest (commonly referred to as AJAX) transactions in a cross-browser fashion, including integrated support for form posts, error handling and callbacks. Connection Manager also supports file uploading. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;DataSource Utility:&lt;/strong&gt; DataSource provides an interface for retrieving data from arrays, XHR services, and custom functions with integrated caching and Connection Manager support. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Dom Collection:&lt;/strong&gt;The DOM Utility is an umbrella object comprising a variety of convenience methods for common DOM-scripting tasks, including element positioning and CSS style management. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Drag &amp;amp; Drop:&lt;/strong&gt; Create draggable objects that can be picked up and dropped elsewhere on the page. You write code for the &amp;quot;interesting moments&amp;quot; that are triggered at each stage of the interaction (such as when a dragged object crosses over a target); the utility handles all the housekeeping and keeps things working smoothly in all supported browsers. &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Controls available:&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;strong&gt;AutoComplete:&lt;/strong&gt; The AutoComplete Control allows you to streamline user interactions involving text-entry; the control provides suggestion lists and type-ahead functionality based on a variety of data-source formats and supports server-side data-sources via XMLHttpRequest. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Button Control:&lt;/strong&gt; The Button Control provides checkbox, radio button, submit and menu-button UI elements that are more impactful visually and more powerful programmatically than the browser&amp;#39;s built-in form widgets. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Calendar:&lt;/strong&gt; The Calendar Control is a graphical, dynamic control used for date selection. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Container: &lt;/strong&gt;The Container family of controls supports a variety of DHTML windowing patterns including Tooltip, Panel, Dialog and SimpleDialog. The Module and Overlay controls provide a platform for implementing additional, customized DHTML windowing patterns. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;DataTable Control:&lt;/strong&gt; DataTable leverages the semantic markup of the HTML table and enhances it with sorting, column-resizing, inline editing of data fields, and more. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Logger:&lt;/strong&gt; The YUI Logger provides a quick and easy way to write log messages to an on-screen console, the FireBug extension for Firefox, or the Safari JavaScript console. Debug builds of YUI Library components are integrated with Logger to output messages for debugging implementations. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Menu:&lt;/strong&gt; Application-style fly-out menus require just a few lines of code with the Menu Control. Menus can be generated entirely in JavaScript or can be layered on top of semantic unordered lists. &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Download and more information: &lt;a href="http://developer.yahoo.com/yui/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;4) Prototype&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.whenpenguinsattack.com/images/prototype.gif"&gt;&lt;/p&gt; &lt;p&gt;Prototype is a JavaScript Framework that aims to ease development of dynamic web applications.&lt;/p&gt; &lt;p&gt;Featuring a unique, easy-to-use toolkit for class-driven development and the nicest Ajax library around, Prototype is quickly becoming the codebase of choice for web application developers everywhere.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Easily deploy ajax applications:&lt;/strong&gt; Besides simple requests, this module also deals in a smart way with JavaScript code returned from a server and provides helper classes for polling.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;DOM extending:&lt;/strong&gt; adds many convenience methods to elements returned by the $() function: for instance, you can write $(&amp;#39;comments&amp;#39;).addClassName(&amp;#39;active&amp;#39;).show() to get the element with the ID &amp;#39;comments&amp;#39;, add a class name to it and show it (if it was previously hidden).  &lt;/li&gt; &lt;li&gt;&lt;strong&gt;Utilizes JSON (JavaScript Object Notation):&lt;/strong&gt; JSON is a light-weight and fast alternative to XML in Ajax requests&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Download and more information &lt;a href="http://www.prototypejs.org/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;3) Rico&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.whenpenguinsattack.com/images/ricologo.gif"&gt;&lt;/p&gt; &lt;p&gt;Designed for building rich Internet applications.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Animation Effects:&lt;/strong&gt; provides responsive animation for smooth effects and transitions that that can communicate change in richer ways than traditional web applications have explored before. Unlike most effects, Rico  2.0 animation can be interrupted, paused, resumed, or have other effects applied to it to enable responsive interaction that the user does not have to wait on&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Styling:&lt;/strong&gt; Rico provides several cinematic effects as well as some simple visual style effects in a very simple interface.&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Drag And Drop:&lt;/strong&gt; Desktop applications have long used drag and drop in their interfaces to simplify user interaction. Rico provides one of the simplest interfaces for enabling your web application to support drag and drop. Just register any HTML element or JavaScript object as a draggable and any other HTML element or JavaScript object as a drop zone and Rico handles the rest. &lt;/li&gt; &lt;li&gt;&lt;strong&gt;AJAX Support: &lt;/strong&gt;Rico provides a very simple interface for registering Ajax request handlers as well as HTML elements or JavaScript objects as Ajax response objects. Multiple elements and/or objects may be updated as the result of one Ajax request. &lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Download and more information &lt;a href="http://openrico.org/rico/home.page" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;2) Qooxdoo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.whenpenguinsattack.com/images/qoo.gif"&gt;&lt;/p&gt; &lt;p&gt;qooxdoo is one of the most comprehensive and innovative Open Source multipurpose AJAX frameworks, dual-licensed under LGPL/EPL. It includes support for professional JavaScript development, a state-of-the-art GUI toolkit and high-level client-server communication. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt; &lt;strong&gt;Client detection:&lt;/strong&gt; qooxdoo knows what browser is being used and makes this information available to you. &lt;/li&gt; &lt;li&gt; &lt;strong&gt;Browser abstraction:&lt;/strong&gt; qooxdoo includes a browser abstraction layer which tries to abstract all browser specifics to one common &amp;quot;standard&amp;quot;. This simplifies the real coding of countless objects by allowing you to focus on what you want and not &amp;quot;how to want it&amp;quot;. The browser abstraction layer comes with some basic functions often needed when creating real GUIs. For example, runtime styles or positions (in multiple relations: page, client and screen) of each element in your document. &lt;/li&gt; &lt;li&gt;&lt;strong&gt;Advanced property implementation:&lt;/strong&gt; qooxdoo supports &amp;quot;real&amp;quot; properties for objects. This means any class can define properties which the created instances should have. The addProperty handler also adds getter and setter functions. The only thing one needs to add - should you need it - is a modifier function. &lt;/li&gt; &lt;li&gt;&lt;strong&gt;Event Management:&lt;/strong&gt;  qooxdoo comes with its own event interface. This includes event registration and deregistration functions. &lt;p&gt;Furthermore there is the possibility to call the target function in any object context. (The default is the object which defines the event listener.) The event system normalizes differences between the browsers, includes support for mousewheel, doubleclick and other fancy stuff. qooxdoo also comes with an advanced capture feature which allows you to capture all events when a user drags something around for example. &lt;/p&gt;&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Download and more information &lt;a href="http://qooxdoo.org/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;here&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&lt;strong&gt;1) Dojo&lt;/strong&gt;&lt;/p&gt; &lt;p&gt;&lt;img src="http://www.whenpenguinsattack.com/images/dojo.gif"&gt;&lt;/p&gt; &lt;p&gt;Dojo allows you to easily build dynamic capabilities into web pages and any other environment that supports JavaScript sanely. You can use the components that Dojo provides to make your web sites more usable, responsive, and functional. With Dojo you can build degradable user interfaces more easily, prototype interactive widgets quickly, and animate transitions. You can use the lower-level APIs and compatibility layers from Dojo to write portable JavaScript and simplify complex scripts. Dojo&amp;#39;s event system, I/O APIs, and generic language enhancement form the basis of a powerful programming environment. You can use the Dojo build tools to write command-line unit-tests for your JavaScript code. The Dojo build process helps you optimize your JavaScript for deployment by grouping sets of files together and reuse those groups through &amp;quot;profiles&amp;quot;. &lt;/p&gt; &lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt; &lt;ul&gt; &lt;li&gt;&lt;strong&gt;Multiple Points Of Entry:&lt;/strong&gt; A fundamental concept in the design of Dojo is &amp;quot;multiple points of entry&amp;quot;. This term means that Dojo should work very hard to make sure that users should be able to start using Dojo at the level they are most comfortable with. &lt;/li&gt; &lt;li&gt;&lt;strong&gt;Interpreter Independence:&lt;/strong&gt; Dojo tries very hard to ensure that it&amp;#39;s possible to support at least the very core of the system on as many JavaScript enabled platforms as possible. This will allow Dojo to serve as a &amp;quot;standard library&amp;quot; for JavaScript programmers as they move between client-side, server-side, and desktop programming environments. &lt;/li&gt; &lt;li&gt;&lt;strong&gt;Unifies several codebases:&lt;/strong&gt; builds on several contributed code bases (&lt;a href="http://nwidgets.org/%27" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;nWidgets&lt;/a&gt;, &lt;a href="http://burstproject.org/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; Burstlib&lt;/a&gt;, and &lt;a href="http://fm.dept-z.com/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; f(m)&lt;/a&gt;).&lt;/li&gt; &lt;/ul&gt; &lt;p&gt;Download and more information &lt;a href="http://www.dojotoolkit.org/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;here&lt;/a&gt; &lt;/p&gt;                        &lt;/div&gt;             &lt;/div&gt;   &lt;div&gt;        &lt;h2&gt;     14 Comments so far  &lt;/h2&gt;   &lt;ol&gt;         &lt;li&gt;       &lt;div&gt;         &lt;a href="http://www.dougalmathews.com/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Dougal Matthews&lt;/a&gt;&amp;nbsp;April 24th, 2007          10:58 am		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;Have you not tried ExJS? &lt;a href="http://extjs.com/" rel="nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;http://extjs.com/&lt;/a&gt;&lt;/p&gt; &lt;p&gt;Oh and I&amp;#39;d personally put Yahoo UI higher, 1st or 2nd.&lt;/p&gt; &lt;p&gt;Also, unless you are ignoring non open source stuff… what about Microsoft&amp;#39;s AJAX (Atlas)? &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://alterform.com/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Nate Cavanaugh&lt;/a&gt;&amp;nbsp;April 24th, 2007          11:20 am		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;No jQuery? Cmon, it&amp;#39;s one of the best JS libraries around. &lt;img src="http://www.whenpenguinsattack.com/wp-includes/images/smilies/icon_smile.gif" alt=":)"&gt; &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://www.tweako.com/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Mike&lt;/a&gt;&amp;nbsp;April 24th, 2007          12:23 pm		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;Great list.&lt;/p&gt; &lt;p&gt;submitted in queue @ tweako&lt;/p&gt; &lt;p&gt;( &lt;a href="http://www.tweako.com/" rel="nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;http://www.tweako.com&lt;/a&gt; ) &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://inneroptics.net/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Tony T.&lt;/a&gt;&amp;nbsp;April 24th, 2007          12:52 pm		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;I&amp;#39;m just curious if you considered mootools as one of these frameworks, or if it just fell below the top 5?  I really like mootools mainly because of it&amp;#39;s really light weight (and the ability to build a js package of only the components you want straight from their website).  I&amp;#39;ve been using YUI the past few months on a project made specifically for broadband clients.  I wouldn&amp;#39;t recommend it for any normal production website because of it&amp;#39;s size. &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://inneroptics.net/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Tony T.&lt;/a&gt;&amp;nbsp;April 24th, 2007          12:53 pm		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;I guess everyone has their favorites &lt;img src="http://www.whenpenguinsattack.com/wp-includes/images/smilies/icon_smile.gif" alt=":-)"&gt; &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://mellentine.com/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;jaredmellentine&lt;/a&gt;&amp;nbsp;April 24th, 2007          1:02 pm		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;I have to agree with Nate.  jQuery is pretty amazing and extremely well documented. &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://developer.yahoo.com/yui" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;nate koechley&lt;/a&gt;&amp;nbsp;April 24th, 2007          3:19 pm		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;It would be interesting to hear a bit about your ranking criteria and notes on the pros and cons of each library.&lt;/p&gt; &lt;p&gt;thanks,&lt;br&gt; nate &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         Shane&amp;nbsp;April 25th, 2007          1:45 am		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;Why isn&amp;#39;t jQuery in the list? Rico is like so yesterday! &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         cliff&amp;nbsp;April 25th, 2007          3:39 am		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;I&amp;#39;ve got some professional experience with dojo, and if it&amp;#39;s the best thing going then I&amp;#39;m afraid the other libraries must be worse to be rated below it… and that&amp;#39;s pretty bad from my personal experience. &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://www.mindgrids.com/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Tom Sieron&lt;/a&gt;&amp;nbsp;April 25th, 2007          4:47 am		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;I was suprised not see jQuery here as well. It  has comparable features to the libraries you&amp;#39;ve mentioned, plus it&amp;#39;s lightweight and comes with abundance of plugins (and works with Ext now). Right now I&amp;#39;m preparing a presentation on JS libraries (for php developers at a local barcamp-thing) and your post is one of my resources for the comparison, it would be great if you could shed some light on your criteria, coz I&amp;#39;ve been pondering upon that all morning and I&amp;#39;m having trouble identifying the important issues for a webdev (im a designer by trade). Cheers. &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://www.jaslabs.com/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Justin Silverton&lt;/a&gt;&amp;nbsp;April 25th, 2007          6:55 pm		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;&amp;quot;I&amp;#39;ve got some professional experience with dojo, and if it&amp;#39;s the best thing going then I&amp;#39;m afraid the other libraries must be worse to be rated below it… and that&amp;#39;s pretty bad from my personal experience.&amp;quot; &lt;/p&gt; &lt;p&gt;What issues did you hava with dojo?  Im curious because I&amp;#39;ve used it a couple of times and found it to be a fairly complete framework. &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://www.elektronramp.com/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Dennis Kayser&lt;/a&gt;&amp;nbsp;May 6th, 2007          2:44 am		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;What! jQuery is not in the top 5! There&amp;#39;s got to be a mistake. Seriously I&amp;#39;d like to hear why jQuery is not in here? It&amp;#39;d be interesting to know. &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         &lt;a href="http://www.jaslabs.com/" rel="external nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Justin Silverton&lt;/a&gt;&amp;nbsp;May 6th, 2007          10:29 am		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;&amp;quot;What! jQuery is not in the top 5! There&amp;#39;s got to be a mistake. Seriously I&amp;#39;d like to hear why jQuery is not in here? It&amp;#39;d be interesting to know.&amp;quot;&lt;/p&gt; &lt;p&gt;it&amp;#39;s mostly because I don&amp;#39;t have much experience with it (it also seems like the main page for it is down: &lt;a href="http://jquery.com/" rel="nofollow" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; http://jquery.com/&lt;/a&gt;).  Can you post some reasons why you think it is better than the frameworks listed? &lt;/p&gt; &lt;/div&gt;    &lt;/li&gt;             &lt;li&gt;       &lt;div&gt;         shoebappa&amp;nbsp;May 6th, 2007          9:36 pm		  		  		  		          &lt;/div&gt;             &lt;div&gt;&lt;p&gt;jQuery is good because of its modular plug-in architecture making it small while providing flexibility by adding plug-ins.  The main benefit of jQuery is that it sits along side of your site so you can easily make a site that can function without JavaScript but if the user has JS enabled the jQuery code would go into action and add the additional functionality.  That and its CSS selector and XPath style queries for interacting with the DOM is invaluable.  Should definitely be at the top of the list IMO… &lt;/p&gt; &lt;p&gt;Looks like they&amp;#39;re moving servers but you have to give jQuery a look, I didn&amp;#39;t see how incredible it was until I started to hose around with it.&lt;/p&gt;&lt;/div&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-4253428840044785354?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/4253428840044785354/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=4253428840044785354' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4253428840044785354'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4253428840044785354'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/05/top-5-javascript-frameworks.html' title='Top 5 javascript frameworks�'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-7658984657686609556</id><published>2007-04-30T22:58:00.001+08:00</published><updated>2007-04-30T22:58:12.826+08:00</updated><title type='text'>Vincent Partington: Top 10 Java EE performance problems</title><content type='html'>&lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=45187" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Vincent Partington: Top 10 Java EE performance problems&lt;/a&gt;&lt;br&gt;&lt;br&gt;                              For the last two and a half months, Vincent Partington has been blogging about the top ten Enterprise Java Application Performance Problems. The list:&lt;ul&gt;&lt;li&gt;#10 - &lt;a href="http://blog.xebia.com/2007/02/18/ejapp-top-10-countdown-10-excessive-logging/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;  Excessive logging&lt;/a&gt;&lt;/li&gt;&lt;li&gt;#9 - &lt;a href="http://blog.xebia.com/2007/02/25/ejapp-top-10-countdown-9-incorrect-application-server-configuration/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Incorrect application server configuration &lt;/a&gt;&lt;/li&gt;&lt;li&gt;#8 - &lt;a href="http://blog.xebia.com/2007/03/09/ejapp-top-10-countdown-8-incorrect-usage-of-java-ee/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; Incorrect usage of Java EE&lt;/a&gt;&lt;/li&gt;&lt;li&gt;#7 - &lt;a href="http://blog.xebia.com/2007/03/19/ejapp-top-10-countdown-7-unnecessary-use-of-xml/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Unnecessary use of XML &lt;/a&gt;&lt;/li&gt;&lt;li&gt;#6 - &lt;a href="http://blog.xebia.com/2007/03/26/ejapp-top-10-countdown-6-improper-caching/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; Improper caching&lt;/a&gt;&lt;/li&gt;&lt;li&gt;#5 - &lt;a href="http://blog.xebia.com/2007/04/02/ejapp-top-10-countdown-5-excessive-memory-usage/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Excessive memory usage&lt;/a&gt; &lt;/li&gt;&lt;li&gt;#4 - &lt;a href="http://blog.xebia.com/2007/04/16/ejapp-top-10-countdown-4-badly-performing-libraries/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; Badly performing libraries&lt;/a&gt;&lt;/li&gt;&lt;li&gt;#3 - &lt;a href="http://blog.xebia.com/2007/04/22/ejapp-top-10-countdown-3-incorrectly-implemented-concurrency/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; Incorrectly implemented concurrency&lt;/a&gt;&lt;/li&gt;&lt;li&gt;#2 - &lt;a href="http://blog.xebia.com/2007/04/25/ejapp-top-10-countdown-2-unnecessary-remoting/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; Unnecessary remoting&lt;/a&gt;&lt;/li&gt;&lt;li&gt;#1 - &lt;a href="http://blog.xebia.com/2007/04/29/ejapp-top-10-countdown-1-incorrect-database-usage/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;Incorrect database usage &lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Now he &lt;a href="http://blog.xebia.com/2007/04/30/ejapp-top-10-countdown-wrap-up/" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; wraps up the countdown&lt;/a&gt; with some conclusions about Enterprise Java performance in general:&lt;ul&gt;&lt;li&gt;First of all, Java developers should consider performance an importance quality requirement of their application to which they should pay attention from the start to the end of the project. &lt;/li&gt;&lt;li&gt;Secondly, Java developers need to work with the people that can help them improve the performance of their application like application server and database administrators.&lt;/li&gt;&lt;/ul&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-7658984657686609556?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/7658984657686609556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=7658984657686609556' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7658984657686609556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7658984657686609556'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/vincent-partington-top-10-java-ee.html' title='Vincent Partington: Top 10 Java EE performance problems'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-8282426564024604265</id><published>2007-04-30T22:39:00.001+08:00</published><updated>2007-04-30T22:39:45.921+08:00</updated><title type='text'>在局域网内部实现MSN通讯服务 资讯中心-计世网</title><content type='html'>&lt;a href="http://www.ccw.com.cn/news2/internet/htm2007/20070429_255111.shtml" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;在局域网内部实现MSN通讯服务 资讯中心-计世网&lt;/a&gt;&lt;br&gt;&lt;br&gt;                               MSNMessengerService集即时消息、网络电话、自动检查邮件等功能于一体，很受广大&amp;quot;网虫&amp;quot;的喜爱，但是您知道吗，MSNMessengerService不但可以登录到MSN的Messenge  &lt;table style="margin: 10px 7px 3px 4px;" align="left" border="0" cellpadding="0" cellspacing="0"&gt; &lt;tbody&gt;&lt;tr&gt;&lt;td&gt;    &lt;div&gt;   &lt;/div&gt;    &lt;br&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;rServer，还可以登录到局域网内的ExchangeServer呢！无需连接到Internet，您一样可以享受MSNMessengerService的强大功能！&lt;p&gt;&lt;/p&gt;&lt;p&gt;下面笔者就如何建立局域网内部的通讯服务做详细介绍：&lt;/p&gt;&lt;p&gt;前提条件&lt;/p&gt;&lt;p&gt;网络中有一台计算机安装了MicrosoftExchangeServer2000（MicrosoftExchangeServer2000的安装方法不是本文重点，所以不做介绍了。详情请参阅： &lt;a href="http://support.microsoft.com%EF%BC%89" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;http://support.microsoft.com）&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;&lt;strong&gt;准备工作&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;1、一张MicrosoftExchangeServer2000安装光盘。 &lt;/p&gt;&lt;p&gt;2、下载MSNMessengerService的最新版本（ &lt;a href="http://messenger.msn.com/lccn" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;http://messenger.msn.com/lccn&lt;/a&gt;）。&lt;/p&gt;&lt;p&gt;安装与设置过程&lt;/p&gt;&lt;p&gt;一、添加ChatServices和InstantMessagingServices&lt;/p&gt;&lt;p&gt;1、将MicrosoftExchangeServer2000安装光盘放入服务器光驱，单击&amp;quot;ExchangeServerSetup&amp;quot;。 &lt;/p&gt;&lt;p&gt;2、当出现&amp;quot;MicrosoftExchangeInstallation向导&amp;quot;时，单击&amp;quot;下一步&amp;quot;。在&amp;quot;Action&amp;quot;栏选择&amp;quot;Change&amp;quot;，将ChatServices和InstantMessagingServices都选择成&amp;quot;Install&amp;quot;，单击&amp;quot;下一步&amp;quot;安装向导会自动完成安装任务。&lt;/p&gt;&lt;p&gt;二、配置InstantMessaging &lt;/p&gt;&lt;p&gt; 1、单击&amp;quot;开始&amp;quot;，指向&amp;quot;程序→MicrosoftExchange&amp;quot;，单击&amp;quot;SystemManager&amp;quot;，双击&amp;quot;Servers&amp;quot;，双击您的计算机名，双击&amp;quot;&lt;a href="http://wiki.ccw.com.cn/Mac+Pro" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; &lt;font color="#0000cc"&gt;&lt;b&gt;Pro&lt;/b&gt;&lt;/font&gt;&lt;/a&gt;tocols&amp;quot;，右击&amp;quot;InstantMessaging（RVP）&amp;quot;，选择&amp;quot;新建&amp;quot;，单击&amp;quot;InstantMessagingVirtualServer&amp;quot;，在DisplayName栏中输入配置文件名。 &lt;/p&gt;&lt;p&gt;2、单击&amp;quot;下一步&amp;quot;，在Choose&lt;a href="http://wiki.ccw.com.cn/Pentium_II" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt;&lt;font color="#0000cc"&gt;&lt;b&gt;II&lt;/b&gt;&lt;/font&gt;&lt;/a&gt;SWebSite中选择Web站点。单击&amp;quot;下一步&amp;quot;，在DN &lt;a href="http://wiki.ccw.com.cn/index.php/SD" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; &lt;font color="#0000cc"&gt;&lt;b&gt;SD&lt;/b&gt;&lt;/font&gt;&lt;/a&gt;omainName栏中输入DNS名（例如：home.net），此DNS名将作为用户登录邮件地址@符号后面的部分。单击&amp;quot;下一步&amp;quot;，在&amp;quot;Allowthisservertohostaccounts&amp;quot;前面打勾，使配置文件马上生效，配置完成后建议重新启动服务器。&lt;/p&gt;&lt;p&gt;三、配置用户账户&lt;/p&gt;&lt;p&gt; 1、在&amp;quot;管理工具&amp;quot;中单击&amp;quot;ActiveDirectory用户和计算机&amp;quot;，单击&amp;quot;Users&amp;quot;，任意选择一个用户（例如：administrator），双击账户，在&amp;quot;ExchangeFeatures&amp;quot;选项卡中，选中&amp;quot;InstantMessaging&amp;quot;。&lt;/p&gt;&lt;p&gt;2、单击&amp;quot;Enable→Browse&amp;quot;，在&amp;quot;ServerName&amp;quot;中选择配置文件名，单击&amp;quot;确定&amp;quot;。回到上一级选项卡。单击&amp;quot;确定&amp;quot;，即完成用户账户配置。 &lt;/p&gt;&lt;p&gt;四、安装、配置MSNMessengerService&lt;/p&gt;&lt;p&gt;1、将MicrosoftExchangeServer2000安装光盘放入客户机光驱；在客户机，单击&amp;quot;开始→运行&amp;quot;，键入&amp;quot;X:INSTMSGI386CL&lt;a href="http://wiki.ccw.com.cn/IE" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; &lt;font color="#0000cc"&gt; &lt;b&gt;IE&lt;/b&gt;&lt;/font&gt;&lt;/a&gt;NTCHSMMSSETUP.EXE&amp;quot;（X代表您的光驱的盘符），开始安装MSNMessengerService2.2forExchange。&lt;/p&gt;&lt;p&gt;2、MSNMessengerService2.2forExchange安装完毕后，再安装您从网上下载的MSNMessengerService3.x。&lt;/p&gt;&lt;p&gt;3、安装完毕后在MSNMessengerService3.x主窗口， 单击&amp;quot;工具&amp;quot;；选择&amp;quot;选项&amp;quot;，在&amp;quot;账户&amp;quot;选项卡中的&amp;quot;首先用此账户登录&amp;quot;选项中选择&amp;quot;Exchange账户&amp;quot;在Exchange账户&amp;quot;登录名&amp;quot;框中输入登录名&lt;a href="mailto:administrator@home.net" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"&gt; administrator@home.net&lt;/a&gt;。&lt;/p&gt;&lt;p&gt;4、单击&amp;quot;确定&amp;quot;，选择&amp;quot;单击这里登录&amp;quot;，即可登录到MicrosoftExchangeServer2000InstantMessagingService。 &lt;/p&gt;&lt;p&gt;注意：您必须首先安装MSNMessengerService2.2forExchange，然后再升级到MSNMessengerService3.x才能有登录到MicrosoftExchangeServer2000InstantMessagingService的选项，否则MSNMessengerService3.x中将没有登录到MicrosoftExchangeServer2000InstantMessagingService选项  。&lt;/p&gt;&lt;p&gt;5、重复3、4步即可创建、配置用户账户及客户端。&lt;/p&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-8282426564024604265?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/8282426564024604265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=8282426564024604265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8282426564024604265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8282426564024604265'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/msn.html' title='在局域网内部实现MSN通讯服务 资讯中心-计世网'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-7799994569747394580</id><published>2007-04-26T09:04:00.000+08:00</published><updated>2007-04-26T09:04:41.924+08:00</updated><title type='text'>Yod'm 3D - About - Visual Tooltip</title><content type='html'>&lt;a href="http://chsalmon.club.fr/index.php?en/Yod-m-3d-about"&gt;Yod'm 3D - About - Visual Tooltip&lt;/a&gt;: "Yet anOther Desktop Manager 3D&lt;br /&gt;( Windows 2000/XP/Vista )&lt;br /&gt;( DirectX 9 required )&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Yod'm 3D is a virtual desktop manager with the fashionable effect : the cube&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;By default, the rotation of the cube is done with the keys CTRL+SHIFT+Arrows :&lt;br /&gt;&lt;br /&gt;   * CTRL+SHIFT+Left/Right = Next/prev desktop&lt;br /&gt;&lt;br /&gt;   * CTRL+SHIFT+Up = Activate and show a 'far' view of the current desktop, Left and right to turn the cube&lt;br /&gt;&lt;br /&gt;   * CTRL+SHIFT+Down = Activate and show a 'near' view of the current desktop, Left and right to turn the cube&lt;br /&gt;&lt;br /&gt;Hold down CTRL+SHIFT to use the mouse to turn the cube.&lt;br /&gt;( The rotation is possible only horizontally )"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-7799994569747394580?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://chsalmon.club.fr/index.php?en/Yod-m-3d-about' title='Yod&apos;m 3D - About - Visual Tooltip'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/7799994569747394580/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=7799994569747394580' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7799994569747394580'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7799994569747394580'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/yodm-3d-about-visual-tooltip.html' title='Yod&apos;m 3D - About - Visual Tooltip'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-1645399018078527585</id><published>2007-04-25T22:47:00.000+08:00</published><updated>2007-04-25T22:47:44.479+08:00</updated><title type='text'>Enum Types (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)</title><content type='html'>&lt;a href="http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html"&gt;Enum Types (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)&lt;/a&gt;: "Java programming language enum types are much more powerful than their counterparts in other languages. The enum declaration defines a class (called an enum type). The enum class body can include methods and other fields. The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared. This method is commonly used in combination with the for-each construct to iterate over the values of an enum type. For example, this code from the Planet class example below iterates over all the planets in the solar system.&lt;br /&gt;&lt;br /&gt;   for (Planet p : Planet.values()) {&lt;br /&gt;       System.out.printf('Your weight on %s is %f%n',&lt;br /&gt;                             p, p.surfaceWeight(mass));&lt;br /&gt;   }"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-1645399018078527585?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://java.sun.com/docs/books/tutorial/java/javaOO/enum.html' title='Enum Types (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/1645399018078527585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=1645399018078527585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1645399018078527585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1645399018078527585'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/enum-types-java-tutorials-learning-java.html' title='Enum Types (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-6935009886068710437</id><published>2007-04-25T22:12:00.000+08:00</published><updated>2007-04-25T22:12:25.233+08:00</updated><title type='text'>Nested Classes (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)</title><content type='html'>&lt;a href="http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html"&gt;Nested Classes (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)&lt;/a&gt;: "A nested class is a member of its enclosing class and, as such, has access to other members of the enclosing class, even if they are declared private. As a member of OuterClass, a nested class can be declared private, public, protected, or package private. (Recall that outer classes can only be declared public or package private.)&lt;br /&gt;&lt;br /&gt;   Terminology: Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are simply called static nested classes. Non-static nested classes are called inner classes."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-6935009886068710437?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://java.sun.com/docs/books/tutorial/java/javaOO/nested.html' title='Nested Classes (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/6935009886068710437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=6935009886068710437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6935009886068710437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6935009886068710437'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/nested-classes-java-tutorials-learning.html' title='Nested Classes (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-7436671081239716126</id><published>2007-04-24T09:43:00.000+08:00</published><updated>2007-04-24T09:43:13.203+08:00</updated><title type='text'>60 best CSS directories you would die to watch! at Witty Sparks</title><content type='html'>&lt;a href="http://www.wittysparks.com/2007/04/22/60-best-css-directories-you-would-die-to-watch/"&gt;60 best CSS directories you would die to watch! at Witty Sparks&lt;/a&gt;: "With new technologies flooding the web,different tools are available with which a web designer can showcase his creativity and craft. But despite putting in the effort and sweat, numerous websites with fantastic creativity fail to get noticed. Also, the surge in designing is driving designers to dig for creativity, color schemes and layouts.&lt;br /&gt;&lt;br /&gt;Keeping these aspects in mind, we came up with a compendium of best CSS directories, CSS showcase, CSS galleries that rank / grade websites (using CSS) on the basis of ‘alexa ranking’, colors, categories, tags, ratings and RSS.&lt;br /&gt;&lt;br /&gt;If you feel that a particular site is worth to get showcased, then drop the URL’s in your comments so that they become a part of our next list.&lt;br /&gt;&lt;br /&gt;If you found this article useful, digg it to ensure that a designer’s effort doesn’t go unnoticed."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-7436671081239716126?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.wittysparks.com/2007/04/22/60-best-css-directories-you-would-die-to-watch/' title='60 best CSS directories you would die to watch! at Witty Sparks'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/7436671081239716126/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=7436671081239716126' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7436671081239716126'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7436671081239716126'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/60-best-css-directories-you-would-die.html' title='60 best CSS directories you would die to watch! at Witty Sparks'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-6682224506274967624</id><published>2007-04-19T00:08:00.000+08:00</published><updated>2007-04-19T00:08:15.251+08:00</updated><title type='text'>MSSQL数据库移植后的用户权限问题</title><content type='html'>&lt;a href="http://topic.csdn.net/t/20050706/19/4127423.html"&gt;&lt;/a&gt;把数据库备份还原到另一个服务器时，可能会遇到孤立用户的问题 &lt;br /&gt; 举例：数据库test有用户U_tom，对应的登录帐户为L_tom,按以下步骤操作将会出现孤立用户U_tomf: &lt;br /&gt; &lt;br /&gt; 备份test-&gt;删除数据库test-&gt;删除登录L_tom-&gt;还原test &lt;br /&gt; &lt;br /&gt; 查看： &lt;br /&gt; 1、企业管理器-&gt;展开要查看的数据库-&gt;用户   ，会发现相应的用户没有对应的登录 &lt;br /&gt; 2、在查询分析器中执行   EXECsp_change_users_login   @Action='Report' &lt;br /&gt; &lt;br /&gt;  解决：  &lt;br /&gt;  办法一、自动新增一个和用户名相同的登录帐户，并影射  &lt;br /&gt;  EXEC   sp_change_users_login   'Auto_Fix',   'U_tom'  &lt;br /&gt;    &lt;br /&gt;  办法二、新增一个登录帐户，然后将此登录帐户映射到孤立的用户  &lt;br /&gt;  EXEC   sp_addlogin   'L_tom'  &lt;br /&gt;  --Change   the   user   account   to   link   with   the   'L_tom'   login.  &lt;br /&gt;  EXEC   sp_change_users_login   'Update_One',   'U_tom',   'L_tom'  &lt;br /&gt;    &lt;br /&gt;  或者:  &lt;br /&gt;  1、找到该用户的ID   例如：  &lt;br /&gt;  select   sid   from   sysusers   where   name='U_tom'  &lt;br /&gt;  结果为  &lt;br /&gt;  0x67E19EC564D7344CB19AC35085C1A36B  &lt;br /&gt;    &lt;br /&gt;  2、新增一个登录帐户L_tom，将此登录帐户映射到孤立的用户  &lt;br /&gt;  EXEC   sp_addlogin   @loginame   =   'L_tom',  &lt;br /&gt;                 @sid   =   0x67E19EC564D7344CB19AC35085C1A36B  &lt;br /&gt;    &lt;br /&gt;  参考：sp_change_users_login   、sp_addlogin   的语法参考&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-6682224506274967624?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://topic.csdn.net/t/20050706/19/4127423.html' title='MSSQL数据库移植后的用户权限问题'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/6682224506274967624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=6682224506274967624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6682224506274967624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6682224506274967624'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/mssql.html' title='MSSQL数据库移植后的用户权限问题'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-9020347302331314515</id><published>2007-04-17T09:10:00.000+08:00</published><updated>2007-04-17T09:10:46.497+08:00</updated><title type='text'>VoIP Now: 74 Open Source VoIP Apps &amp; Resources</title><content type='html'>&lt;a href="http://www.voipnow.org/2007/04/74_open_source_.html"&gt;VoIP Now: 74 Open Source VoIP Apps &amp;amp; Resources&lt;/a&gt;: "When a body of independent auditors and experts recommended that the State of California consider open-source software and voice over Internet Protocol telephony (VoIP) as two measures to cut costs in 2004, that was the signal that open source and VoIP should unite. After all, what's better than free software? Open source is better, because you have access to the code. What's better than open source? Open source that's focused on VoIP. That's what you get here — 74 open source apps tucked into categories that you can use 'as is' or change to fit your specific VoIP needs.&lt;br /&gt;&lt;br /&gt;The following apps and resources are categorized by SIP, H.323, IAX, and RTP protocols and include clients, libraries, gatekeepers, and any other open source resource available for those specific protocols plus PBX and IVR platforms. You'll also find tools like faxware, voicemail apps, and middleware that applies to one or more of the previously mentioned protocols."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-9020347302331314515?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.voipnow.org/2007/04/74_open_source_.html' title='VoIP Now: 74 Open Source VoIP Apps &amp; Resources'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/9020347302331314515/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=9020347302331314515' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/9020347302331314515'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/9020347302331314515'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/voip-now-74-open-source-voip-apps.html' title='VoIP Now: 74 Open Source VoIP Apps &amp; Resources'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-6716622084691900991</id><published>2007-04-16T08:59:00.000+08:00</published><updated>2007-04-16T08:59:54.339+08:00</updated><title type='text'>Zolved - How to reduce the memory usage on Firefox?</title><content type='html'>&lt;a href="http://www.zolved.com/synapse/view_content/24939/How_to_reduce_the_memory_usage_on_Firefox"&gt;Zolved - How to reduce the memory usage on Firefox?&lt;/a&gt;: "Most of the time, Firefox doesn't use abnormal amount of system memory, it sometimes due to other sources, like number of plug-ins, themes and extensions. It is also highly recommended that you have the latest version of Firefox as the memory usage is minimized. If you want to download the latest copy of Firefox, click here.&lt;br /&gt;&lt;br /&gt;Follow these steps to check what is causing the abnormal memory usage:&lt;br /&gt;&lt;br /&gt;   * Check your Extensions and Themes.&lt;br /&gt;   * Check the Plug-ins.&lt;br /&gt;   * Clear Download History.&lt;br /&gt;   * Restart Firefox Periodically.&lt;br /&gt;   * Assign Memory Cache on Firefox."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-6716622084691900991?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.zolved.com/synapse/view_content/24939/How_to_reduce_the_memory_usage_on_Firefox' title='Zolved - How to reduce the memory usage on Firefox?'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/6716622084691900991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=6716622084691900991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6716622084691900991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6716622084691900991'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/zolved-how-to-reduce-memory-usage-on.html' title='Zolved - How to reduce the memory usage on Firefox?'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-8727149602785563526</id><published>2007-04-14T06:17:00.000+08:00</published><updated>2007-04-14T06:17:43.414+08:00</updated><title type='text'>预防措施</title><content type='html'>&lt;a href="http://www.danxirou.com/yufang/index.htm"&gt;预防措施&lt;/a&gt;: "★ 禁酒及含酒精类饮料&lt;br /&gt;　　酒精在体内主要通过肝脏分解、解毒，所以，酒精可直接损伤肝功能，引起肝胆功能失调，使胆汁的分泌、排出过程紊乱，从而刺激胆囊形成新的息肉及/或使原来的息肉增长、变大，增加胆囊息肉的癌变系数。&lt;br /&gt;　　★ 饮食要规律、早餐要吃好&lt;br /&gt;　　规律饮食、吃好早餐对胆囊息肉患者极其重要。人体内肝脏主管分泌胆汁，分泌的胆汁存储入胆囊内，而胆汁的功能主要是消化油性食物。如果不吃早餐，则晚上分泌的胆汁利用不上，存留于胆囊内"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-8727149602785563526?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.danxirou.com/yufang/index.htm' title='预防措施'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/8727149602785563526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=8727149602785563526' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8727149602785563526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8727149602785563526'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/blog-post.html' title='预防措施'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-1723399429463447422</id><published>2007-04-13T21:14:00.000+08:00</published><updated>2007-04-13T21:14:48.573+08:00</updated><title type='text'>11amDesign Tutorials and Articles - 101 Hidden Tips &amp; Secrets For Photoshop</title><content type='html'>&lt;p&gt;1. Press Tab will hide tool bar and palette, Shift+Tab will hide only palette.&lt;br /&gt;&lt;br /&gt;2. Hold Shift + click the top blue bar for toolbar and palette will move them to the nearest edge.&lt;br /&gt;&lt;br /&gt;3. Double click the top blue bar, on any palette window, to minimize it.&lt;br /&gt;&lt;br /&gt;4. Double click the gray background will bring up open file option, Hold Shift+double click will open up the browser.&lt;br /&gt;&lt;br /&gt;5. Sick of the default gray background around your image? Select paint bucket, hold shift and click on the gray background, it will change to whatever color you have in your foreground color box.&lt;br /&gt;&lt;br /&gt;6. In Photoshop, all "Cancel" buttons in a window can be changed to a "Reset" button by holding Alt.&lt;br /&gt;&lt;br /&gt;7. Caps lock will switch your cursor for accuracy.&lt;br /&gt;&lt;br /&gt;8. Press F button, it will switch between 3 different screen modes and give you more working area.&lt;br /&gt;&lt;br /&gt;9. To draw a straight line, click then move to the end point and hold shift + click.&lt;br /&gt;&lt;br /&gt;10. Hold Ctrl will temporary make any tool into move tool until you release Ctrl.&lt;br /&gt;&lt;br /&gt;11. Ctrl + Alt and click drag the image, it will make a duplication of the current image over lay on top.&lt;br /&gt;&lt;br /&gt;12. Hold Space bar, it will make any tool into "Hand Tool" until you release Space bar.&lt;br /&gt;&lt;br /&gt;13. While in Zoom Tool, Ctrl+space = zoom in, alt+space = zoom out.&lt;br /&gt;&lt;br /&gt;14. Hold Ctrl and press "+" or "-" it will change the % for image in navigator window.&lt;br /&gt;&lt;br /&gt;15. When Using eyedropper tool to capture foreground color, hold Alt and click, it will instantly capture the color for background.&lt;br /&gt;&lt;br /&gt;16. With Measure Tool, draw a line then hold Alt and draw another line from the end of the first line, it will measure the angle.&lt;br /&gt;&lt;br /&gt;17. Ctrl+Alt+Z and Ctrl+Shift+Z will go back and forth in the history.&lt;br /&gt;&lt;br /&gt;18. Alt+Backspace and Ctrl+Backspace will fill in the whole screen with foreground color or background color, Shift+backspace will bring up option window, Alt+Shift+Backspace and Ctrl+Shift+Backspace, will fill the image with foreground or background color but will leave the alpha transparent area alone.&lt;br /&gt;&lt;br /&gt;19. When free transforming with Ctrl+T, hold Alt to keep the original image and then to transform a duplicated layer of it. Ctrl+Shift+T to repeat whatever you did in the last transform.&lt;br /&gt;&lt;br /&gt;20. To make sure your Crop is on the edge of the image, hold Ctrl while cropping.&lt;br /&gt;&lt;br /&gt;21. Ctrl+J will duplicate the current layer.&lt;br /&gt;&lt;br /&gt;22. Ctrl+Shift+E will merge all visible layers to one layer, Ctrl+Shift+Alt+E will make a copy of the original and merge all visible layers.&lt;br /&gt;&lt;br /&gt;23. While using Marquee Tools, hold Alt it will make the starting point as a center of the selection.&lt;br /&gt;&lt;br /&gt;24. Ctrl + D to deselect, Ctrl+Shift+D to reselect what you deselected.&lt;br /&gt;&lt;br /&gt;25. While selecting with Marquee tool, pressing the space bar can allow you to move the selection.&lt;br /&gt;&lt;br /&gt;26. Hold Shift and press "+" or "-" it will switch between the layer mode:&lt;br /&gt;&lt;br /&gt;N = Normal&lt;br /&gt;I = Dissolve&lt;br /&gt;M = Multiply&lt;br /&gt;S = Screen&lt;br /&gt;O = Overlay&lt;br /&gt;F = Soft Light&lt;br /&gt;H = Hard Light&lt;br /&gt;D = Color Dodge&lt;br /&gt;B = Color Burn&lt;br /&gt;K = Darken&lt;br /&gt;G = Lighten&lt;br /&gt;E = Difference&lt;br /&gt;X = Exclusion&lt;br /&gt;U = Hue&lt;br /&gt;T = Saturation&lt;br /&gt;C = Color&lt;br /&gt;Y = Luminosity&lt;br /&gt;Q = Behind 1&lt;br /&gt;L = Threshold 2&lt;br /&gt;R = Clear 3&lt;br /&gt;W = Shadow 4&lt;br /&gt;V = Midtones 4&lt;br /&gt;Z = Highlights 4&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;***The shortcut works even for following situation:&lt;br /&gt;&lt;br /&gt;***Alpha turned off, Indexed Mode, Line tool, Bucket Tools, Dodge and Burn Tools&lt;br /&gt;&lt;br /&gt;27. While using Brush or any other tools, change the opacity by typing the number.&lt;br /&gt;&lt;br /&gt;*** type one number for % of it's ten times [4=40%]&lt;br /&gt;&lt;br /&gt;***type two number for exact % [press 7 then 2 will get 72%]&lt;br /&gt;&lt;br /&gt;28. Hold Alt while clicking on the eye icon beside the layer, it will hide all other layers.&lt;br /&gt;&lt;br /&gt;29. Hold Alt while clicking the pen icon beside the layer, it will unchain this layer from all layers.&lt;br /&gt;&lt;br /&gt;30. Select a layer, hold Alt and click the top edge of another layer, it will group them.&lt;br /&gt;&lt;br /&gt;31. Hold Alt and click the button "Create a new layer", it will create a new adjustment layer.&lt;br /&gt;&lt;br /&gt;32. Select a layer and hold Alt, then click on the garbage can button. It will instantly delete the layer, marquee where you want alpha and Ctrl+click the "Create new channel" button, it will create an alpha only on the area you marquee.&lt;br /&gt;&lt;br /&gt;33. File&gt; Automate &gt; Contact Sheet: this can create a small thumbnail for every file, this can save you some time from searching.&lt;br /&gt;&lt;br /&gt;34. When Move Tool is selected, toolbox on top can be useful from time to time, these are "Auto select layer" and "Show bounding box".&lt;br /&gt;&lt;br /&gt;35. While Move Tool is selected, hold Shift (Alt+Shift+Right click) and allow whether or not to make a current layer chain with your upper layer.&lt;br /&gt;&lt;br /&gt;36. With grid on, click the top left corner of the grid and drag to anywhere on the image to set the pivot, double clicking on the icon again reset the pivot.&lt;br /&gt;&lt;br /&gt;37. After, draw a path on the image with pen tool, Ctrl+shift+H can hide/show it.&lt;br /&gt;&lt;br /&gt;38. Control Navigator with keyboard sometimes can be more time efficient than mouse.&lt;br /&gt;&lt;br /&gt;***&lt;br /&gt;&lt;br /&gt;Home = move to top left corner&lt;br /&gt;End = move to right bottom corner&lt;br /&gt;PageUp = move up one page&lt;br /&gt;PageDown = move down one page&lt;br /&gt;Ctrl+PageUp = move left one page&lt;br /&gt;Ctrl+PageDown = move right one page&lt;br /&gt;Shift+PageUp = move up 10 pixel&lt;br /&gt;Shift+PageDown = move down 10 pixel&lt;br /&gt;Ctrl+Shift+PageUp = move left 10 pixel&lt;br /&gt;Ctrl+Shift+PageDown = move right 10 pixel&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;39. Ctrl+Tab allows you to switch between different image files you are working on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;40. F12 = Revert to how the file was the last time you saved it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;41. Shortcuts for Channel: RGB, CMYK, indexed color...&lt;br /&gt;&lt;br /&gt;***&lt;br /&gt;&lt;br /&gt;Ctrl+"~" = RGB&lt;br /&gt;Ctrl+1 = red&lt;br /&gt;Ctrl+2 = green&lt;br /&gt;Ctrl+3 = blue&lt;br /&gt;Ctrl+4 = other path&lt;br /&gt;Ctrl+9 = other path&lt;br /&gt;Ctrl+"~" = CMYK&lt;br /&gt;Ctrl+1 = light green&lt;br /&gt;Ctrl+2 = pink red&lt;br /&gt;Ctrl+3 = yellow&lt;br /&gt;Ctrl+4 = black&lt;br /&gt;Ctrl+5 = other path&lt;br /&gt;Ctrl+9 = other path&lt;br /&gt;Ctrl+1 = Indexed&lt;br /&gt;Ctrl+2 = other path&lt;br /&gt;Ctrl+9 = other path&lt;br /&gt;&lt;br /&gt;42. hold Ctrl then you can draw a red box in the Navigator thumbnail for viewing.&lt;br /&gt;&lt;br /&gt;43. Hold Alt and click on any of the history steps, that step will be copied and become the most recent one.&lt;br /&gt;&lt;br /&gt;44. Alt drag a step from a serial action can copy it to another action.&lt;br /&gt;&lt;br /&gt;45. Alt-click the flare preview thumb, and you can fill in numerical co-ordinates for lens flare.&lt;br /&gt;&lt;br /&gt;46. Holding Shift + Alt while transforming an object will do it proportionally, from the center.&lt;br /&gt;&lt;br /&gt;47. If you have the move tool selected and you want something duplicated just hold the alt key and move the image, holding the Shift + Alt while doing this, it will move it along one axis.&lt;br /&gt;&lt;br /&gt;48. If you want to straighten an image that is crooked (maybe from scanning), click on the eyedropper tool or hit the I key 3 times to get the ruler. Click on the left side of the straight edge, then the right side of the straight (but crooked) edge. The choose Image&gt; Rotate Canvas&gt; Arbitrary, Photoshop will give you the degrees of rotation you just click ok.&lt;br /&gt;&lt;br /&gt;49. If you create something in Illustrator, copy and paste it in Photoshop, it will ask you if you want this to be a pixel, path, or shape layer.&lt;br /&gt;&lt;br /&gt;50. If you have a mask on a layer and you want to place a image in there and keep the mask. Simply open the image, say copy, and then Ctrl click on the layer to select the mask and use Shift + Ctrl + V to paste it into the mask which will also put it on a new layer as well.&lt;br /&gt;&lt;br /&gt;51. To center an image, Ctrl + A , Ctrl + X, Ctrl + V, I think it also puts that image on a new layer.&lt;br /&gt;&lt;br /&gt;52. Ctrl+E will merge the highlighted layer down to the next&lt;br /&gt;&lt;br /&gt;53. When you have a brush selected, using [ or ] will scroll up or down that brush list.&lt;br /&gt;&lt;br /&gt;54. Double clicking the zoom tool will make the image 100%, double clicking the hand tool will fit the image to your screen resolution.&lt;br /&gt;55. Typing Content:&lt;br /&gt;&lt;br /&gt;Ctrl + H will hide the highlight on your selected type.&lt;br /&gt;&lt;br /&gt;If you click once while your type is selected on the font list, you can use your arrows to scroll up and down and see the fonts change on the fly!&lt;br /&gt;&lt;br /&gt;Alt + Left or Right arrows will change your tracking in increments of 10&lt;br /&gt;Ctrl + Alt + Left or Right arrows will change your tracking in increments of 100&lt;br /&gt;Ctrl + Alt + Up or Down arrows will change your leading in increments of 10 pts&lt;br /&gt;Shift + Ctrl with &lt;&gt; will change your font size in increments of 2 pts&lt;br /&gt;&lt;br /&gt;56. Ctrl + Alt + T to make a copy of the layer in which you want to transform.&lt;br /&gt;&lt;br /&gt;57. Ctrl + Alt + Right arrow. duplicates the layer you are on.&lt;br /&gt;&lt;br /&gt;58. Change the active layer : Alt + [ or ].&lt;br /&gt;&lt;br /&gt;59. Move the active layer up and down : Ctrl + [ or ].&lt;br /&gt;&lt;br /&gt;60. Link 2 layers: with move tool click in the first layer hold Shift and click in the second one.&lt;br /&gt;&lt;br /&gt;61. Ctrl+[plus key] will let you zoom in on an image anytime while Ctrl+[minus key] zooms out. Ctrl+Alt+[plus key] will zoom in AND RESIZE the window to fit the image size... same for Ctrl+Alt+[minus key] as well.&lt;br /&gt;&lt;br /&gt;62. When using the Polygonal Lasso Tool, click backspace to undo a lasso step.&lt;br /&gt;&lt;br /&gt;63. Pressing X will switch the selected foreground and background colors.&lt;br /&gt;&lt;br /&gt;64. Pressing D will reset the foreground and backgrounds colors to black and white.&lt;br /&gt;&lt;br /&gt;65. If your image has multiple layers, create a Marquee selection and press Ctrl+Shift+Cit won't work if you selected a hidden layer) will copy the image into memory as if they were flattened! Paste it on a new document to see the result.&lt;br /&gt;&lt;br /&gt;66. Ctrl+Alt+Z will do multiple undo, versus just one.&lt;br /&gt;&lt;br /&gt;67. Ctrl+click a layer thumbnail to select the layer transparency&lt;br /&gt;&lt;br /&gt;68. To see what your layer mask looks like (and edit it), Alt+click its thumbnail in the layers palette&lt;br /&gt;&lt;br /&gt;69. Press and hold Ctrl+Alt and click the Help bar with your mouse, drag it down and highlight "About Photoshop" and let go of the left mouse button for a different About Photoshop splash/screen.&lt;br /&gt;&lt;br /&gt;70. When using Polygon lasso tool hold Shift to make a perfect line, it goes every 30 degrees&lt;br /&gt;&lt;br /&gt;71.Photoshop CS2: Group many layers by clicking the layers you want to group by clicking it while holding the Shift key down, and then press Ctrl+G to group them into a folder for means of better organization.&lt;br /&gt;&lt;br /&gt;72. Ctrl+Shift+N creates a new layer with a dialog box; Ctrl+Shift+Alt+N gets you a new layer without the hassle.&lt;br /&gt;&lt;br /&gt;73. Back to brush, [ and ] will increase/decrease your brush size, Shift + [ or ] will soften or harden your brush edge.&lt;br /&gt;&lt;br /&gt;74. Still in [ and ], Ctrl + [ or ] will move your currently selected layer up and down the hierarchy and Shift + [ or ] will select upper layer or lower layer.&lt;br /&gt;&lt;br /&gt;75. Stamp Tool (s) is used to copy an area of image (defined by alt+clicking and area) and paint it somewhere else (cloning). It also works when you have multiple images open at the same time. Alt click an area of any opened file image and paint it anywhere else.&lt;br /&gt;&lt;br /&gt;76. After you created a text you can click on font type tab and tap "down" key over and over to scroll through the font list and see the changes in (relatively) real time. A feature that I am tired of waiting to happen in illustrator.&lt;br /&gt;&lt;br /&gt;77. Still in text mode, a trick from Microsoft word to apply hi-light to your text hit Ctrl+Shift+ &lt;&gt; to resize your text, to your preferred font size. Pressing Ctrl key while you are typing also gives you a free transform box temporarily and will go if you release it. Resizing text also works by pressing Ctrl+T (on selected layer, not when you are typing). It still retains as an editable text layer after.&lt;br /&gt;&lt;br /&gt;78. And remember, pressing enter when you type will take you to a new line just like typing a letter but pressing Ctrl+Enter or Enter on numeric key will finish what you type.&lt;br /&gt;&lt;br /&gt;79. You can drag a layer on to any other opened images in Photoshop and it will copy it as a layer (better than copy and paste image). Holding down Shift while moving it will snap the image right on the center of the other opened image&lt;br /&gt;&lt;br /&gt;80. If you are working with sets....&lt;br /&gt;&lt;br /&gt;Click on the set, in the blending mode it shows pass through by default... if you have an adjustment layer within a set and you want that adjustment layer to effect those layers underneath it within the set only, set the blending mode of the set to "normal" instead.&lt;br /&gt;&lt;br /&gt;CODE&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Mentioned before with more explanation:&lt;br /&gt;&lt;br /&gt;- Pressed F to switch to 3 different viewing mode... when I first try it I said "wtf? what it's for?" Well, if you are sick of painting your image on the corners just to find yourself resizing your current image window, with F you can pan way outside your image. Happy corner painting!!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;- Create a new file, 500x500 px, create a new layer, get a standard brush and paint a dot on the top center of your image (like the number 12 position on a clock). Press Ctrl+Alt+T, it will duplicate your original layer and free transform the new one. Move the pivot point (the circle with little dot in it found when you are free transforming something) to the center of your image, rotate your image 30 degrees to the right and hit OK to confirm the transform&lt;br /&gt;&lt;br /&gt;now.........&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Be excited..........&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Hit Ctrl+Shift+Alt+T 10 times and see what happens!&lt;br /&gt;&lt;br /&gt;81. When using the "move tool" you can select any layer by holding down the CTL key(CMD on a Mac) and clicking on the part of the layer on the canvas with your mouse. This way you won't have to go to the Layers palette every time and you don't have to keep checking on or off the auto select options for the move tool.&lt;br /&gt;&lt;br /&gt;82. You can link up layers without going into the layers palette, by selecting the layer (how I just mentioned above) and holding down CTL + Shift(CMD + SHIT on a Mac) for each additional layer you want to link up. You can unlink them by clicking on the layer again.&lt;br /&gt;&lt;br /&gt;83. You can delete more than one layer at a time.......by linking up all the layer you want to delete, and holding down CTL(CMD on a Mac) while you click on the garbage icon to delete the layer.&lt;br /&gt;&lt;br /&gt;84. When using the type tool you can ok it by pressing CTL + Enter(CMD + Enter on a Mac) instead of clicking on the check mark on the options.&lt;br /&gt;&lt;br /&gt;85. If you have more than one type layer, and want to make any of the following changes color/font/size/alignment/initializing to all of the type layers at the same time.....All you have to do is link up the type layer, hold down the Shift key and in the options for the type tool make your change i.e. color, size, etc.&lt;br /&gt;&lt;br /&gt;86. You can use your number pad to change opacity for a layer.... I.e. type 5 and the opacity will be 50; type 55 and the opacity will be 55. You can use the number pad for any tool that uses opacity...like the airbrush tool, stamp tool, brush, gradient, etc.&lt;br /&gt;&lt;br /&gt;87. Pressing Tab key will hide the Tools palette and any other palette that you have on the stage. Pressing "F" will change between Full Screen modes. Using these two tips you can view your work Full Screen without any palettes.(You can press CTL+Alt+0 to fit your work to the screen, or you can press CTL+0 to zoom to 100%)&lt;br /&gt;&lt;br /&gt;88. Pressing the "+" and "-" keys while holding down CTL+Alt will resize the whole document window, not just the work area.&lt;br /&gt;&lt;br /&gt;89. You can delete a layer by holding down the "Alt" key and pressing "L" twice......actually now with Photoshop 7 you got to press "L" three times. It's not actually a keyboard shortcut, but it's a quick way to do it....don't know if it works on a MAC.&lt;br /&gt;&lt;br /&gt;90. Pan documents with the space bar.&lt;br /&gt;&lt;br /&gt;91. Ctrl+click a layer (in layers palette) to select it's transparency.&lt;br /&gt;&lt;br /&gt;92. Ctrl+Alt+click between 2 layers in the palette to group them.&lt;br /&gt;&lt;br /&gt;93. Alt + click in “add layer mask” button to add a black layer mask (instead of a white one).&lt;br /&gt;&lt;br /&gt;94. When you select something, pressing Ctrl+J will copy the selected area and add another layer with the copied area - opposing copying the layer, making a new layer, and pasting it.&lt;br /&gt;&lt;br /&gt;95. To glue the palettes together (all palettes combined into one strip), you just drag &amp; drop a palette onto the end of another palette (watch the rectangle that indicates where the palette will get attached to).&lt;br /&gt;&lt;br /&gt;96. Hold down Alt while Burning to Dodge instead, and vice versa.&lt;br /&gt;&lt;br /&gt;97. Ctrl-click a layer to select an objects; alternatively, you may select more than one object/s in more than 1 layer by holding Shift while using the method just mentioned (Ctrl-click). To deselect, just press Ctrl+D.&lt;br /&gt;&lt;br /&gt;98. If you have a mini scroll on your mouse, you may use that to zoom in (scroll up) or zoom out (scroll down).&lt;br /&gt;&lt;br /&gt;99. Need to locate a layer quick? Use the Move Tool (V) and right click on the area the object lays. There should now be a “cursor-menu” with all the layers that is in that particular area. Now take a good guess and see which one of them fits the shoe; select a layer and Ctrl-Click the layer in the Layer Palette - see if the selection traces the object you desired to edit/find. Useful for those messy people (i.e. me!).&lt;br /&gt;&lt;br /&gt;100. Need to get rid of a background quick? Assuming you at least know how to crop around an object, do so. Now press Ctrl+I or Shift+Ctrl+I for Inverse Selection. Press Ctrl+X to %@#!* that part out, and you should be left with the object!&lt;br /&gt;&lt;br /&gt;101. Want to save the time from loading All your Photoshop brushes, when your Photoshop accidentally forgets to load them up (happens to me sometimes)? Select the brush tool, and click the little arrow pointing right (located at the top toolbar), next to the Master Diameter tick. Go down to Preset Manager and now there should be a menu of all the brushes currently loaded. Click on the first brush (top left) and scroll down to the bottom. Now hold Shift and click the last brush (bottom right). This should highlight all the brushes. See the “Save Set” to the right in the menu? Click that and name your brush set whatever you want, for this matter I just name it All (so I remember that this brush set contains all the brushes I currently have loaded, and is located near the top when loading the brushes up). &lt;/p&gt;     &lt;!-- /Article --&gt;&lt;!-- Article Categories Listing --&gt;&lt;!-- /Article Categories Listing --&gt;                      &lt;!-- Article Info --&gt;     &lt;p&gt;Last update: 2007-03-22 07:13&lt;br /&gt;Author: Gary Logsdon&lt;br /&gt;Revision: 1.0&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-1723399429463447422?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://browseatwork.com/nph-proxy.cgi/000000A/http/www.11amdesign.com/faq/index.php?sid=1708%C3%A2%C5%92%C2%A9=en&amp;action=artikel&amp;cat=1&amp;id=343&amp;artlang=en' title='11amDesign Tutorials and Articles - 101 Hidden Tips &amp; Secrets For Photoshop'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/1723399429463447422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=1723399429463447422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1723399429463447422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1723399429463447422'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/11amdesign-tutorials-and-articles-101.html' title='11amDesign Tutorials and Articles - 101 Hidden Tips &amp; Secrets For Photoshop'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-1148567033884036481</id><published>2007-04-12T14:52:00.000+08:00</published><updated>2007-04-12T14:52:34.143+08:00</updated><title type='text'>EJSChart :: 100% Pure JavaScript Charting Solution</title><content type='html'>&lt;a href="http://www.ejschart.com/index.php"&gt;EJSChart :: 100% Pure JavaScript Charting Solution&lt;/a&gt;: "# Interactive: Features such as Hints, Mouse Tracking, Mouse Events, Key Tracking and Events, Zooming, Scrolling, and Crosshairs raise interactivity and user experience in web charting to a new level.&lt;br /&gt;# Sample Area ChartAxis Scaling: There's no need to determine your data range before hand. EJSChart will calculate and scale automatically to fit whatever data it is presented with.&lt;br /&gt;# Auto Zooming, Scrolling: Too much data and not enough screen real estate? Show it all. Let your end users zoom in on the pieces they're most interested in. Axis locking for single axis zoom, scrolling and automatic axis scaling are all included.&lt;br /&gt;# Sample Stacked ChartStackable Series: Multiple chart series can be stacked and combined to fit many charting needs.&lt;br /&gt;# Multiple Chart Types: Line, Area, Scatter, Pie, Bar and Function series are just the beginning. New series are just a few lines of JavaScript code away."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-1148567033884036481?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.ejschart.com/index.php' title='EJSChart :: 100% Pure JavaScript Charting Solution'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/1148567033884036481/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=1148567033884036481' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1148567033884036481'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1148567033884036481'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/ejschart-100-pure-javascript-charting.html' title='EJSChart :: 100% Pure JavaScript Charting Solution'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-3643141636421977215</id><published>2007-04-08T10:57:00.000+08:00</published><updated>2007-04-08T10:57:32.704+08:00</updated><title type='text'>怎样让Delphi做出来的程序在任务栏上显示不止一个按钮？</title><content type='html'>&lt;a href="http://topic.csdn.net/t/20050614/16/4082020.html"&gt;&lt;/a&gt;&lt;br /&gt;主　　题：      怎样让Delphi做出来的程序在任务栏上显示不止一个按钮？  &lt;br /&gt;       &lt;br /&gt;  怎样让Delphi做出来的程序在任务栏上显示不止一个按钮？  &lt;br /&gt;  我想让一个不是主窗口的窗口在任务栏上显示一个按钮，以便和主窗口来回切换，怎么办？  &lt;br /&gt;&lt;br /&gt;    &lt;br /&gt;       &lt;br /&gt;  回复人：   u2m(breeze_wang)   (   )   信誉：125      2003-04-12   13:34:15Z      得分:0        &lt;br /&gt;       &lt;br /&gt;       &lt;br /&gt;  在Delphi中我们可以静态或动态地创建窗体，所谓静态创建窗体是指在设计程序时一并建好窗体，动态创建是指在程序运行时根据需要使用Create方法 创建新窗体,然后使用Show方法来显示窗体。但令人遗憾的是，在显示非启动窗体时，不论用户在程序中创建多少个窗体，每个应用程序只能有一个程序图标， 在Windows的任务条上只显示一个程序图标。  &lt;br /&gt;  在编写应用程序时，有时我们需要同一应用程序显示两个程序图标，那么如何实现呢？我们只需重载窗体的CreateParams过程即可实现，下面以一个示例来说明如何使用。  &lt;br /&gt;  　  &lt;br /&gt;  一、应用实例  &lt;br /&gt;  　  &lt;br /&gt;  在Delphi集成环境中创建两个窗体，其中窗体一为主窗体，即程序启动窗体，在其上添加显示窗体二的按钮。因为要让窗体显示的同时在任务栏上再显示一个 程序图标，为了区别，将窗体二的图标更换，然后在窗体二的private部分声明重载CreateParams过程：  &lt;br /&gt;  unit   Unit2;  &lt;br /&gt;  ……  &lt;br /&gt;  private  &lt;br /&gt;  {   Private   declarations   }  &lt;br /&gt;  procedure   CreateParams(var   Params:   TCreateParams);   override;  &lt;br /&gt;  最后在单元文件的实现部分（Implementation）添加重载过程的实现代码：  &lt;br /&gt;  procedure   TForm2.CreateParams(VAR   Params:   TCreateParams);  &lt;br /&gt;  begin  &lt;br /&gt;  Inherited   CreateParams(Params);  &lt;br /&gt;  Params.WndParent   :=   GetDesktopWindow;  &lt;br /&gt;  end;  &lt;br /&gt;  运行程序中，当按下启动窗体中的“显示窗口二”按钮时，会显示窗体二，并且在Windows的任务栏上同时会出现一个新的程序图标，如图1所示。  &lt;br /&gt;  　  &lt;br /&gt;  二、程序分析  &lt;br /&gt;  　  &lt;br /&gt;  当程序需要创建一个窗体、向系统发出要创建一个新窗体的WM_CREATE消息时，系统将指示程序调用CreateWnd方法来创建窗体， CreateWnd方法在创建窗体前，需要调用CreateParams过程来获得窗体的初始化参数，在获得这些参数后，最后再调用 CreateWindowHandle方法创建一个窗体句柄，完成了一个窗体的创建工作。因此，如果我们要使某一窗体在任务栏上显示程序图标，就需要修改 窗体的初始化参数，重载CreateParams过程。  &lt;br /&gt;  程序窗口的初始化参数被封装成一个TCreateParams类型的对象，该类型的定义如下所示：  &lt;br /&gt;  type  &lt;br /&gt;  TCreateParams   =   record  &lt;br /&gt;  {窗体的标题文字}  &lt;br /&gt;  Caption:   PChar;  &lt;br /&gt;  {窗体的类型，比如WS_CHILD   、WS_DISABLED等}  &lt;br /&gt;  Style:   DWORD;  &lt;br /&gt;  {扩展的窗体类型}  &lt;br /&gt;  ExStyle:   DWORD;  &lt;br /&gt;  {窗体的左上角位置}  &lt;br /&gt;  X,   Y:   Integer;  &lt;br /&gt;  {窗体的宽、高}  &lt;br /&gt;  Width,   Height:   Integer;  &lt;br /&gt;  {该窗体的父窗体句柄}  &lt;br /&gt;  WndParent:   HWND;  &lt;br /&gt;  {指向WM_CREATE消息LParam参数}  &lt;br /&gt;  Param:   Pointer  &lt;br /&gt;  {该类包含了一些与窗体有关的信息，如鼠标光标、选单等}  &lt;br /&gt;  WindowClass:   TWndClass;  &lt;br /&gt;  {该窗体的类名}  &lt;br /&gt;  WinClassName:   array[0..63]   of   Char;  &lt;br /&gt;  end;  &lt;br /&gt;  CreateParams过程是当窗体创建时执行，它初始化窗体创建的参数记录。所以如果要显示某一窗体的图标，必须要提高该窗体的级别，即将它的父窗体 置为Windows的桌面，桌面的句柄可以通过API函数GetDesktopWindow来获得，因此只要我们在重载函数体中添加语句 “Params.WndParent  &lt;br /&gt;  :=   GetDesktopWindow;”，就可以实现窗体的图标显示，正如上例所演示的那样。&lt;br /&gt;&lt;br /&gt;对MDI子窗口：&lt;br /&gt;procedure   TForm2.Button1Click(Sender:   TObject);  &lt;br /&gt;  var   hd:hwnd;  &lt;br /&gt;  begin  &lt;br /&gt;        hd:=GetDesktopWindow();  &lt;br /&gt;        windows.SetParent(self.Handle,hd);  &lt;br /&gt;        self.WindowState:=wsMinimized;  &lt;br /&gt;  end;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-3643141636421977215?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://topic.csdn.net/t/20050614/16/4082020.html' title='怎样让Delphi做出来的程序在任务栏上显示不止一个按钮？'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/3643141636421977215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=3643141636421977215' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3643141636421977215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3643141636421977215'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/delphi.html' title='怎样让Delphi做出来的程序在任务栏上显示不止一个按钮？'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-4283871463006470241</id><published>2007-04-07T00:46:00.000+08:00</published><updated>2007-04-07T00:46:36.231+08:00</updated><title type='text'>FullerScreen :: Firefox Add-ons</title><content type='html'>&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/4650"&gt;FullerScreen :: Firefox Add-ons&lt;/a&gt;: "This extension enhances the Full Screen mode into a really full screen mode, hiding the remaining toolbars and statusbar and making them visible again when the mouse pointer hits an edge of the screen.&lt;br /&gt;&lt;br /&gt;This cross-platform extension is tested on Windows and Linux, should work fine on Mac, and is licensed under the Mozilla Public License."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-4283871463006470241?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://addons.mozilla.org/en-US/firefox/addon/4650' title='FullerScreen :: Firefox Add-ons'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/4283871463006470241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=4283871463006470241' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4283871463006470241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4283871463006470241'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/fullerscreen-firefox-add-ons.html' title='FullerScreen :: Firefox Add-ons'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-7342298859753976447</id><published>2007-04-06T04:04:00.000+08:00</published><updated>2007-04-06T04:04:39.655+08:00</updated><title type='text'>ADG (IndySSL)</title><content type='html'>&lt;a href="http://adg.bmpcoe.org/IndySSL/"&gt;ADG (IndySSL)&lt;/a&gt;: "SIMPLE INDY 9/10 SSL CLIENT AND SERVER EXAMPLES&lt;br /&gt;&lt;br /&gt;Written by Ralph Sickinger, Best Manufacturing Practices Center of Excellence (BMPCOE)&lt;br /&gt;&lt;br /&gt;e-mail: ralph @ bmpcoe.org&lt;br /&gt;&lt;br /&gt;SSL CLIENT:&lt;br /&gt;This program is a simple TCP Client that makes an SSL connection on port 3000. To connect to a server, enter the IP address of the server in the box labeled 'Host:', and then press the 'Connect' button. Once a connection has been established, the client displays any text received from the server in the memo area. To send text to the server, enter it in the available edit box, and then press [enter].&lt;br /&gt;&lt;br /&gt;SSL SERVER:&lt;br /&gt;This program establishes a TCP Server that listens for SSL connections on port 3000. When a connection is received, the server responds with 'Hello', and then listens for any other lines of text sent from the client. When a line is received, it is echoed to the screen as well as back to the client.&lt;br /&gt;&lt;br /&gt;Note: in order to run this program, you must have libeay32.dll and ssleay32.dll installed where the application can find them (either in the Windows System32 folder, or in the same folder as the application itself. These files can be downloaded from: http://indy.fulgan.com/SSL/ The server also requires that the certificate files (sample.crt, sample.key, and sampleRoot.pem) be available in the same folder as the excutable."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-7342298859753976447?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://adg.bmpcoe.org/IndySSL/' title='ADG (IndySSL)'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/7342298859753976447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=7342298859753976447' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7342298859753976447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7342298859753976447'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/04/adg-indyssl.html' title='ADG (IndySSL)'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-8594959804267806991</id><published>2007-03-29T09:36:00.000+08:00</published><updated>2007-03-29T09:36:43.047+08:00</updated><title type='text'>InfoQ: Introduction to JBoss Seam</title><content type='html'>&lt;a href="http://www.infoq.com/articles/jboss-seam"&gt;InfoQ: Introduction to JBoss Seam&lt;/a&gt;: "JBoss Seam is a 'lightweight framework for Java EE 5.0'. What does that mean? Isn't Java EE (Enterprise Edition) 5.0 itself a collection of 'frameworks'? Why do you need another one that is outside of the official specification? Well, we view Seam as the 'missing framework' that should have been included in Java EE 5.0. It sits on top of Java EE 5.0 frameworks to provide a consistent and easy-to-understand programming model for all components in an enterprise web application. It also makes stateful applications and business process-driven applications a breeze to develop. In another words, Seam is all about developer productivity and application scalability."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-8594959804267806991?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.infoq.com/articles/jboss-seam' title='InfoQ: Introduction to JBoss Seam'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/8594959804267806991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=8594959804267806991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8594959804267806991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8594959804267806991'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/infoq-introduction-to-jboss-seam.html' title='InfoQ: Introduction to JBoss Seam'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-1800358515146570450</id><published>2007-03-29T09:14:00.000+08:00</published><updated>2007-03-29T09:14:05.780+08:00</updated><title type='text'>Pure servlets: Rethink the view</title><content type='html'>&lt;a href="http://www-128.ibm.com/developerworks/java/library/j-pureserv/?ca=dgr-jw22PureServletGUI"&gt;Pure servlets: Rethink the view&lt;/a&gt;: "For Web pages with dynamic content, Java™Server Pages (JSP) technology is touted as a means of separating the developer's concerns from those of the UI designer. Unfortunately, JSP is too complex for many designers, so Java developers tend to handle the JSP code themselves, often with unsatisfactory results. This article demonstrates the advantages of an unorthodox alternative: using simple helper objects to build a Web interface based on servlets alone."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-1800358515146570450?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www-128.ibm.com/developerworks/java/library/j-pureserv/?ca=dgr-jw22PureServletGUI' title='Pure servlets: Rethink the view'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/1800358515146570450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=1800358515146570450' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1800358515146570450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1800358515146570450'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/pure-servlets-rethink-view.html' title='Pure servlets: Rethink the view'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-6850127066485600241</id><published>2007-03-27T09:32:00.000+08:00</published><updated>2007-03-27T09:32:51.498+08:00</updated><title type='text'>LocalApplicationSamePlaceSuite - xmpp4moz - XMPP for Mozilla - Trac</title><content type='html'>&lt;a href="http://dev.hyperstruct.net/xmpp4moz/wiki/LocalApplicationSamePlaceSuite"&gt;LocalApplicationSamePlaceSuite - xmpp4moz - XMPP for Mozilla - Trac&lt;/a&gt;: "SamePlace is a set of extensions for Firefox, Flock and Thunderbird to keep in touch, chat, play and interact with your contacts without leaving your browser or mail client."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-6850127066485600241?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://dev.hyperstruct.net/xmpp4moz/wiki/LocalApplicationSamePlaceSuite' title='LocalApplicationSamePlaceSuite - xmpp4moz - XMPP for Mozilla - Trac'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/6850127066485600241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=6850127066485600241' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6850127066485600241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6850127066485600241'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/localapplicationsameplacesuite-xmpp4moz.html' title='LocalApplicationSamePlaceSuite - xmpp4moz - XMPP for Mozilla - Trac'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-5275297549131962837</id><published>2007-03-27T04:43:00.000+08:00</published><updated>2007-03-27T04:43:14.253+08:00</updated><title type='text'>Anonymouser :: Firefox Add-ons</title><content type='html'>&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1415"&gt;Anonymouser :: Firefox Add-ons&lt;/a&gt;: "Open link anonymously with...&lt;br /&gt;&lt;br /&gt;Open link anonymously with anonymouse.org"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-5275297549131962837?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://addons.mozilla.org/en-US/firefox/addon/1415' title='Anonymouser :: Firefox Add-ons'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/5275297549131962837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=5275297549131962837' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5275297549131962837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5275297549131962837'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/anonymouser-firefox-add-ons.html' title='Anonymouser :: Firefox Add-ons'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-4528580299623108806</id><published>2007-03-27T04:42:00.000+08:00</published><updated>2007-03-27T04:42:26.673+08:00</updated><title type='text'>ReloadEvery :: Firefox Add-ons</title><content type='html'>&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/115"&gt;ReloadEvery :: Firefox Add-ons&lt;/a&gt;: "Reloads web pages every so many seconds or minutes. The function is accessible via the context menu (menu you get when you right click on a web page) or via a drop down menu on the reload button ...&lt;br /&gt;&lt;br /&gt;Reloads web pages every so many seconds or minutes. The function is accessible via the context menu (menu you get when you right click on a web page) or via a drop down menu on the reload button&lt;br /&gt;&lt;br /&gt;Keywords: auto refresh, auto reload"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-4528580299623108806?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://addons.mozilla.org/en-US/firefox/addon/115' title='ReloadEvery :: Firefox Add-ons'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/4528580299623108806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=4528580299623108806' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4528580299623108806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4528580299623108806'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/reloadevery-firefox-add-ons.html' title='ReloadEvery :: Firefox Add-ons'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-8139614623963813226</id><published>2007-03-27T03:06:00.000+08:00</published><updated>2007-03-27T03:06:06.248+08:00</updated><title type='text'>Tempomail :: Firefox Add-ons</title><content type='html'>&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3883"&gt;Tempomail :: Firefox Add-ons&lt;/a&gt;: "Create temporary email adresses to prevent your mailbox from...&lt;br /&gt;&lt;br /&gt;Create temporary email adresses to prevent your mailbox from spam&lt;br /&gt;Works with:"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-8139614623963813226?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://addons.mozilla.org/en-US/firefox/addon/3883' title='Tempomail :: Firefox Add-ons'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/8139614623963813226/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=8139614623963813226' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8139614623963813226'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8139614623963813226'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/tempomail-firefox-add-ons.html' title='Tempomail :: Firefox Add-ons'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-9026274132649663401</id><published>2007-03-27T02:44:00.000+08:00</published><updated>2007-03-27T02:44:37.268+08:00</updated><title type='text'>IE Tab :: Firefox Add-ons</title><content type='html'>&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1419"&gt;IE Tab :: Firefox Add-ons&lt;/a&gt;: "IE Tab - an extension from Taiwan, features: Embedding Internet Explorer in tabs of Mozilla/Firefox...&lt;br /&gt;&lt;br /&gt;This is a great tool for web developers, since you can easily see how your webpage displayed in IE with just one click and then switch back to Firefox.&lt;br /&gt;&lt;br /&gt;If you need some instructions.&lt;br /&gt;Please visit our official website on http://ietab.mozdev.org"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-9026274132649663401?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://addons.mozilla.org/en-US/firefox/addon/1419' title='IE Tab :: Firefox Add-ons'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/9026274132649663401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=9026274132649663401' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/9026274132649663401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/9026274132649663401'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/ie-tab-firefox-add-ons.html' title='IE Tab :: Firefox Add-ons'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-5280767937421236788</id><published>2007-03-27T02:33:00.000+08:00</published><updated>2007-03-27T02:33:54.749+08:00</updated><title type='text'>BrowseAtWork :: Firefox Add-ons</title><content type='html'>&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2059"&gt;BrowseAtWork :: Firefox Add-ons&lt;/a&gt;: "Allows you to open the current page, or a link on the current page, anonymously with BrowseAtWork.com by adding a shortcut to the context menu...&lt;br /&gt;&lt;br /&gt;Allows you to open the current page, or a link on the current page, anonymously with BrowseAtWork.com by adding a shortcut to the context menu.&lt;br /&gt;Ideal for viewing webpages blocked by many corporate or school filters. Licensed under the GNU GPL.&lt;br /&gt;&lt;br /&gt;*~* Please see the developer comments for information regarding support queries. Thanks. *~*"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-5280767937421236788?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://addons.mozilla.org/en-US/firefox/addon/2059' title='BrowseAtWork :: Firefox Add-ons'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/5280767937421236788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=5280767937421236788' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5280767937421236788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5280767937421236788'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/browseatwork-firefox-add-ons.html' title='BrowseAtWork :: Firefox Add-ons'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-8595935013879004196</id><published>2007-03-27T01:13:00.000+08:00</published><updated>2007-04-28T17:02:57.094+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>Dictionary Tooltip :: Firefox Add-ons</title><content type='html'>&lt;a href="https://addons.mozilla.org/en-US/firefox/addon/1171"&gt;Dictionary Tooltip :: Firefox Add-ons&lt;/a&gt;: "Press ctrl+shift+D (or) double-click (or) right-click after selecting a word to see its meaning. This extension is ideal for those who doesn't like to switch their window to see the meaning of a word. ...&lt;br /&gt;&lt;br /&gt;Press ctrl+shift+D (or) double-click (or) right-click after selecting a word to see its meaning. This extension is ideal for those who doesn't like to switch their window to see the meaning of a word.&lt;br /&gt;&lt;br /&gt;If you have problems like "Error opening input stream (invalid filename?", install v1.1.3 from the website. Especially Mac users, please install it from my website. Report any other bugs via email.&lt;br /&gt;&lt;br /&gt;New version released on the website at http://www.rjonna.com/ext/dictionarytip.php"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-8595935013879004196?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/8595935013879004196/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=8595935013879004196' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8595935013879004196'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8595935013879004196'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/dictionary-tooltip-firefox-add-ons.html' title='Dictionary Tooltip :: Firefox Add-ons'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-7027803844370352220</id><published>2007-03-23T23:10:00.000+08:00</published><updated>2007-03-23T23:10:35.535+08:00</updated><title type='text'>dhtmlxGrid - sortable Javascript DHTML grid with rich script API</title><content type='html'>&lt;a href="http://scbr.com/docs/products/dhtmlxGrid/index.shtml"&gt;dhtmlxGrid - sortable Javascript DHTML grid with rich script API&lt;/a&gt;: "dhtmlxGrid is a Ajax-enabled JavaScript grid control that provides professional solution for representing and editing tabular data on the web. Carefully designed, with powerful script API, this editable DHTML grid is easy configurable with XML or js methods and shows convincing results working with large amounts of data.&lt;br /&gt;&lt;br /&gt;dhtmlxGrid allows easy implementation of nice looking (managed through css or predefined skins) DHTML tables with rich in-cell editing, fixed multiline headers/footers, resizable, sortable and draggable columns. Numerous event handlers let you add necessary interactivity to grid-based interfaces. Smart Rendering technology and built-in paginal output allow this data grid to work effectively with huge datasets."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-7027803844370352220?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://scbr.com/docs/products/dhtmlxGrid/index.shtml' title='dhtmlxGrid - sortable Javascript DHTML grid with rich script API'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/7027803844370352220/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=7027803844370352220' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7027803844370352220'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7027803844370352220'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/dhtmlxgrid-sortable-javascript-dhtml.html' title='dhtmlxGrid - sortable Javascript DHTML grid with rich script API'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-5839202741446384569</id><published>2007-03-11T23:23:00.000+08:00</published><updated>2007-03-11T23:23:44.514+08:00</updated><title type='text'>Passing Information to a Method or a Constructor (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)</title><content type='html'>&lt;a href="http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html"&gt;Passing Information to a Method or a Constructor (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)&lt;/a&gt;: "Arbitrary Number of Arguments&lt;br /&gt;You can use a construct called varargs to pass an arbitrary number of values to a method. You use varargs when you don't know how many of a particular type of argument will be passed to the method. It's a shortcut to creating an array manually (the previous method could have used varargs rather than an array)."&lt;br /&gt;&lt;br /&gt;&lt;h3 fmstyle="C-Head"&gt;Arbitrary Number of Arguments&lt;/h3&gt;   You can use a construct called &lt;em&gt;varargs&lt;/em&gt; to pass an arbitrary number of values to a method.  You use varargs when you don't know how many of a particular type of argument will be passed to the method. It's a shortcut to creating an array manually (the previous method could have used varargs rather than an array). &lt;p&gt; To use varargs, you follow the type of the last parameter by an ellipsis (three dots, ...),  then a space, and the parameter name. The method can then be called with any number of that parameter, including none. &lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;public Polygon polygonFrom(Point... corners) {&lt;br /&gt;   int numberOfSides = corners.length;&lt;br /&gt;   double squareOfSide1, lengthOfSide1;&lt;br /&gt;   squareOfSide1 = (corners[1].x - corners[0].x)*(corners[1].x - corners[0].x)&lt;br /&gt;   + (corners[1].y - corners[0].y)*(corners[1].y - corners[0].y) ;&lt;br /&gt;   lengthOfSide1 = Math.sqrt(squareOfSide1);&lt;br /&gt;   // more method body code follows that creates&lt;br /&gt;   // and returns a polygon connecting the Points&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt; You can see that, inside the method, &lt;code&gt;corners&lt;/code&gt; is treated like an array.  The method can be called either with an array or with a sequence of arguments. The code in the method body will treat the parameter as an array in either case. &lt;p&gt; You will most commonly see varargs with the printing methods; for example, this &lt;code&gt;printf&lt;/code&gt; method: &lt;/p&gt;&lt;blockquote&gt;&lt;pre&gt;public PrintStream printf(String format, Object... args)&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt; allows you to print an arbitrary number of objects. It can be called like this: &lt;blockquote&gt;&lt;pre&gt;System.out.printf("%s: %d, %s%n", name, idnum, address);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt; or like this &lt;blockquote&gt;&lt;pre&gt;System.out.printf("%s: %d, %s, %s, %s%n", name, idnum, address, phone, email);&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt; or with yet a different number of arguments.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-5839202741446384569?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://java.sun.com/docs/books/tutorial/java/javaOO/arguments.html' title='Passing Information to a Method or a Constructor (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/5839202741446384569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=5839202741446384569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5839202741446384569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5839202741446384569'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/passing-information-to-method-or.html' title='Passing Information to a Method or a Constructor (The Java™ Tutorials &gt; Learning the Java Language &gt; Classes and Objects)'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-2427852452996512800</id><published>2007-03-11T01:22:00.000+08:00</published><updated>2007-03-11T01:22:48.217+08:00</updated><title type='text'>Equality, Relational, and Conditional Operators (The Java™ Tutorials &gt; Learning the Java Language &gt; Language Basics)</title><content type='html'>&lt;a href="http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op2.html"&gt;Equality, Relational, and Conditional Operators (The Java™ Tutorials &gt; Learning the Java Language &gt; Language Basics)&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;The Type Comparison Operator instanceof&lt;br /&gt;&lt;br /&gt;The instanceof operator compares an object to a specified type. You can use it to test if an object is an instance of a class, an instance of a subclass, or an instance of a class that implements a particular interface.&lt;br /&gt;&lt;br /&gt;The following program, InstanceofDemo, defines a parent class (named Parent), a simple interface (named MyInterface), and a child class (named Child) that inherits from the parent and implements the interface.&lt;br /&gt;&lt;br /&gt;   class InstanceofDemo {&lt;br /&gt;     public static void main(String[] args) {&lt;br /&gt;&lt;br /&gt;       Parent obj1 = new Parent();&lt;br /&gt;       Parent obj2 = new Child();&lt;br /&gt;&lt;br /&gt;       System.out.println('obj1 instanceof Parent: ' + (obj1 instanceof Parent));&lt;br /&gt;       System.out.println('obj1 instanceof Child: ' + (obj1 instanceof Child));&lt;br /&gt;       System.out.println('obj1 instanceof MyInterface: ' + (obj1 instanceof MyInterface));&lt;br /&gt;       System.out.println('obj2 instanceof Parent: ' + (obj2 instanceof Parent));&lt;br /&gt;       System.out.println('obj2 instanceof Child: ' + (obj2 instanceof Child));&lt;br /&gt;       System.out.println('obj2 instanceof MyInterface: ' + (obj2 instanceof MyInterface));&lt;br /&gt;&lt;pre&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Parent{}&lt;br /&gt;class Child extends Parent implements MyInterface{}&lt;br /&gt;interface MyInterface{}&lt;br /&gt;&lt;/pre&gt;  Output:   &lt;blockquote&gt;&lt;pre&gt;obj1 instanceof Parent: true&lt;br /&gt;obj1 instanceof Child: false&lt;br /&gt;obj1 instanceof MyInterface: false&lt;br /&gt;obj2 instanceof Parent: true&lt;br /&gt;obj2 instanceof Child: true&lt;br /&gt;obj2 instanceof MyInterface: true&lt;br /&gt;&lt;/pre&gt;&lt;/blockquote&gt;  When using the &lt;code&gt;instanceof&lt;/code&gt; operator, keep in mind that &lt;code&gt;null&lt;/code&gt; is not an instance of anything.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-2427852452996512800?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://java.sun.com/docs/books/tutorial/java/nutsandbolts/op2.html' title='Equality, Relational, and Conditional Operators (The Java™ Tutorials &gt; Learning the Java Language &gt; Language Basics)'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/2427852452996512800/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=2427852452996512800' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2427852452996512800'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2427852452996512800'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/03/equality-relational-and-conditional.html' title='Equality, Relational, and Conditional Operators (The Java™ Tutorials &gt; Learning the Java Language &gt; Language Basics)'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-7044177867447668055</id><published>2007-02-27T13:15:00.000+08:00</published><updated>2007-02-27T13:15:59.782+08:00</updated><title type='text'>g.georgovassilis - Using the GWTHandler</title><content type='html'>&lt;a href="http://g.georgovassilis.googlepages.com/usingthegwthandler"&gt;g.georgovassilis - Using the GWTHandler&lt;/a&gt;: "If you have used Spring before and are already using GWT for serious applications you might have considered using Spring controllers instead of GWT's RemoteServiceServlet. There are plenty good reasons for doing so actually."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-7044177867447668055?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://g.georgovassilis.googlepages.com/usingthegwthandler' title='g.georgovassilis - Using the GWTHandler'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/7044177867447668055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=7044177867447668055' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7044177867447668055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7044177867447668055'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2007/02/ggeorgovassilis-using-gwthandler.html' title='g.georgovassilis - Using the GWTHandler'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-2063471071834972706</id><published>2006-12-06T17:33:00.000+08:00</published><updated>2006-12-06T17:33:00.610+08:00</updated><title type='text'>AJAX Matters Blog » AJAX Tutorials</title><content type='html'>&lt;a href="http://www.ajaxmatters.com/blog/ajax-tutorials/"&gt;AJAX Matters Blog » AJAX Tutorials&lt;/a&gt;: "AJAX Tutorials&lt;br /&gt;&lt;br /&gt;A comprehensive list (over 130) of tutorials on AJAX, JavaScript and other web development topics.&lt;br /&gt;&lt;br /&gt;  1. Javascript Motion Tween&lt;br /&gt;     by Philippe Maegerman&lt;br /&gt;  2. 10 Realistic Steps to a Faster Web Site&lt;br /&gt;     by Alexander Kirk&lt;br /&gt;  3. 60 More AJAX Tutorials&lt;br /&gt;     by Max Kiesler&lt;br /&gt;  4. addEvent() considered harmful - an article from quirksmode.org&lt;br /&gt;  5. AJAX and scripting Web services with E4X, Part 1 - “Get an introduction to ECMAScript for XML (E4X), a simple extension to JavaScript that makes XML scripting very simple. In this paper, the authors demonstrate a Web programming model called Asynchronous JavaScript and XML (AJAX)…”&lt;br /&gt;  6. AJAX and scripting Web services with E4X, Part 2 - We have successfully used E4X to invoke Web services, and now we would like to provide Web services using E4X.&lt;br /&gt;  7. AJAX and Session Race Conditions&lt;br /&gt;     by Harry Fuecks&lt;br /&gt;  8. AJAX Design Patterns - “Is this tutorial any different from the others? Well yes and no, it is different in being a tutorial on how to design and build a complete site and not just some fancy little details like how to turn caching in AJAX off or how to create a fancy widget.”&lt;br /&gt;     by Christian Decker&lt;br /&gt;  9. AJAX FAQ for the Java Developer&lt;br /&gt;"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-2063471071834972706?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.ajaxmatters.com/blog/ajax-tutorials/' title='AJAX Matters Blog » AJAX Tutorials'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/2063471071834972706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=2063471071834972706' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2063471071834972706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2063471071834972706'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/12/ajax-matters-blog-ajax-tutorials.html' title='AJAX Matters Blog » AJAX Tutorials'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-9165427670673833775</id><published>2006-10-31T16:40:00.000+08:00</published><updated>2006-10-31T16:40:24.053+08:00</updated><title type='text'>Cheat Sheet Round-Up: Ajax, CSS, LaTeX, Ruby��� | Smashing Magazine | modern magazine for web-designers and developers</title><content type='html'>&lt;a href="http://www.smashingmagazine.com/cheat-sheets-static.html"&gt;�� Cheat Sheet Round-Up: Ajax, CSS, LaTeX, Ruby��� | Smashing Magazine | modern magazine for web-designers and developers&lt;/a&gt;: "Whether you���ve forgotten the name of a function or the property of a cascading style sheet - handy cheat sheets deliver the information you are looking for - immediately. Most cheat sheets are available as .pdf or .png-files, so you can print them and use them every day for whatever projects you���re currently working on. We present an extensive overview of useful cheat sheets we���ve found in the Web. Something is missing? Don���t hesistate to comment!"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-9165427670673833775?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.smashingmagazine.com/cheat-sheets-static.html' title='Cheat Sheet Round-Up: Ajax, CSS, LaTeX, Ruby��� | Smashing Magazine | modern magazine for web-designers and developers'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/9165427670673833775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=9165427670673833775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/9165427670673833775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/9165427670673833775'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/cheat-sheet-round-up-ajax-css-latex.html' title='Cheat Sheet Round-Up: Ajax, CSS, LaTeX, Ruby��� | Smashing Magazine | modern magazine for web-designers and developers'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-621719883409887748</id><published>2006-10-23T08:59:00.000+08:00</published><updated>2006-10-23T08:59:33.891+08:00</updated><title type='text'>How to Install Internet Explorer 7.0 Bypassing Genuine Windows Validation...</title><content type='html'>&lt;a href="http://fmshaon.blogspot.com/2006/10/how-to-install-internet-explorer-70.html"&gt;Shaon's Weblog: How to Install Internet Explorer 7.0 Bypassing Genuine Windows Validation...&lt;/a&gt;: "You must have Windows XP Service Pack-2 (SP2) in order to install Internet Explorer 7.0. But still you will face a problem while installing this new Internet Explorer if your copy of Windows XP is not a genuine (non-pirated) one, since IE 7.0 installation requires genuine windows validation!!! So what to do??? Don���t worry��� There are some tricky steps through which you can install IE 7.0 even in your pirated copy of windows XP bypassing the genuine windows validation. You just have to follow the following steps one by one:"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-621719883409887748?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://fmshaon.blogspot.com/2006/10/how-to-install-internet-explorer-70.html' title='How to Install Internet Explorer 7.0 Bypassing Genuine Windows Validation...'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/621719883409887748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=621719883409887748' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/621719883409887748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/621719883409887748'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/how-to-install-internet-explorer-70.html' title='How to Install Internet Explorer 7.0 Bypassing Genuine Windows Validation...'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-7513249462906263930</id><published>2006-10-21T14:23:00.000+08:00</published><updated>2006-10-21T14:23:05.029+08:00</updated><title type='text'>O'Reilly Network -- Open Tools for MySQL Administrators</title><content type='html'>&lt;a href="http://www.oreillynet.com/pub/a/mysql/2006/10/19/mysql-tools.html"&gt;O'Reilly Network -- Open Tools for MySQL Administrators&lt;/a&gt;: "MySQL provides some tools to monitor and troubleshoot a MySQL server, but they don't always suit a MySQL developer or administrator's common needs, or may not work in some scenarios, such as remote or over-the-web monitoring. Fortunately, the MySQL community has created a variety of free tools to fill the gaps. On the other hand, many of these are hard to find via web searches. In fact, web searches can be frustrating because they uncover abandoned or special-purpose, not ready-to-use projects. You could spend hours trying to find tools for monitoring and troubleshooting your MySQL servers. What's a tool-seeker to do?"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-7513249462906263930?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.oreillynet.com/pub/a/mysql/2006/10/19/mysql-tools.html' title='O&apos;Reilly Network -- Open Tools for MySQL Administrators'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/7513249462906263930/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=7513249462906263930' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7513249462906263930'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7513249462906263930'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/oreilly-network-open-tools-for-mysql.html' title='O&apos;Reilly Network -- Open Tools for MySQL Administrators'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-1394020032860087274</id><published>2006-10-18T08:44:00.000+08:00</published><updated>2006-10-19T14:36:44.891+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DB2'/><category scheme='http://www.blogger.com/atom/ns#' term='drupal'/><title type='text'>Drupal with IBM DB2 Express-C</title><content type='html'>&lt;a href="http://www-128.ibm.com/developerworks/ibm/library/i-osource9/index.html#listing18"&gt;Using open source software to design, develop, and deploy a collaborative Web site, Part 9: Understanding the database layer&lt;/a&gt;: "Drupal with IBM DB2 Express-C&lt;br /&gt;&lt;br /&gt;Enabling Drupal to use a database back end other than MySQL or PostgreSQL involves a moderate amount of work. There are two development tasks that must be completed before your database can be used by Drupal. The first task is to generate the initial database schema script. The following files are used to initialize MySQL and PostgreSQL databases, respectively:&lt;br /&gt;&lt;br /&gt; * database/database.4.1.mysql&lt;br /&gt; * database/database.pgsql"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-1394020032860087274?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/1394020032860087274/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=1394020032860087274' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1394020032860087274'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1394020032860087274'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/drupal-with-ibm-db2-express-c.html' title='Drupal with IBM DB2 Express-C'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-3553042571955461894</id><published>2006-10-17T10:42:00.000+08:00</published><updated>2006-10-17T10:42:51.219+08:00</updated><title type='text'>网民为什么不买你的帐</title><content type='html'>有的人也许会说，我的网站做大了，功能全了，用户就来了。我看，未必。其实，一个网站做起来，第一批用户的作用是至关重要的。如果告诉我第一批用户就是网 站宣传出来的，我肯定会只给打20分。你必须有一个非常有粘性的吸引网民能够来注册的特点。我们谈的是一个战役，战役开始攻占第一个山头是决定成败的，而 不是和我描述整个战役是否能够成功，那是纸上谈兵，诸葛亮都有过这个点上的投资错误，结果是斩了马谡。&lt;br /&gt;&lt;br /&gt;http://news.phoenixtv.com/phoenixtv/83929059737731072/20060927/895498.shtml&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-3553042571955461894?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://news.phoenixtv.com/phoenixtv/83929059737731072/20060927/895498.shtml' title='网民为什么不买你的帐'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/3553042571955461894/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=3553042571955461894' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3553042571955461894'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3553042571955461894'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/blog-post.html' title='网民为什么不买你的帐'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-3757178550905977402</id><published>2006-10-15T20:47:00.000+08:00</published><updated>2006-10-15T20:47:07.888+08:00</updated><title type='text'>Enterprise Web Applications. Presentation Layer. Evaluation Resu</title><content type='html'>&lt;a href="http://www.theserverside.com/discussions/thread.tss?thread_id=42640"&gt;Enterprise Web Applications. Presentation Layer. Evaluation Resu&lt;/a&gt;: "We specified the requirements for the Open Source Java Web frameworks used in presentation layer of Enterprise Web Applications:&lt;br /&gt;&lt;br /&gt;1. Performance.&lt;br /&gt;&lt;br /&gt;2. Modal dialogs.&lt;br /&gt;&lt;br /&gt;3. Partial page refresh.&lt;br /&gt;&lt;br /&gt;4. Component-based and event-driven.&lt;br /&gt;&lt;br /&gt;The philosophy should be: a Web application should behave like a desktop application, and it should be developed like a desktop application.&lt;br /&gt;&lt;br /&gt;Is it possible to satisfy all those requirements? How much will we have to pay for the convenience and flexibility - with performance loss (which translates into higher hardware cost)?"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-3757178550905977402?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.theserverside.com/discussions/thread.tss?thread_id=42640' title='Enterprise Web Applications. Presentation Layer. Evaluation Resu'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/3757178550905977402/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=3757178550905977402' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3757178550905977402'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3757178550905977402'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/enterprise-web-applications.html' title='Enterprise Web Applications. Presentation Layer. Evaluation Resu'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-6079945812074864881</id><published>2006-10-12T14:05:00.000+08:00</published><updated>2006-10-12T14:05:08.432+08:00</updated><title type='text'>ObjectLabKit 1.0.1: Date Calculators for Business and Finance</title><content type='html'>&lt;a href="http://www.theserverside.com/news/thread.tss?thread_id=42572"&gt;ObjectLabKit 1.0.1: Date Calculators for Business and Finance&lt;/a&gt;: "ObjectLab has announced the release of version 1.0.1 of ObjectLab Kit for Java 1.5, available for download via SourceForge or the Maven Central Repository.&lt;br /&gt;&lt;br /&gt;The Kit provides Date Calculators and comes in two versions: one based on pure JDK (1.5) and one based on the Joda-time library (1.3+, JDK 1.5). The library is live in a UK &amp; international Bank in the Credit Derivatives department.&lt;br /&gt;&lt;br /&gt;The DateCalculator implementation is intended for any business, while the other two interfaces are more specific to the financial industry. The most common function of a lot of banking or business applications is the handling of holidays and weekends; a set of standard rules are implemented to deal with days falling on a holiday. The library concentrates of the date manipulation and calculations.&lt;br /&gt;&lt;br /&gt;ObjectLab Kit provides the implementation of three interfaces:&lt;br /&gt;&lt;br /&gt;   * DateCalculator for all date calculation and handling of weekends or holidays&lt;br /&gt;   * PeriodCountCalculator for calculating differences between two dates in days, months or years according to some financial algorithms&lt;br /&gt;   * IMMDateCalculator to calculate the International Money Market dates&lt;br /&gt;&lt;br /&gt;ObjectLab has used and participated in several open source projects. ObjectLab is also sponsoring QALab, a tool that keeps track over time of the static analysis results from Fin"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-6079945812074864881?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.theserverside.com/news/thread.tss?thread_id=42572' title='ObjectLabKit 1.0.1: Date Calculators for Business and Finance'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/6079945812074864881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=6079945812074864881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6079945812074864881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6079945812074864881'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/objectlabkit-101-date-calculators-for.html' title='ObjectLabKit 1.0.1: Date Calculators for Business and Finance'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-4601170274394474893</id><published>2006-10-11T21:15:00.000+08:00</published><updated>2006-10-11T21:15:53.766+08:00</updated><title type='text'>Disable automatic install of IE 7</title><content type='html'>&lt;a href="http://www.intelliadmin.com/blog/2006/10/disable-automatic-install-of-ie-7.html"&gt;IntelliAdmin.com: Disable automatic install of IE 7&lt;/a&gt;: "Many administrators are going to be taken by surprise when they find out that IE 7 is going to be installed automatically via Windows Update.&lt;br /&gt;&lt;br /&gt;There are considerable changes that could cause many headaches. Most administrators would prefer to decide when IE 7 is deployed on their network.&lt;br /&gt;&lt;br /&gt;This is why microsoft has released the IE 7 blocking tool. It can be downloaded from here at Microsoft's website.&lt;br /&gt;&lt;br /&gt;Once you download and extract the package you will see that it is a command line tool. You simply call the script with the computer name and"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-4601170274394474893?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.intelliadmin.com/blog/2006/10/disable-automatic-install-of-ie-7.html' title='Disable automatic install of IE 7'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/4601170274394474893/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=4601170274394474893' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4601170274394474893'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4601170274394474893'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/disable-automatic-install-of-ie-7.html' title='Disable automatic install of IE 7'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-8651341206276191218</id><published>2006-10-09T18:07:00.000+08:00</published><updated>2006-10-09T18:07:13.867+08:00</updated><title type='text'>apache+Domino的整合</title><content type='html'>&lt;p&gt;先前已有透過 apache與 tomcat整合，達到透過 tomcat來存取 domino資料庫，現在透過 &lt;a href="http://www.google.com/"&gt;google&lt;/a&gt;大神找到另一方式來與 domino整合。&lt;/p&gt; &lt;p&gt;以下內容主要是參考此篇：&lt;a href="http://www.notestips.com/80256B3A007F2692/1/NAMO5RX3PX"&gt;Configuring Apache, PHP, MySQL and Domino for Windows 2000&lt;/a&gt;：&lt;/p&gt; &lt;p&gt;若是以Apache為主，要有一 Notes資料庫直接秀在瀏覽器上，便可以用 Proxy module來整合之。透過 mod_proxy.so便可以把 domino導向至 Apache的 port 80。&lt;/p&gt; &lt;p&gt;主要是修改 httpd.conf檔案，幫原本被註解掉的mod_proxy.so、mod_proxy_http.so以及mod_rewrite.so開啟，並增加&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;ReWriteEngineOn&lt;br /&gt;ReWriteRule ^(.*).nsf http://localhost:81$1.nsf$2&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;透過此方式，Domino即可透過Apache存取之。 &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-8651341206276191218?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://tech.dokein.net/index.php?cat=9&amp;paged=2' title='apache+Domino的整合'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/8651341206276191218/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=8651341206276191218' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8651341206276191218'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/8651341206276191218'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/apachedomino.html' title='apache+Domino的整合'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-3924294250379431487</id><published>2006-10-06T16:04:00.000+08:00</published><updated>2006-10-06T16:04:07.596+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Java Interview Questions</title><content type='html'>&lt;a href="http://java-j2ee-interview-questions.blogspot.com/"&gt;Java Interview Questions&lt;/a&gt;: "Java Interview Questions and Answers"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-3924294250379431487?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/3924294250379431487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=3924294250379431487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3924294250379431487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3924294250379431487'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/java-interview-questions.html' title='Java Interview Questions'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-956423784914157647</id><published>2006-10-06T16:02:00.000+08:00</published><updated>2006-10-06T16:02:55.093+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Mastering Enterprise JavaBeans 3.0</title><content type='html'>&lt;a href="http://www.theserverside.com/tt/books/wiley/masteringEJB3/index.tss"&gt;Mastering Enterprise JavaBeans 3.0&lt;/a&gt;: "Published in July 2006, the best selling book Mastering EJB is now in its fourth edition and has been updated for EJB 3.0. This edition features chapters on session beans and message-driven beans, EJB-Java EE integration and advanced persistence concepts. In-depth coverage of the Java Persistence API and using POJO entities with EJB is also included. By reading this book, you will acquire a deep understanding of EJB 3.0."&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-956423784914157647?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/956423784914157647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=956423784914157647' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/956423784914157647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/956423784914157647'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/mastering-enterprise-javabeans-30.html' title='Mastering Enterprise JavaBeans 3.0'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-1355882818031159632</id><published>2006-10-06T09:02:00.000+08:00</published><updated>2006-10-06T09:02:34.853+08:00</updated><title type='text'>20 FireFox Extensions That Every Web Designer Should Know About - CyberKnowledge Blog</title><content type='html'>&lt;a href="http://cyber-knowledge.net/blog/2006/10/05/20-firefox-extensions-that-every-web-designer-should-know-about/"&gt;20 FireFox Extensions That Every Web Designer Should Know About - CyberKnowledge Blog&lt;/a&gt;: "20 FireFox Extensions That Every Web Designer Should Know About"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-1355882818031159632?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://cyber-knowledge.net/blog/2006/10/05/20-firefox-extensions-that-every-web-designer-should-know-about/' title='20 FireFox Extensions That Every Web Designer Should Know About - CyberKnowledge Blog'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/1355882818031159632/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=1355882818031159632' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1355882818031159632'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/1355882818031159632'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/20-firefox-extensions-that-every-web.html' title='20 FireFox Extensions That Every Web Designer Should Know About - CyberKnowledge Blog'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-2202587925226590349</id><published>2006-10-05T22:04:00.000+08:00</published><updated>2006-10-05T22:04:08.379+08:00</updated><title type='text'>Firefox Extension Tutorial ��� Business Logs</title><content type='html'>&lt;a href="http://businesslogs.com/technology/firefox_extension_tutorial.php"&gt;Firefox Extension Tutorial ��� Business Logs&lt;/a&gt;: "For my final class at RIT I had to create a Firefox extension using XUL, CSS, and Javascript. Just to shake things up around here, I decided to post the tutorial about its development here instead of on a standalone website. I know that extension development may not be your cup of tea, but maybe you'll find some of it interesting. Here we go!"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-2202587925226590349?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://businesslogs.com/technology/firefox_extension_tutorial.php' title='Firefox Extension Tutorial ��� Business Logs'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/2202587925226590349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=2202587925226590349' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2202587925226590349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/2202587925226590349'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/firefox-extension-tutorial-business.html' title='Firefox Extension Tutorial ��� Business Logs'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-4893948230258541235</id><published>2006-10-05T21:38:00.000+08:00</published><updated>2006-10-05T21:38:35.693+08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>AsH: Top 126 Ajax Tutorials</title><content type='html'>&lt;a href="http://vyk1.spaces.live.com/Blog/cns%21EBE3A761F939F926%211051.entry"&gt;AsH: Top 126 Ajax Tutorials&lt;/a&gt;: "Top 126 Ajax Tutorials&lt;br /&gt;Getting Started&lt;br /&gt;&lt;br /&gt; 1. An Ajax Hello World project to Get You Going : First program at Mike On Code&lt;br /&gt; 2. Rasmus 30 second AJAX Tutorial : first program using Ajax at CoderLab&lt;br /&gt; 3. Instant Tutorial : Quick tutorial at AleemBawany&lt;br /&gt; 4. Ajax Toybox : Simple first programs including, Hello, World, Dynamic City, State Lookup, Ajax to Clean Your Clock, Ajax Calculator and an RSS News Ticker.&lt;br /&gt; 5. A simple Ajax example : a simple program demo for Ajax at MD Groves&lt;br /&gt; 6. Ajax Toolbox / XMLHttpRequest AjaxRequest Library Examples : Ajax examples including Error Handing, Time Out, Simultaneous Requests, Activity Monitoring, Form Submittal, Event Handlers, Queued Requests, Request Parameters&lt;br /&gt; 7. An Introduction to Ajax : introduction to Ajax at Prokata&lt;br /&gt; 8. Implementing simple Ajax interaction in your Web Application using XMLHttpRequest object : Intro + explanatory diagram at JavaReference&lt;br /&gt; 9. Nitty Gritty Ajax : Intro and Tutorial at WebMonkey"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-4893948230258541235?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/4893948230258541235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=4893948230258541235' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4893948230258541235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/4893948230258541235'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/ash-top-126-ajax-tutorials.html' title='AsH: Top 126 Ajax Tutorials'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-3530921200900245687</id><published>2006-10-05T21:34:00.000+08:00</published><updated>2006-10-05T21:34:39.160+08:00</updated><title type='text'>File Download Security</title><content type='html'>Want to prevent people from linking to your downloads?  This script will force a page to be loaded before the download starts.  HTML header statements are used to trigger the download of the file.  PHP is used to push the file to the browser.&lt;br /&gt;http://trailfire.com/bonlebon/marks/14947&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-3530921200900245687?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://trailfire.com/bonlebon/marks/14947' title='File Download Security'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/3530921200900245687/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=3530921200900245687' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3530921200900245687'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/3530921200900245687'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/file-download-security.html' title='File Download Security'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-7371642598943131876</id><published>2006-10-05T21:27:00.000+08:00</published><updated>2006-10-05T21:27:42.294+08:00</updated><title type='text'>How to create CSS overlapping tabs?</title><content type='html'>&lt;a href="http://www.osresources.com/6_1_en.html"&gt;OSResources - How to create CSS overlapping tabs?&lt;/a&gt;: "Sometimes simulating a real desktop interface for your web application can be a real challenge, especially when dealing with tabs. Side-to-side tabs are not easy to create in CSS, but overlapping tabs are even harder. I had to create overlapping CSS tabs for the Interaction Ajax chat application and I thought I would share this HOW-TO with you to save you hours :)"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-7371642598943131876?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.osresources.com/6_1_en.html' title='How to create CSS overlapping tabs?'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/7371642598943131876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=7371642598943131876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7371642598943131876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/7371642598943131876'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/10/how-to-create-css-overlapping-tabs.html' title='How to create CSS overlapping tabs?'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-5354653424034839475</id><published>2006-09-29T17:06:00.000+08:00</published><updated>2006-09-29T17:06:26.805+08:00</updated><title type='text'>Download details: Windows Server 2003 Resource Kit Tools</title><content type='html'>&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&amp;amp;displaylang=en"&gt;Download details: Windows Server 2003 Resource Kit Tools&lt;/a&gt;: "Overview&lt;br /&gt;The Microsoft�� Windows�� Server 2003 Resource Kit Tools are a set of tools to help administrators streamline management tasks such as troubleshooting operating system issues, managing Active Directory��, configuring networking and security features, and automating application deployment. "&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-5354653424034839475?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&amp;displaylang=en' title='Download details: Windows Server 2003 Resource Kit Tools'/><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/5354653424034839475/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=5354653424034839475' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5354653424034839475'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/5354653424034839475'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/download-details-windows-server-2003.html' title='Download details: Windows Server 2003 Resource Kit Tools'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-6338288220545672051</id><published>2006-09-29T14:40:00.000+08:00</published><updated>2006-09-29T14:42:03.710+08:00</updated><title type='text'>解析Html页面:HTML Parser的试用</title><content type='html'>最近在研究lucene的全文检索,在很多地方需要解析或者说分析Html内容或者Html页面,Lucene本身的演示程序中也提供了一个Html Parser,但是不是纯Java的解决方案.于是到处搜索,在网上找到了一个"HTMLParser".&lt;br /&gt;http://www.webjx.com/htmldata/2005-08-12/1123809282.html&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-6338288220545672051?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/6338288220545672051/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=6338288220545672051' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6338288220545672051'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/6338288220545672051'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/htmlhtml-parser.html' title='解析Html页面:HTML Parser的试用'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-115949482761462897</id><published>2006-09-29T09:53:00.000+08:00</published><updated>2006-09-29T09:53:47.623+08:00</updated><title type='text'>从HTML中攫取你所需的信息</title><content type='html'>&lt;a href="http://www-128.ibm.com/developerworks/cn/java/l-html-parser/"&gt;从HTML中攫取你所需的信息&lt;/a&gt;: "本文并非想通过分析HTML的语法然后从中解析出数据，这样做实现困难而且没有什么实际应用的意义，或者应该这样说：我们并不想自己去实现一个HTML语法的分析器。我们要做的仅仅是从HTML中提取我们所需的信息。不同于XML这种对格式要求非常严格的标志语言，HTML在推出时并没有对其格式进行严格的定义，比如HTML中标签并不一定要成对出现，但是又要求浏览器能尽量的正确显示其所要表达出来的内容。浏览器经过多年发展其适应能力越来越强，很多格式非常糟糕"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-115949482761462897?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/115949482761462897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=115949482761462897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115949482761462897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115949482761462897'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/html_28.html' title='从HTML中攫取你所需的信息'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-115949345219998557</id><published>2006-09-29T09:30:00.000+08:00</published><updated>2006-09-29T09:30:52.223+08:00</updated><title type='text'>扩展 HTMLParser 对自定义标签的处理能力</title><content type='html'>&lt;a href="http://www.crackj2ee.com/Article/ShowArticle.asp?ArticleID=495"&gt;扩展 HTMLParser 对自定义标签的处理能力&lt;/a&gt;: "本文阐述如何利用 HTMLParser 项目对 HTML 或者 WML 文档中出现的一些特殊的或者是自定义的标签进行处理。"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-115949345219998557?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/115949345219998557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=115949345219998557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115949345219998557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115949345219998557'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/htmlparser.html' title='扩展 HTMLParser 对自定义标签的处理能力'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-115928361458357830</id><published>2006-09-26T23:13:00.000+08:00</published><updated>2006-09-26T23:13:34.623+08:00</updated><title type='text'>JIRA - Bug tracking, issue tracking and project management software</title><content type='html'>&lt;a href="http://www.atlassian.com/software/jira/"&gt;JIRA - Bug tracking, issue tracking and project management software&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;这是一个项目管理的好产品，但是WEB方式总是不方便，可以考虑开发一个同样功能但基于C/S版的产品&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-115928361458357830?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/115928361458357830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=115928361458357830' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115928361458357830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115928361458357830'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/jira-bug-tracking-issue-tracking-and.html' title='JIRA - Bug tracking, issue tracking and project management software'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-115910904996144337</id><published>2006-09-24T22:44:00.000+08:00</published><updated>2006-09-24T22:44:09.963+08:00</updated><title type='text'>Getting Started with ModelMaker</title><content type='html'>&lt;a href="http://delphi.about.com/gi/dynamic/offsite.htm?zi=1/XJ&amp;sdn=delphi&amp;amp;zu=http%3A%2F%2Fcommunity.borland.com%2Farticle%2F0%2C1410%2C29006%2C00.html"&gt;About.com: http://community.borland.com/article/0,1410,29006,00.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-115910904996144337?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/115910904996144337/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=115910904996144337' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910904996144337'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910904996144337'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/getting-started-with-modelmaker.html' title='Getting Started with ModelMaker'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-115910895585445440</id><published>2006-09-24T22:42:00.000+08:00</published><updated>2006-09-24T22:42:35.863+08:00</updated><title type='text'>Resizing the drop-down list of a TCombobox</title><content type='html'>&lt;a href="http://delphi.about.com/gi/dynamic/offsite.htm?zi=1/XJ&amp;sdn=delphi&amp;amp;zu=http%3A%2F%2Fwww.delphicorner.f9.co.uk%2Farticles%2Fcomps11.htm"&gt;About.com: http://www.delphicorner.f9.co.uk/articles/comps11.htm&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-115910895585445440?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/115910895585445440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=115910895585445440' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910895585445440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910895585445440'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/resizing-drop-down-list-of-tcombobox.html' title='Resizing the drop-down list of a TCombobox'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-115910831502977198</id><published>2006-09-24T22:31:00.000+08:00</published><updated>2006-09-24T22:31:55.040+08:00</updated><title type='text'>ListBox to the Max</title><content type='html'>&lt;a href="http://delphi.about.com/b/a/035407.htm"&gt;ListBox to the Max&lt;/a&gt;: "ListBox to the Max&lt;br /&gt;TIPS :: The main purpose of a TListBox component is displaying a collection of items in a scrollable list. Here are some list box tips to make a ListBox component more powefull:&lt;br /&gt;&lt;br /&gt;# How to Draw a Radio Button for a TListBox Item in Delphi&lt;br /&gt;# How to Jump to the Last Item in the TListBox Delphi component&lt;br /&gt;# Place a TEdit inside a TListBox to enable inplace editing of ListBox items&lt;br /&gt;# ListBox with a horizontal scroll bar&lt;br /&gt;# Add columns to a ListBox&lt;br /&gt;# Drag from ListBox to Edit&lt;br /&gt;# Long ListBox entries as Hints&lt;br /&gt;# How to change the background color on different lines of text in a TListBox&lt;br /&gt;Thursday October 16, 2003"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-115910831502977198?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/115910831502977198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=115910831502977198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910831502977198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910831502977198'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/listbox-to-max.html' title='ListBox to the Max'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-115910652755962121</id><published>2006-09-24T22:02:00.000+08:00</published><updated>2006-09-24T22:03:32.303+08:00</updated><title type='text'>An introduction to hook procedures</title><content type='html'>&lt;a href="http://delphi.about.com/library/bluc/text/uc063001a.htm"&gt;An introduction to hook procedures&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:verdana, geneva, helvetica;font-size:85%;"&gt;   Article submitted by: &lt;a href="mailto:wibble82@hotmail.com"&gt;Chris Cummings&lt;/a&gt;, &lt;a href="http://delphi.about.com/gi/dynamic/offsite.htm?site=http://wibblovia.topcities.com"&gt;http://wibblovia.topcities.com&lt;/a&gt;   &lt;/span&gt;&lt;p&gt;&lt;span style="font-family:verdana, geneva, helvetica;font-size:85%;"&gt;This document describes what windows hooks are and how to use them. In order to use hooks properly you will need a copy of the windows SDK, that can be downloaded from the Microsoft web site. The project hooks.dpr contains all the code for the program used in this document and hookdll.dpr contains the DLL required. The actual code itself is shown and explained more thoroughly as remarks within the projects. &lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-115910652755962121?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/115910652755962121/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=115910652755962121' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910652755962121'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910652755962121'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/introduction-to-hook-procedures.html' title='An introduction to hook procedures'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-34947833.post-115910627025111756</id><published>2006-09-24T21:57:00.000+08:00</published><updated>2006-09-24T22:05:08.243+08:00</updated><title type='text'>Pear to Pear delphi program</title><content type='html'>&lt;a href="http://delphi.about.com/gi/dynamic/offsite.htm?zi=1/XJ&amp;sdn=delphi&amp;amp;zu=http%3A%2F%2Fbdn1.borland.com%2Farticle%2Fborcon%2F0%2C1919%2C31718%2C00.html"&gt;About.com: http://bdn1.borland.com/article/borcon/0,1919,31718,00.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;关于P2P WEB编程&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34947833-115910627025111756?l=meixuesong.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://meixuesong.blogspot.com/feeds/115910627025111756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=34947833&amp;postID=115910627025111756' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910627025111756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/34947833/posts/default/115910627025111756'/><link rel='alternate' type='text/html' href='http://meixuesong.blogspot.com/2006/09/pear-to-pear-delphi-program.html' title='Pear to Pear delphi program'/><author><name>Jason</name><uri>http://www.blogger.com/profile/04535109348082168360</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='24' height='32' src='http://3.bp.blogspot.com/_Ed2oWHNGofs/SOC8R-YNtpI/AAAAAAAAAW0/5Khzxm81pmY/S220/n513895389_164.jpg'/></author><thr:total>0</thr:total></entry></feed>
