<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="text">博客园_卢春城专栏</title><subtitle type="text">.NET &amp; WIN32 API</subtitle><id>http://feed.cnblogs.com/blog/u/31990/rss</id><updated>2012-05-24T07:14:46Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><generator>feed.cnblogs.com</generator><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/"/><link rel="self" type="application/atom+xml" href="http://feed.cnblogs.com/blog/u/31990/rss"/><entry><id>http://www.cnblogs.com/lucc/archive/2011/04/14/2016532.html</id><title type="text">Lesktop开源WebIM 2.2.0.11——增加在线客服功能</title><summary type="text">距离上次在博客园发布Lesktop2.0.2.7已经有几个月了，在这段时间里，又增加了几个小功能，这次的修改主要有：1、支持MSSQL数据库；2、显示在线/离线；3、增加在线客服功能，可将在线客服嵌入到任何网页中。</summary><published>2011-04-14T14:59:00Z</published><updated>2011-04-14T14:59:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2011/04/14/2016532.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2011/04/14/2016532.html"/><content type="html">&lt;p&gt;距离上次在博客园发布Lesktop2.0.2.7已经有几个月了，在这段时间里，又增加了几个小功能，这次的修改主要有：&lt;/p&gt;  &lt;p&gt;1、支持MSSQL数据库；&lt;/p&gt;  &lt;p&gt;2、显示在线/离线；&lt;/p&gt;  &lt;p&gt;3、增加在线客服功能，可将在线客服嵌入到任何网页中。&lt;/p&gt;  &lt;p&gt;下面主要介绍在线客服功能：&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;你可以在任何网站中嵌入在线客服，具体方法如下：&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1、注册客服人员；&lt;/p&gt;  &lt;p&gt;2、使用客服人员的登陆名，生成嵌入代码，并将代码嵌入插入到要嵌入客服的网页中。嵌入代码格式如下：&lt;/p&gt;  &lt;span class="rem"&gt;&amp;lt;!--&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;嵌入客服系统，系统将在此处生成客服人员的HTML代码&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;CSR: {客服人员登录名}&lt;/span&gt;&lt;br/&gt;&lt;span class="rem"&gt;--&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;src&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;&lt;span class="rem"&gt;{您的主机}&lt;/span&gt;/Lesktop/EmbedCS.ashx?CSR=&lt;span class="rem"&gt;{客服人员登录名}&lt;/span&gt; &amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;language&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;javascript&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;3、系统将在您插入嵌入代码的位置，生成与客服人员相关（显示昵称和在线状态）的链接的HTML代码。&lt;/p&gt;&lt;p&gt;例如，以下嵌入代码：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201104/201104142300553500.png" width="534" height="257" /&gt;&lt;/p&gt;&lt;p&gt;最终生成的效果如下：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201104/201104142300557437.png" width="374" height="201" /&gt;&lt;/p&gt;&lt;p&gt;点击生成的链接，将弹出客服系统对话框：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201104/201104142307145679.png" width="566" height="463" /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;生成自定义的客服HTML代码&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;嵌入客服代码后，客服系统默认将生成一个A链接（ &lt;font color="#ff0000"&gt;&amp;lt;a …&amp;gt;昵称（状态）&amp;lt;/a&amp;gt;&lt;/font&gt; ），您可以修改&lt;font color="#ff0000"&gt;Lesktop/Core/Embed.js&lt;/font&gt;来生成自定义的HTML代码：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201104/201104142355535907.png" width="686" height="187" /&gt;&lt;/p&gt;&lt;div class="link"&gt;&lt;a href="http://luchuncheng.com/blog/article.aspx?ID=12" target="_blank"&gt;Lesktop演示和下载&lt;/a&gt; [&lt;a href="javascript:StartChat('lucc')"&gt;在线咨询&lt;/a&gt;] &lt;/div&gt;&lt;img src="http://www.cnblogs.com/lucc/aggbug/2016532.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lucc/archive/2011/04/14/2016532.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2011/03/20/1989218.html</id><title type="text">在SQL Server中对视图进行增删改</title><summary type="text">本文将介绍在SQL Server中，如何对视图进行增删改。</summary><published>2011-03-19T17:54:00Z</published><updated>2011-03-19T17:54:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2011/03/20/1989218.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2011/03/20/1989218.html"/><content type="html">&lt;p&gt;&lt;a href="http://luchuncheng.com" target="_blank"&gt;Lesktop开源IM&lt;/a&gt;发布以后，有一些网友问及如何在嵌入IM后与自己网站的用户系统整合(&lt;font color="#ff0000"&gt;即如何让嵌入的IM直接使用网站原有的用户数据库，而不需要将已有的用户数据导入到IM的数据库中&lt;/font&gt;)。Lesktop对Users表（存储用户登录名，昵称，密码等信息的表）都是在存储过程中进行增删改的，显然，如果直接去改Users表相关的存储过程是比较麻烦的，&lt;font color="#ff0000"&gt;本文将介绍一种较为简单的方法，在不需要修改存储过程和源代码的情况下整合用户系统&lt;/font&gt;。&lt;/p&gt;  &lt;p&gt;为实现这个目的，&lt;font color="#ff0000"&gt;先介绍一下在SQL SERVER中，如何对视图进行增删改&lt;/font&gt;。假使用户有Name,Remark两项信息，但是没有存放在同一张表中，而是分开存储在两个表UserBase(ID, Name)，UserExtent(ID, Remark)中。&lt;/p&gt;  &lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201103/201103200154436254.png" width="520" height="121" /&gt;&lt;/p&gt;  &lt;p&gt;为使用方便，建立一个视图Users，用于表示用户的完整信息，其定义如下：&lt;/p&gt;  &lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;VIEW&lt;/span&gt; [dbo].[Users]&lt;br/&gt;&lt;span class="kwrd"&gt;as&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;SELECT&lt;/span&gt; b.ID &lt;span class="kwrd"&gt;as&lt;/span&gt; ID, b.Name &lt;span class="kwrd"&gt;as&lt;/span&gt; Name, e.Remark &lt;span class="kwrd"&gt;as&lt;/span&gt; Remark &lt;br/&gt;&lt;span class="kwrd"&gt;FROM&lt;/span&gt; UserBase b, UserExtent e &lt;br/&gt;&lt;span class="kwrd"&gt;WHERE&lt;/span&gt; b.ID = e.ID;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;现在，我们希望通过Users视图进行增删改实现对UserBase，UserExtent表进行修改。显然，如果对Users直接执行insert，update，delete是不可能的，执行时会发生以下错误：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201103/201103200154432109.png" width="415" height="79" /&gt;&lt;/p&gt;&lt;p&gt;在SQL Server中，对视图增删改可以通过触发器来实现，例如我们可以创建一个INSERT触发器，当在视图Users上执行INSERT时，在触发器中实现对UserBase，UserExtent的INSERT操作。在触发器中，&lt;font color="#ff0000"&gt;可以通过名称为inserted的表，获取到新插入的行&lt;/font&gt;，具体代码如下：&lt;/p&gt;&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;TRIGGER&lt;/span&gt; [dbo].[Users_Insert] &lt;span class="kwrd"&gt;ON&lt;/span&gt; [dbo].[Users] INSTEAD &lt;span class="kwrd"&gt;OF&lt;/span&gt; INSERT&lt;br/&gt;&lt;span class="kwrd"&gt;as&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;declare&lt;/span&gt; @name nvarchar(32), @remark nvarchar(32)&lt;br/&gt;&lt;span class="kwrd"&gt;declare&lt;/span&gt; ins_cursor &lt;span class="kwrd"&gt;cursor&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;for&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; Name, Remark &lt;span class="kwrd"&gt;from&lt;/span&gt; inserted&lt;br/&gt;&lt;span class="kwrd"&gt;open&lt;/span&gt; ins_cursor&lt;br/&gt;&lt;span class="kwrd"&gt;fetch&lt;/span&gt; &lt;span class="kwrd"&gt;next&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; ins_cursor &lt;span class="kwrd"&gt;into&lt;/span&gt; @name, @remark;&lt;br/&gt;&lt;span class="kwrd"&gt;while&lt;/span&gt;(@@fetch_status = 0)&lt;br/&gt;&lt;span class="kwrd"&gt;begin&lt;/span&gt;&lt;br/&gt;    &lt;font color="#008000"&gt;--读取所有行，并插入&lt;br/&gt;&lt;/font&gt;    insert &lt;span class="kwrd"&gt;into&lt;/span&gt; UserBase (Name) &lt;span class="kwrd"&gt;values&lt;/span&gt; (@name);&lt;br/&gt;    insert &lt;span class="kwrd"&gt;into&lt;/span&gt; UserExtent(ID, Remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (@@&lt;span class="kwrd"&gt;identity&lt;/span&gt;, @remark);&lt;br/&gt;    &lt;span class="kwrd"&gt;fetch&lt;/span&gt; &lt;span class="kwrd"&gt;next&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; ins_cursor &lt;span class="kwrd"&gt;into&lt;/span&gt; @name, @remark;&lt;br/&gt;&lt;span class="kwrd"&gt;end&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;close&lt;/span&gt; ins_cursor&lt;p&gt;下面我们通过插入两行数据测试触发器：&lt;/p&gt;&lt;font color="#008000"&gt;--清空所有数据&lt;/font&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; UserExtent;&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; UserBase;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;create&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; #temp(&lt;br/&gt;    name nvarchar(32),&lt;br/&gt;    remark nvarchar(32)&lt;br/&gt;)&lt;br/&gt;insert #temp (name,remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (N&lt;span class="str"&gt;'user1'&lt;/span&gt;, N&lt;span class="str"&gt;'1'&lt;/span&gt;);&lt;br/&gt;insert #temp (name,remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (N&lt;span class="str"&gt;'user2'&lt;/span&gt;, N&lt;span class="str"&gt;'2'&lt;/span&gt;);&lt;br/&gt;&lt;br/&gt;&lt;font color="#008000"&gt;--插入两行数据&lt;/font&gt;&lt;br/&gt;insert Users(name, remark)&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; name,remark &lt;span class="kwrd"&gt;from&lt;/span&gt; #temp&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;drop&lt;/span&gt; &lt;span class="kwrd"&gt;table&lt;/span&gt; #temp&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Users;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; UserBase;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; UserExtent;&lt;p&gt;执行结果如下：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201103/201103200154433189.png" width="262" height="252" /&gt;&lt;/p&gt;&lt;p&gt;创建更新触发器，与INSERT触发器类似，受影响的行会保存在inserted中，&lt;font color="#ff0000"&gt;可以从inserted表中获取受影响的行&lt;/font&gt;，并更新UserBase，UserExtent，具体代码如下：&lt;/p&gt;&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;TRIGGER&lt;/span&gt; [dbo].[Users_Update] &lt;span class="kwrd"&gt;ON&lt;/span&gt; [dbo].[Users] INSTEAD &lt;span class="kwrd"&gt;OF&lt;/span&gt; &lt;span class="kwrd"&gt;UPDATE&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;as&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;update&lt;/span&gt; UserExtent&lt;br/&gt;&lt;span class="kwrd"&gt;set&lt;/span&gt; UserExtent.Remark=ins.Remark&lt;br/&gt;&lt;span class="kwrd"&gt;from&lt;/span&gt; inserted ins&lt;br/&gt;&lt;span class="kwrd"&gt;where&lt;/span&gt; UserExtent.ID = ins.ID;&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;update&lt;/span&gt; UserBase&lt;br/&gt;&lt;span class="kwrd"&gt;set&lt;/span&gt; UserBase.Name=ins.Name&lt;br/&gt;&lt;span class="kwrd"&gt;from&lt;/span&gt; inserted ins&lt;br/&gt;&lt;span class="kwrd"&gt;where&lt;/span&gt; UserBase.ID = ins.ID;&lt;p&gt;测试代码：&lt;/p&gt;&lt;font color="#008000"&gt;--清空所有数据&lt;/font&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; UserExtent;&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; UserBase;&lt;br/&gt;&lt;font color="#008000"&gt;--插入两行数据&lt;/font&gt;&lt;br/&gt;insert Users (name,remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (N&lt;span class="str"&gt;'user1'&lt;/span&gt;, N&lt;span class="str"&gt;'1'&lt;/span&gt;);&lt;br/&gt;insert Users (name,remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (N&lt;span class="str"&gt;'user2'&lt;/span&gt;, N&lt;span class="str"&gt;'2'&lt;/span&gt;);&lt;br/&gt;insert Users (name,remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (N&lt;span class="str"&gt;'user3'&lt;/span&gt;, N&lt;span class="str"&gt;'2'&lt;/span&gt;);&lt;br/&gt;&lt;font color="#008000"&gt;--修改后两行数据&lt;/font&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;UPDATE&lt;/span&gt; Users &lt;span class="kwrd"&gt;set&lt;/span&gt; Remark = N&lt;span class="str"&gt;'3'&lt;/span&gt; &lt;span class="kwrd"&gt;where&lt;/span&gt; Remark = N&lt;span class="str"&gt;'2'&lt;/span&gt;&lt;br/&gt;&lt;font color="#008000"&gt;--输出数据&lt;/font&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Users;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; UserBase;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; UserExtent;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;测试结果：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201103/201103200154432633.png" width="218" height="300" /&gt;&lt;/p&gt;&lt;p&gt;创建删除触发器，在删除的触发器中，&lt;font color="#ff0000"&gt;可以通过deleted表，获取被删除的行&lt;/font&gt;，具体代码如下：&lt;/p&gt;&lt;span class="kwrd"&gt;CREATE&lt;/span&gt; &lt;span class="kwrd"&gt;TRIGGER&lt;/span&gt; [dbo].[Users_Delete] &lt;span class="kwrd"&gt;ON&lt;/span&gt; [dbo].[Users] INSTEAD &lt;span class="kwrd"&gt;OF&lt;/span&gt; &lt;span class="kwrd"&gt;DELETE&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;as&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; UserExtent &lt;span class="kwrd"&gt;where&lt;/span&gt; ID &lt;span class="kwrd"&gt;in&lt;/span&gt; (&lt;span class="kwrd"&gt;select&lt;/span&gt; ID &lt;span class="kwrd"&gt;from&lt;/span&gt; deleted)&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; UserBase &lt;span class="kwrd"&gt;where&lt;/span&gt; ID &lt;span class="kwrd"&gt;in&lt;/span&gt; (&lt;span class="kwrd"&gt;select&lt;/span&gt; ID &lt;span class="kwrd"&gt;from&lt;/span&gt; deleted)&lt;p&gt;测试代码：&lt;/p&gt;&lt;font color="#008000"&gt;--清空所有数据&lt;/font&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; UserExtent;&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; UserBase;&lt;br/&gt;&lt;font color="#008000"&gt;--插入两行数据&lt;/font&gt;&lt;br/&gt;insert Users (name,remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (N&lt;span class="str"&gt;'user1'&lt;/span&gt;, N&lt;span class="str"&gt;'1'&lt;/span&gt;);&lt;br/&gt;insert Users (name,remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (N&lt;span class="str"&gt;'user2'&lt;/span&gt;, N&lt;span class="str"&gt;'2'&lt;/span&gt;);&lt;br/&gt;insert Users (name,remark) &lt;span class="kwrd"&gt;values&lt;/span&gt; (N&lt;span class="str"&gt;'user3'&lt;/span&gt;, N&lt;span class="str"&gt;'2'&lt;/span&gt;);&lt;br/&gt;&lt;font color="#008000"&gt;--删除后两行数据&lt;/font&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;delete&lt;/span&gt; &lt;span class="kwrd"&gt;from&lt;/span&gt; Users &lt;span class="kwrd"&gt;where&lt;/span&gt; Remark = N&lt;span class="str"&gt;'2'&lt;/span&gt;&lt;br/&gt;&lt;font color="#008000"&gt;--输出数据&lt;/font&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; Users;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; UserBase;&lt;br/&gt;&lt;span class="kwrd"&gt;select&lt;/span&gt; * &lt;span class="kwrd"&gt;from&lt;/span&gt; UserExtent;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;background-color: #ffffff;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;运行结果：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201103/20110320015444125.png" width="226" height="195" /&gt;&lt;/p&gt;&lt;p&gt;上文已介绍了如何对视图进行增删改，接下来将介绍如何通过建立视图并添加增删改触发器实现Lesktop开源IM用户系统的整合。首先介绍一下Lesktop开源IM数据库中&lt;font color="#ff0000"&gt;Users&lt;/font&gt;表的结构：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201103/201103200154446744.png" width="335" height="379" /&gt;&lt;/p&gt;&lt;p&gt;假使您的网站的用户表(假使名称为&lt;font color="#ff0000"&gt;MyUserTable&lt;/font&gt;)只有Name,Nickname：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201103/201103200154444236.png" width="337" height="78" /&gt;&lt;/p&gt;&lt;p&gt;那么，您可以建立一张扩展表(假使名称为&lt;font color="#ff0000"&gt;UserExtentIM&lt;/font&gt;)，用于存储其他信息：&lt;/p&gt;&lt;p&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201103/201103200154443680.png" width="415" height="360" /&gt;&lt;/p&gt;&lt;p&gt;接下来，您只需要&lt;font color="#ff0000"&gt;把Users表删掉，重新建立一个名称为Users的视图，然后用上文处理Users, UserBase, UserExtent的方法，在Users视图上建好触发器，在触发器中对MyUserTable，UserExtentIM表进行增删改即可&lt;/font&gt;，Lesktop的存储过程对User进行读取和增删改时，将通过触发器自动转换成对MyUserTable，UserExtentIM的操作，因此不需要修改任何存储过程和源代码，当然也不会对你原有的数据库造成影响。&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lucc/aggbug/1989218.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lucc/archive/2011/03/20/1989218.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2010/11/24/1886087.html</id><title type="text">WebBrowser介绍——Javascript与C++互操作</title><summary type="text">WebBrowser控件是Microsoft提供的一个用于网页浏览的客户端控件，WebBrowser控件的使用相当广泛，例如很多邮件客户端都是使用可编辑的WebBrowser控件作为写邮件的工具，也有很多软件用WebBrowser控件弹出网页，如qq的个性首页。本文主要探讨在使用WebBrowser时如何实现Javascript与C++的互操作。</summary><published>2010-11-23T16:25:00Z</published><updated>2010-11-23T16:25:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2010/11/24/1886087.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2010/11/24/1886087.html"/><content type="html">&lt;p&gt;WebBrowser控件是Microsoft提供的一个用于网页浏览的客户端控件，WebBrowser控件的使用相当广泛，例如很多邮件客户端都是使用可编辑的WebBrowser控件作为写邮件的工具，也有很多软件用WebBrowser控件弹出网页，如qq的个性首页。关于WebBrowser的应用，也可以参考笔者开发的&lt;a href="http://www.luchuncheng.com" target="_blank"&gt;开源WebIM&lt;/a&gt;，Lesktop开源WebIM提供的IM客户端就是使用WebBrowser实现的：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.luchuncheng.com" target="_blank"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/Windows-Live-Writer/WebBrowser_13676/image_3.png" width="578" height="456" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;微软的MFC和.NET都有WebBrowser控件，这两个控件虽然容易上手，不过由于包装的太好，所以很难深入。因此&lt;font color="#ff0000"&gt;本文介绍的WebBrowser将不使用MFC和.NET，而是使用C++实现SDK的&lt;/font&gt;&lt;font color="#ff0000"&gt;WebBrowser&lt;/font&gt;。&lt;/p&gt;  &lt;p&gt;由于&lt;font color="#ff0000"&gt;本文主要探讨如何实现Javascript与C++的互操作&lt;/font&gt;，对于如何使用SDK实现WebBrowser，本文不做详细介绍，读者可以参考以下这篇文章：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.csdn.net/norsd/archive/2008/09/13/2921389.aspx" target="_blank"&gt;http://blog.csdn.net/norsd/archive/2008/09/13/2921389.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;不过尽管文章中介绍了SDK实现WebBrowser的要点，却没有提供一个可以运行的示例，如果要看到实际的运行效果，可以下载以下这份源代码，源代码中也包括了互操作的演示：&lt;/p&gt;  &lt;div class="link"&gt;&lt;a href="http://files.cnblogs.com/lucc/webbrowser.zip"&gt;SDK实现WebBrowser及演示代码&lt;/a&gt;[&lt;a href="javascript:_PostComment(null, true)"&gt;好文，推荐一下&lt;/a&gt;&lt;a href="javascript:_PostComment('看不懂', false)"&gt;看不懂&lt;/a&gt;]&lt;/div&gt;&lt;p&gt;&lt;strong&gt;1、C++调用WebBrowser中的全局函数，变量等&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;&lt;strong&gt;(1) 从C++的角度看WebBrowser中的对象&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;WebBrowser中的对象大致可以分成两类：DOM对象和使用Javascript创建的对象。但是无论是那种对象，从C++的角度来看，都是一些实现了&lt;a href="http://msdn.microsoft.com/en-us/library/ms221608.aspx" target="_blank"&gt;IDispatch&lt;/a&gt;接口的对象，因此，如果用C++操作WebBrowser中的对象（全局函数，变量，DOM）等，只需要通过IDispatch即可。&lt;/p&gt;  &lt;p&gt;&lt;font color="#000000"&gt;&lt;strong&gt;(2) 3个常用的函数&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;当&lt;font color="#ff0000"&gt;获取了WebBrowser的对象的IDispatch接口后，就可以调用IDispatch的Invoke方法来调用对象的方法，获取对象的属性和设置对象的属性&lt;/font&gt;。但是Invoke是通过ID判断要调用指定对象的哪一个方法（或属性），因此在通过方法（或属性）名称调用对象的方法是，必须&lt;font color="#ff0000"&gt;先调用IDispatch的GetIDsOfNames方法，将方法（或属性）名转换成ID&lt;/font&gt;，然后才能通过IDispatch的Invoke方法调用对象的方法。为了方便操作，封装了&lt;font color="#ff0000"&gt;三个函数，分别用于调用WebBrowser的对象的方法，读取对象的属性，设置对象的属性。&lt;/font&gt;&lt;/p&gt;  &lt;div class="code"&gt;   DISPID CWebBrowserBase::FindId(IDispatch *pObj, LPOLESTR pName)&lt;br/&gt;{&lt;br/&gt;    DISPID id = 0;&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(FAILED(pObj-&amp;gt;GetIDsOfNames(IID_NULL,&amp;amp;pName,1,LOCALE_SYSTEM_DEFAULT,&amp;amp;id))) id = -1;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; id;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;HRESULT CWebBrowserBase::InvokeMethod(IDispatch *pObj, LPOLESTR pName, VARIANT *pVarResult, VARIANT *p, &lt;span class="kwrd"&gt;int&lt;/span&gt; cArgs)&lt;br/&gt;{&lt;br/&gt;    DISPID dispid = FindId(pObj, pName);&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(dispid == -1) &lt;span class="kwrd"&gt;return&lt;/span&gt; E_FAIL;&lt;br/&gt;&lt;br/&gt;    DISPPARAMS ps;&lt;br/&gt;    ps.cArgs = cArgs;&lt;br/&gt;    ps.rgvarg = p;&lt;br/&gt;    ps.cNamedArgs = 0;&lt;br/&gt;    ps.rgdispidNamedArgs = NULL;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; pObj-&amp;gt;Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &amp;amp;ps, pVarResult, NULL, NULL);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;HRESULT CWebBrowserBase::GetProperty(IDispatch *pObj, LPOLESTR pName, VARIANT *pValue)&lt;br/&gt;{&lt;br/&gt;    DISPID dispid = FindId(pObj, pName);&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(dispid == -1) &lt;span class="kwrd"&gt;return&lt;/span&gt; E_FAIL;&lt;br/&gt;&lt;br/&gt;    DISPPARAMS ps;&lt;br/&gt;    ps.cArgs = 0;&lt;br/&gt;    ps.rgvarg = NULL;&lt;br/&gt;    ps.cNamedArgs = 0;&lt;br/&gt;    ps.rgdispidNamedArgs = NULL;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; pObj-&amp;gt;Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &amp;amp;ps, pValue, NULL, NULL);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;HRESULT CWebBrowserBase::SetProperty(IDispatch *pObj, LPOLESTR pName, VARIANT *pValue)&lt;br/&gt;{&lt;br/&gt;    DISPID dispid = FindId(pObj, pName);&lt;br/&gt;    &lt;span class="kwrd"&gt;if&lt;/span&gt;(dispid == -1) &lt;span class="kwrd"&gt;return&lt;/span&gt; E_FAIL;&lt;br/&gt;&lt;br/&gt;    DISPPARAMS ps;&lt;br/&gt;    ps.cArgs = 1;&lt;br/&gt;    ps.rgvarg = pValue;&lt;br/&gt;    ps.cNamedArgs = 0;&lt;br/&gt;    ps.rgdispidNamedArgs = NULL;&lt;br/&gt;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; pObj-&amp;gt;Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &amp;amp;ps, NULL, NULL, NULL);&lt;br/&gt;}&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&lt;font color="#000000"&gt;&lt;strong&gt;(3)调用页面的全局函数&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;&lt;p&gt;在网页中，&lt;font color="#ff0000"&gt;所有的全局函数均是window的一个方法&lt;/font&gt;，因此，如果要调用全局函数，首先要获取到页面的window对象，然后用InvokeMethod调用全局函数，例如，假设页面中有一个Test全局函数：&lt;/p&gt;&lt;div class="code"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;language&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;javascript&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; Test()&lt;br/&gt;{&lt;br/&gt;    alert(&lt;span class="str"&gt;&amp;quot;你调用了Test&amp;quot;&lt;/span&gt;);&lt;br/&gt;}&lt;br/&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;那么，您可以在C++中用以下代码调用Test函数：&lt;/p&gt;&lt;div class="code"&gt;  VARIANT &lt;span class="kwrd"&gt;params&lt;/span&gt;[10];&lt;br/&gt;VARIANT ret;&lt;br/&gt;&lt;span class="rem"&gt;//获取页面window&lt;/span&gt;&lt;br/&gt;IDispatch *pHtmlWindow = pBrowser-&amp;gt;GetHtmlWindow();&lt;br/&gt;&lt;span class="rem"&gt;//页面全局函数Test实际上是window的Test方法，&lt;/span&gt;&lt;br/&gt;CWebBrowserBase::InvokeMethod(pHtmlWindow, L&lt;span class="str"&gt;&amp;quot;Test&amp;quot;&lt;/span&gt;, &amp;amp;ret, &lt;span class="kwrd"&gt;params&lt;/span&gt;, 0);&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&lt;strong&gt;(4)调用全局对象的方法&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;在网页中，&lt;font color="#ff0000"&gt;所有的全局变量均是window的一个属性&lt;/font&gt;，因此，如果要调用变量的方法（或属性），首先要获取到页面的window对象，然后用GetProperty获取到全局变量，然后就可以调用这个对象的方法，或读写其属性。例如，假设页面中有一个globalObject全局变量：&lt;/p&gt;&lt;div class="code"&gt;  &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt; &lt;span class="attr"&gt;language&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;javascript&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;type&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;function&lt;/span&gt; GlobalObject()&lt;br/&gt;{&lt;br/&gt;    &lt;span class="kwrd"&gt;this&lt;/span&gt;.Test=&lt;span class="kwrd"&gt;function&lt;/span&gt;()&lt;br/&gt;    {&lt;br/&gt;        alert(&lt;span class="str"&gt;&amp;quot;你调用了GlobalObject.Test&amp;quot;&lt;/span&gt;);&lt;br/&gt;    }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;var&lt;/span&gt; globalObject = &lt;span class="kwrd"&gt;new&lt;/span&gt; GlobalObject();&lt;br/&gt;&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;script&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;那么，您可以使用一下代码调用globalObject的Test方法：&lt;/p&gt;&lt;div class="code"&gt;  VARIANT &lt;span class="kwrd"&gt;params&lt;/span&gt;[10];&lt;br/&gt;VARIANT ret;&lt;br/&gt;&lt;span class="rem"&gt;//获取页面window&lt;/span&gt;&lt;br/&gt;IDispatch *pHtmlWindow = pBrowser-&amp;gt;GetHtmlWindow();&lt;br/&gt;&lt;span class="rem"&gt;//获取globalObject&lt;/span&gt;&lt;br/&gt;CVariant globalObject;&lt;br/&gt;&lt;span class="kwrd"&gt;params&lt;/span&gt;[0].vt = VT_BSTR;&lt;br/&gt;&lt;span class="kwrd"&gt;params&lt;/span&gt;[0].bstrVal = L&lt;span class="str"&gt;&amp;quot;globalObject&amp;quot;&lt;/span&gt;;&lt;br/&gt;CWebBrowserBase::GetProperty(pHtmlWindow, L&lt;span class="str"&gt;&amp;quot;globalObject&amp;quot;&lt;/span&gt;, &amp;amp;globalObject);&lt;br/&gt;&lt;span class="rem"&gt;//调用globalObject.Test&lt;/span&gt;&lt;br/&gt;CWebBrowserBase::InvokeMethod(globalObject.pdispVal, L&lt;span class="str"&gt;&amp;quot;Test&amp;quot;&lt;/span&gt;, &amp;amp;ret, &lt;span class="kwrd"&gt;params&lt;/span&gt;, 0);&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;&lt;strong&gt;2、在网页中调用客户端的方法&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;上文我们已经介绍了如何在C++中调用WebBrowser中的对象，接下来，将介绍如何在页面中调用客户端中的函数和对象：&lt;/p&gt;&lt;p&gt;&lt;strong&gt;(1) 通过window.external调用&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;下面将示例如何通过window.external调用客户端中的函数,假设在C++中定义了一个名为CppCall的函数：&lt;/p&gt;&lt;div class="code"&gt;  &lt;span class="kwrd"&gt;void&lt;/span&gt; CppCall()&lt;br/&gt;{&lt;br/&gt;    MessageBox(NULL, L&lt;span class="str"&gt;&amp;quot;您调用了CppCall&amp;quot;&lt;/span&gt;, L&lt;span class="str"&gt;&amp;quot;提示(C++)&amp;quot;&lt;/span&gt;, 0);&lt;br/&gt;}&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;定义一个对象，并且实现IDispatch接口：&lt;/p&gt;&lt;div class="code"&gt;  &lt;span class="kwrd"&gt;class&lt;/span&gt; ClientCall:&lt;span class="kwrd"&gt;public&lt;/span&gt; IDispatch&lt;br/&gt;{&lt;br/&gt;    &lt;span class="kwrd"&gt;long&lt;/span&gt; _refNum;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt;:&lt;br/&gt;    ClientCall()&lt;br/&gt;    {&lt;br/&gt;        _refNum = 1;&lt;br/&gt;    }&lt;br/&gt;    ~ClientCall(&lt;span class="kwrd"&gt;void&lt;/span&gt;)&lt;br/&gt;    {&lt;br/&gt;    }&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt;:&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// IUnknown Methods&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    STDMETHODIMP QueryInterface(REFIID iid,&lt;span class="kwrd"&gt;void&lt;/span&gt;**ppvObject)&lt;br/&gt;    {&lt;br/&gt;        *ppvObject = NULL;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (iid == IID_IUnknown)    *ppvObject = &lt;span class="kwrd"&gt;this&lt;/span&gt;;&lt;br/&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (iid == IID_IDispatch)    *ppvObject = (IDispatch*)&lt;span class="kwrd"&gt;this&lt;/span&gt;;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(*ppvObject)&lt;br/&gt;        {&lt;br/&gt;            AddRef();&lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; S_OK;&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; E_NOINTERFACE;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    STDMETHODIMP_(ULONG) AddRef()&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; ::InterlockedIncrement(&amp;amp;_refNum);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    STDMETHODIMP_(ULONG) Release()&lt;br/&gt;    {&lt;br/&gt;        ::InterlockedDecrement(&amp;amp;_refNum);&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(_refNum == 0)&lt;br/&gt;        {&lt;br/&gt;            delete &lt;span class="kwrd"&gt;this&lt;/span&gt;;&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; _refNum;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// IDispatch Methods&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    HRESULT _stdcall GetTypeInfoCount(&lt;br/&gt;        unsigned &lt;span class="kwrd"&gt;int&lt;/span&gt; * pctinfo) &lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; E_NOTIMPL;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    HRESULT _stdcall GetTypeInfo(&lt;br/&gt;        unsigned &lt;span class="kwrd"&gt;int&lt;/span&gt; iTInfo,&lt;br/&gt;        LCID lcid,&lt;br/&gt;        ITypeInfo FAR* FAR* ppTInfo) &lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; E_NOTIMPL;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    HRESULT _stdcall GetIDsOfNames(&lt;br/&gt;        REFIID riid, &lt;br/&gt;        OLECHAR FAR* FAR* rgszNames, &lt;br/&gt;        unsigned &lt;span class="kwrd"&gt;int&lt;/span&gt; cNames, &lt;br/&gt;        LCID lcid, &lt;br/&gt;        DISPID FAR* rgDispId &lt;br/&gt;    )&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(lstrcmp(rgszNames[0], L&lt;span class="str"&gt;&amp;quot;CppCall&amp;quot;&lt;/span&gt;)==0)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="rem"&gt;//网页调用window.external.CppCall时，会调用这个方法获取CppCall的ID&lt;/span&gt;&lt;br/&gt;            *rgDispId = 100;&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; S_OK;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    HRESULT _stdcall Invoke(&lt;br/&gt;        DISPID dispIdMember,&lt;br/&gt;        REFIID riid,&lt;br/&gt;        LCID lcid,&lt;br/&gt;        WORD wFlags,&lt;br/&gt;        DISPPARAMS* pDispParams,&lt;br/&gt;        VARIANT* pVarResult,&lt;br/&gt;        EXCEPINFO* pExcepInfo,&lt;br/&gt;        unsigned &lt;span class="kwrd"&gt;int&lt;/span&gt;* puArgErr&lt;br/&gt;    )&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(dispIdMember == 100)&lt;br/&gt;        {&lt;br/&gt;            &lt;span class="rem"&gt;//网页调用CppCall时，或根据获取到的ID调用Invoke方法&lt;/span&gt;&lt;br/&gt;            CppCall();&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; S_OK;&lt;br/&gt;    }&lt;br/&gt;};&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;定义类ClientCall后，就可以创建一个ClientCall的对象，传递给WebBrowser，使得网页中可以通过window.external调用CppCall，要实现这些功能，WebBrowser需要实现IDocHostUIHandler接口，并重写GetExternal方法以返回一个ClientCall对象：&lt;/p&gt;&lt;div class="code"&gt;  ClientCall *pClientCall;&lt;br/&gt;pClientCall = &lt;span class="kwrd"&gt;new&lt;/span&gt; ClientCall();&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;virtual&lt;/span&gt; HRESULT STDMETHODCALLTYPE GetExternal(IDispatch **ppDispatch)&lt;br/&gt;{&lt;br/&gt;    &lt;span class="rem"&gt;//重写GetExternal返回一个ClientCall对象&lt;/span&gt;&lt;br/&gt;    *ppDispatch = pClientCall;&lt;br/&gt;    &lt;span class="kwrd"&gt;return&lt;/span&gt; S_OK;&lt;br/&gt;}&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;接下来，就可以在网页中调用了：&lt;/p&gt;&lt;div class="code"&gt;  window.external.CppCall()&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;strong&gt;(2)向网页传递回调函数&lt;/strong&gt; &lt;p&gt;&lt;font color="#ff0000"&gt;向网页传递回调函数的一个典型应用就是在客户端中用C++处理DOM的事件&lt;/font&gt;(例如，处理按钮的onclick事件)，这里要注意的是，与C++不同的是，在网页中，&lt;font color="#ff0000"&gt;所谓的函数，其实就是一个具有call方法的对象&lt;/font&gt;，因此，向网页传递一个回调函数，其实就是传递一个实现了call方法的对象，因此，我们必须定义一个C++类，并实现IDispatch接口：&lt;/p&gt;&lt;div class="code"&gt;  typedef &lt;span class="kwrd"&gt;void&lt;/span&gt; _stdcall JsFunction_Callback(LPVOID pParam);&lt;br/&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;class&lt;/span&gt; JsFunction:&lt;span class="kwrd"&gt;public&lt;/span&gt; IDispatch&lt;br/&gt;{&lt;br/&gt;    &lt;span class="kwrd"&gt;long&lt;/span&gt; _refNum;&lt;br/&gt;    JsFunction_Callback *m_pCallback;&lt;br/&gt;    LPVOID m_pParam;&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt;:&lt;br/&gt;    JsFunction(JsFunction_Callback *pCallback, LPVOID pParam)&lt;br/&gt;    {&lt;br/&gt;        _refNum = 1;&lt;br/&gt;        m_pCallback = pCallback;&lt;br/&gt;        m_pParam = pParam;&lt;br/&gt;    }&lt;br/&gt;    ~JsFunction(&lt;span class="kwrd"&gt;void&lt;/span&gt;)&lt;br/&gt;    {&lt;br/&gt;    }&lt;br/&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt;:&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// IUnknown Methods&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    STDMETHODIMP QueryInterface(REFIID iid,&lt;span class="kwrd"&gt;void&lt;/span&gt;**ppvObject)&lt;br/&gt;    {&lt;br/&gt;        *ppvObject = NULL;&lt;br/&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt; (iid == IID_IOleClientSite)    *ppvObject = (IOleClientSite*)&lt;span class="kwrd"&gt;this&lt;/span&gt;;&lt;br/&gt;        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (iid == IID_IUnknown)    *ppvObject = &lt;span class="kwrd"&gt;this&lt;/span&gt;;&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(*ppvObject)&lt;br/&gt;        {&lt;br/&gt;            AddRef();&lt;br/&gt;            &lt;span class="kwrd"&gt;return&lt;/span&gt; S_OK;&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; E_NOINTERFACE;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    STDMETHODIMP_(ULONG) AddRef()&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; ::InterlockedIncrement(&amp;amp;_refNum);&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    STDMETHODIMP_(ULONG) Release()&lt;br/&gt;    {&lt;br/&gt;        ::InterlockedDecrement(&amp;amp;_refNum);&lt;br/&gt;        &lt;span class="kwrd"&gt;if&lt;/span&gt;(_refNum == 0)&lt;br/&gt;        {&lt;br/&gt;            delete &lt;span class="kwrd"&gt;this&lt;/span&gt;;&lt;br/&gt;        }&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; _refNum;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    &lt;span class="rem"&gt;// IDispatch Methods&lt;/span&gt;&lt;br/&gt;&lt;br/&gt;    HRESULT _stdcall GetTypeInfoCount(&lt;br/&gt;        unsigned &lt;span class="kwrd"&gt;int&lt;/span&gt; * pctinfo) &lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; E_NOTIMPL;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    HRESULT _stdcall GetTypeInfo(&lt;br/&gt;        unsigned &lt;span class="kwrd"&gt;int&lt;/span&gt; iTInfo,&lt;br/&gt;        LCID lcid,&lt;br/&gt;        ITypeInfo FAR* FAR* ppTInfo) &lt;br/&gt;    {&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; E_NOTIMPL;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    HRESULT _stdcall GetIDsOfNames(&lt;br/&gt;        REFIID riid, &lt;br/&gt;        OLECHAR FAR* FAR* rgszNames, &lt;br/&gt;        unsigned &lt;span class="kwrd"&gt;int&lt;/span&gt; cNames, &lt;br/&gt;        LCID lcid, &lt;br/&gt;        DISPID FAR* rgDispId &lt;br/&gt;    )&lt;br/&gt;    {&lt;br/&gt;        &lt;span class="rem"&gt;//令人费解的是，网页调用函数的call方法时，没有调用GetIDsOfNames获取call的ID，而是直接调用Invoke&lt;/span&gt;&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; E_NOTIMPL;&lt;br/&gt;    }&lt;br/&gt;&lt;br/&gt;    HRESULT _stdcall Invoke(&lt;br/&gt;        DISPID dispIdMember,&lt;br/&gt;        REFIID riid,&lt;br/&gt;        LCID lcid,&lt;br/&gt;        WORD wFlags,&lt;br/&gt;        DISPPARAMS* pDispParams,&lt;br/&gt;        VARIANT* pVarResult,&lt;br/&gt;        EXCEPINFO* pExcepInfo,&lt;br/&gt;        unsigned &lt;span class="kwrd"&gt;int&lt;/span&gt;* puArgErr&lt;br/&gt;    )&lt;br/&gt;    {&lt;br/&gt;        m_pCallback(m_pParam);&lt;br/&gt;        &lt;span class="kwrd"&gt;return&lt;/span&gt; S_OK;&lt;br/&gt;    }&lt;br/&gt;};&lt;/div&gt;&lt;p&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;接下来，我们就可以使用JsFunction向网页传递回调，以下代码用于处理按钮的onclick事件：&lt;/p&gt;&lt;div class="code"&gt;  &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; _stdcall button1_onclick(LPVOID pParam)&lt;br/&gt;{&lt;br/&gt;    MainForm *pMainForm = (MainForm*)pParam;&lt;br/&gt;    MessageBox(pMainForm-&amp;gt;hWnd, L&lt;span class="str"&gt;&amp;quot;您点击了button1&amp;quot;&lt;/span&gt;, L&lt;span class="str"&gt;&amp;quot;提示(C++)&amp;quot;&lt;/span&gt;, 0);&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;VARIANT &lt;span class="kwrd"&gt;params&lt;/span&gt;[10];&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;//获取window&lt;/span&gt;&lt;br/&gt;IDispatch *pHtmlWindow = GetHtmlWindow();&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;//获取document&lt;/span&gt;&lt;br/&gt;CVariant document;&lt;br/&gt;&lt;span class="kwrd"&gt;params&lt;/span&gt;[0].vt = VT_BSTR;&lt;br/&gt;&lt;span class="kwrd"&gt;params&lt;/span&gt;[0].bstrVal = L&lt;span class="str"&gt;&amp;quot;document&amp;quot;&lt;/span&gt;;&lt;br/&gt;GetProperty(pHtmlWindow, L&lt;span class="str"&gt;&amp;quot;document&amp;quot;&lt;/span&gt;, &amp;amp;document);&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;//获取button1&lt;/span&gt;&lt;br/&gt;CVariant button1;&lt;br/&gt;&lt;span class="kwrd"&gt;params&lt;/span&gt;[0].vt = VT_BSTR;&lt;br/&gt;&lt;span class="kwrd"&gt;params&lt;/span&gt;[0].bstrVal = L&lt;span class="str"&gt;&amp;quot;button1&amp;quot;&lt;/span&gt;;&lt;br/&gt;InvokeMethod(document.pdispVal, L&lt;span class="str"&gt;&amp;quot;getElementById&amp;quot;&lt;/span&gt;, &amp;amp;button1, &lt;span class="kwrd"&gt;params&lt;/span&gt;, 1);&lt;br/&gt;&lt;br/&gt;&lt;span class="rem"&gt;//处理button1的onclick事件&lt;/span&gt;&lt;br/&gt;&lt;span class="kwrd"&gt;params&lt;/span&gt;[0].vt = VT_DISPATCH;&lt;br/&gt;&lt;span class="kwrd"&gt;params&lt;/span&gt;[0].pdispVal = &lt;span class="kwrd"&gt;new&lt;/span&gt; JsFunction(button1_onclick, &lt;span class="kwrd"&gt;this&lt;/span&gt;);&lt;br/&gt;SetProperty(button1.pdispVal, L&lt;span class="str"&gt;&amp;quot;onclick&amp;quot;&lt;/span&gt;, &lt;span class="kwrd"&gt;params&lt;/span&gt;);&lt;/div&gt;&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre{font-size: small;color: black;font-family: consolas, "Courier New", courier, monospace;/*white-space: pre;*/}.csharpcode pre { margin: 0em; }.csharpcode .rem { color: #008000; }.csharpcode .kwrd { color: #0000ff; }.csharpcode .str { color: #006080; }.csharpcode .op { color: #0000c0; }.csharpcode .preproc { color: #cc6633; }.csharpcode .asp { background-color: #ffff00; }.csharpcode .html { color: #800000; }.csharpcode .attr { color: #ff0000; }.csharpcode .alt {background-color: #f4f4f4;width: 100%;margin: 0em;}.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;p&gt;以上就是笔者开发&lt;a href="http://www.luchuncheng.com"&gt;Lesktop开源WebIM&lt;/a&gt;时使用WebBrowser的经验总结，如有纰漏，敬请指出。&lt;/p&gt;&lt;div class="link"&gt;&lt;a href="http://files.cnblogs.com/lucc/webbrowser.zip" target="_blank"&gt;SDK实现WebBrowser及演示代码&lt;/a&gt;[&lt;a href="javascript:_PostComment(null, true)"&gt;好文，推荐一下&lt;/a&gt;&lt;a href="javascript:_PostComment('看不懂', false)"&gt;看不懂&lt;/a&gt;]&lt;/div&gt;&lt;img src="http://www.cnblogs.com/lucc/aggbug/1886087.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lucc/archive/2010/11/24/1886087.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2010/09/14/1826236.html</id><title type="text">开源WebOS</title><summary type="text">今天腾讯发布了WebOS风格的WebQQ2.0，只要你拥有一个虚拟空间，使用本文提供的源代码，你也可以部署一个属于自己的WebOS。</summary><published>2010-09-14T11:44:00Z</published><updated>2010-09-14T11:44:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2010/09/14/1826236.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2010/09/14/1826236.html"/><content type="html">&lt;div class="link"&gt;&lt;a href="http://files.cnblogs.com/lucc/LOS-1.0.1.30.zip" target="_blank"&gt;源代码下载&lt;/a&gt;&lt;a href="http://webos.lesktop.com" target="_blank"&gt;在线演示&lt;/a&gt;&lt;a&gt;QQ讨论群:25160257&lt;/a&gt;[&lt;a href="javascript:_PostComment(null, true)"&gt;好文，推荐一下&lt;/a&gt;&lt;a href="javascript:_PostComment('看不懂', false)"&gt;看不懂&lt;/a&gt;] &lt;/div&gt;&lt;p&gt;今天腾讯发布了WebOS风格的WebQQ2.0，只要你拥有一个虚拟空间，使用本文提供的源代码，你也可以部署一个属于自己的WebOS来,效果如下:&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/image_3.png" width="610" height="484" /&gt; &lt;/p&gt;  &lt;p&gt;这个WebOS的功能在&lt;a href="http://www.cnblogs.com/lucc/archive/2010/04/07/1706706.html" target="_blank"&gt;之前的文章&lt;/a&gt;已有介绍过，不在重复，这里主要介绍一个之前没有开放的功能：在线开发。&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;&lt;strong&gt;这里的在线开发指的是：使用WebOS提供的开发工具，基于WebOS提供的API开发出可以运行于该WebOS的应用程序&lt;/strong&gt;&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;下面通过几张图片介绍&lt;strong&gt;如何使用开发工具&lt;/strong&gt;：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/2_2.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="2" border="0" alt="2" src="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/2_thumb.png" width="639" height="480" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="5" border="0" alt="5" src="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/5_3.png" width="640" height="475" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="3" border="0" alt="3" src="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/3_3.png" width="643" height="484" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;点击保存后，&lt;strong&gt;开发工具会生成可执行文件，你可以脱离开发工具直接运行生成的应用程序&lt;/strong&gt;：&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="4" border="0" alt="4" src="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/4_3.png" width="644" height="479" /&gt; &lt;/p&gt;  &lt;p&gt;这次同时还开发了WebOS上所有应用的源代码（IM，图片浏览，CHM阅读器等等），用admin登录后，可以在/admin/&lt;font color="#ff0000"&gt;Home/Projects&lt;/font&gt;中找到这些应用程序对应的工程文件：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/8.png"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="8" border="0" alt="8" src="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/8_thumb.png" width="621" height="480" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;部署指南：&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;1.建立虚拟目录：&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="6" border="0" alt="6" src="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/6_1.png" width="635" height="489" /&gt; &lt;/p&gt;  &lt;p&gt;&lt;/p&gt;  &lt;p&gt;2.添加ISAPI过滤器&lt;/p&gt;  &lt;p&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="7" border="0" alt="7" src="http://images.cnblogs.com/cnblogs_com/lucc/WindowsLiveWriter/WebOS_11394/7_1.png" width="478" height="444" /&gt; &lt;/p&gt;  &lt;p&gt;3.管理员密码：&lt;/p&gt;  &lt;p&gt;用户名：admin&lt;/p&gt;  &lt;p&gt;密码:admin&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;/p&gt;  &lt;p&gt;&lt;div class="link"&gt;&lt;a href="http://files.cnblogs.com/lucc/LOS-1.0.1.30.zip" target="_blank"&gt;源代码下载&lt;/a&gt;&lt;a href="http://webos.lesktop.com" target="_blank"&gt;在线演示&lt;/a&gt;&lt;a&gt;QQ讨论群:25160257&lt;/a&gt;[&lt;a href="javascript:_PostComment(null, true)"&gt;好文，推荐一下&lt;/a&gt;&lt;a href="javascript:_PostComment('看不懂', false)"&gt;看不懂&lt;/a&gt;] &lt;/div&gt;&lt;img src="http://www.cnblogs.com/lucc/aggbug/1826236.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lucc/archive/2010/09/14/1826236.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2010/09/09/1821869.html</id><title type="text">云骞开源即时通讯软件</title><summary type="text">Lesktop2.0 主要增加了好友列表，消息提示等，当用户登录WebIM后，会自动提示新消息，Lesktop2.0 还提供了桌面客户端，可以同时以Web模式和桌面模式运行。</summary><published>2010-09-08T16:30:00Z</published><updated>2010-09-08T16:30:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2010/09/09/1821869.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2010/09/09/1821869.html"/><content type="html">&lt;p&gt;云骞开源IM是一款使用ASP.NET，Ajax和Comet等技术开发的轻量级IM。主要特点有：&lt;/p&gt;  &lt;p&gt;1、云骞开源IM的服务端实际上就是一个ASP.NET网站，因此不需要使用独立服务器，&lt;strong&gt;仅需要一个支持.NET2.0的Web空间即可将IM部署到互联网上&lt;/strong&gt;。&lt;/p&gt;  &lt;p&gt;2、只需要&lt;strong&gt;拷贝两个文件夹，并在页面中嵌入一行代码&lt;/strong&gt;，就可以将IM集成到自己的网站或企业内部的OA系统中。 &lt;/p&gt;  &lt;p&gt;&lt;strong&gt;源代码下载及嵌入方法请参考：&lt;/strong&gt;&lt;a href="http://www.luchuncheng.com/blog/article.aspx?ID=12" target="_blank"&gt;http://www.luchuncheng.com/blog/article.aspx?ID=12&lt;/a&gt;。&lt;/p&gt;  &lt;p&gt;3、可以同时以客户端模式和Web模式运行，两者拥有完全一样的操作界面。&lt;/p&gt;  &lt;p&gt;客户端模式：&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.luchuncheng.com/posts/res/desktop_pre.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="桌面模式" border="0" alt="桌面模式" src="http://images.cnblogs.com/cnblogs_com/lucc/201102/201102192332589272.jpg" width="614" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Web模式（兼容IE6,7,8,FireFox,Chrome等主流浏览器）:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.luchuncheng.com/posts/res/webos_pre.jpg"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="WebOS模式（可嵌入到网页中，支持Firefox,Chorme,IE等主流浏览器）" border="0" alt="WebOS模式（可嵌入到网页中，支持Firefox,Chorme,IE等主流浏览器）" src="http://images.cnblogs.com/cnblogs_com/lucc/201102/20110219233258668.jpg" width="547" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;4、提供了可视化开发工具，以方便您快速开发IM所需的界面和控件，这些界面和控件，可以同时运行于客户端和WEB桌面，不需要编写两套代码。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lucc/201102/201102192333004091.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201102/201102192333012073.png" width="644" height="464" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;5、消息记录（包括消息中的图片和文件）都存储在服务器上，只要可以上网，随时随地都可以浏览您的消息记录。&lt;/p&gt;  &lt;p&gt;&lt;a href="http://images.cnblogs.com/cnblogs_com/lucc/201102/201102200144076889.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/lucc/201102/201102200144073267.png" width="615" height="484" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;hr /&gt;  &lt;p&gt;&lt;strong&gt;云骞企业IM&lt;/strong&gt;&lt;/p&gt;  &lt;p&gt;云骞企业IM是在开源IM基础上开发的功能更全面的企业版IM，主要的改进有：&lt;/p&gt;  &lt;p&gt;1、优化UI性能：云骞开源IM为了保证客户端更加精简，将界面（一个动态页面）及相关的脚本，图片等放在服务器上，因此打开窗口时需要先访问WEB服务器，启动较慢。企业版将客户端需要的资源存储在本地，以提高常用窗口的启动速度。当然，企业版仍然支持客户端和Web两种模式，仍然支持嵌入到已有的网站中，可以与企业内部的OA系统等集成。&lt;/p&gt;  &lt;p&gt;2、提供在线客服功能，可将客服功能嵌入到其他网站中。&lt;/p&gt;  &lt;p&gt;3、支持局域网内文件传送，离线文件以及群共享等。&lt;/p&gt;  &lt;p&gt;4、支持多人会话。&lt;/p&gt;  &lt;p&gt;5、支持企业组织架构，可支持多部门隶属。&lt;/p&gt;  &lt;p&gt;6、支持自动更新。&lt;/p&gt;  &lt;p&gt;&lt;font color="#ff0000"&gt;企业版试用：&lt;/font&gt;&lt;a href="http://eim.cc/trial.aspx" target="_blank"&gt;http://eim.cc/trial.aspx&lt;/a&gt;&lt;/p&gt;&lt;img src="http://www.cnblogs.com/lucc/aggbug/1821869.html?type=1" width="1" height="1" alt=""/&gt;&lt;p&gt;&lt;a href="http://www.cnblogs.com/lucc/archive/2010/09/09/1821869.html" target="_blank"&gt;本文链接&lt;/a&gt;&lt;/p&gt;</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2010/05/27/1745827.html</id><title type="text">一步一步打造WebIM(5)——将WebIM嵌入到页面中</title><summary type="text">在之前的文章中，已经开发了一个简单的WebIM，但是这个WebIM是在独立的页面中的，今天发布的WebIM是一个可以嵌入到自己网页中的版本，你只需添加少量的代码，就可以在页面中嵌入一个WebIM。</summary><published>2010-05-27T14:38:00Z</published><updated>2010-05-27T14:38:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2010/05/27/1745827.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2010/05/27/1745827.html"/><content type="text">在之前的文章中，已经开发了一个简单的WebIM，但是这个WebIM是在独立的页面中的，今天发布的WebIM是一个可以嵌入到自己网页中的版本，你只需添加少量的代码，就可以在页面中嵌入一个WebIM。</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2010/05/25/1743877.html</id><title type="text">一步一步打造WebIM(4)——Comet的特殊之处</title><summary type="text">在一步一步打造WebIM(1)一文中已经使用Comet实现了一个简单的WebIM，那么，Comet究竟和一般的打开网页有何区别，本文将通过编写一个简单的HTTP服务器来说明两者的区别。</summary><published>2010-05-25T12:38:00Z</published><updated>2010-05-25T12:38:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2010/05/25/1743877.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2010/05/25/1743877.html"/><content type="text">在一步一步打造WebIM(1)一文中已经使用Comet实现了一个简单的WebIM，那么，Comet究竟和一般的打开网页有何区别，本文将通过编写一个简单的HTTP服务器来说明两者的区别。</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2010/05/18/1738718.html</id><title type="text">网页信息抓取</title><summary type="text">之前做聊天室时，由于在聊天室中提供了新闻阅读的功能，写了一个从网页中抓取信息（如最新的头条新闻，新闻的来源，标题，内容等）的类，本文将介绍如何使用这个类来抓取网页中需要的信息。</summary><published>2010-05-18T15:16:00Z</published><updated>2010-05-18T15:16:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2010/05/18/1738718.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2010/05/18/1738718.html"/><content type="text">之前做聊天室时，由于在聊天室中提供了新闻阅读的功能，写了一个从网页中抓取信息（如最新的头条新闻，新闻的来源，标题，内容等）的类，本文将介绍如何使用这个类来抓取网页中需要的信息。</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2010/05/16/1736537.html</id><title type="text">一步一步打造WebIM(3)——性能测试</title><summary type="text">在一步一步打造WebIM(1)和(2)中，已经讨论了如何开发一个WebIM，并且使用缓存来提高WebIM的性能，本文将编写一个程序模拟大量用户登录来对WebIM进行性能测试。</summary><published>2010-05-15T19:43:00Z</published><updated>2010-05-15T19:43:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2010/05/16/1736537.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2010/05/16/1736537.html"/><content type="text">在一步一步打造WebIM(1)和(2)中，已经讨论了如何开发一个WebIM，并且使用缓存来提高WebIM的性能，本文将编写一个程序模拟大量用户登录来对WebIM进行性能测试。</content></entry><entry><id>http://www.cnblogs.com/lucc/archive/2010/04/28/1723326.html</id><title type="text">在线CHM阅读器（2）——文件提取及关键文件解析</title><summary type="text">在在线CHM阅读器(1)一文中已提到，CHM其实就是一个结构化存储文件(Structured Storage)，如果也阅读CHM文档，就必须将文件，图片等从CHM文件中提取出来...</summary><published>2010-04-28T14:18:00Z</published><updated>2010-04-28T14:18:00Z</updated><author><name>卢春城</name><uri>http://www.cnblogs.com/lucc/</uri></author><link rel="alternate" href="http://www.cnblogs.com/lucc/archive/2010/04/28/1723326.html"/><link rel="alternate" type="text/html" href="http://www.cnblogs.com/lucc/archive/2010/04/28/1723326.html"/><content type="text">在在线CHM阅读器(1)一文中已提到，CHM其实就是一个结构化存储文件(Structured Storage)，如果也阅读CHM文档，就必须将文件，图片等从CHM文件中提取出来...</content></entry></feed>
