﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-More than C++-随笔分类-插件开发</title><link>http://www.cppblog.com/Lee/category/10159.html</link><description>Beyond  C++</description><language>zh-cn</language><lastBuildDate>Thu, 09 Apr 2009 17:54:45 GMT</lastBuildDate><pubDate>Thu, 09 Apr 2009 17:54:45 GMT</pubDate><ttl>60</ttl><item><title>编写插件锁住Word文档窗口  ——API和COM接口Hook综合演示（转）</title><link>http://www.cppblog.com/Lee/archive/2009/04/09/79392.html</link><dc:creator>David Lee</dc:creator><author>David Lee</author><pubDate>Thu, 09 Apr 2009 14:55:00 GMT</pubDate><guid>http://www.cppblog.com/Lee/archive/2009/04/09/79392.html</guid><wfw:comment>http://www.cppblog.com/Lee/comments/79392.html</wfw:comment><comments>http://www.cppblog.com/Lee/archive/2009/04/09/79392.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee/comments/commentRss/79392.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee/services/trackbacks/79392.html</trackback:ping><description><![CDATA[关键字　API Hook，COM Hook，ATL，Office 文档安全，C++<br /><br />　　现在的木马后门种类非常之多，其中有些木马专门以Office 文档为窃取目标，我最近做了一些Anti这些木马的工作，在工作中我基本上实现了阻止未知程序利用Office自动化接口窃取Word内容，但限于公司利益我只能写一些基本上已经比较成熟和公开的技术，当然其中了包含我的设计思想，我想多多少少会让你有所收获，你可任意转载文章，但请注明作者和出处，谢谢！<br />　　首先我们知道Ole拖放是由DoDragDrop启动的，为此你可以事先要准备一些参数给DoDragDrop使用，最开始我的想法是直接阻止DoDragDrop调用，后来我发现这样做会使Word文档窗口内部的拖放操作失效，这会给人一种很不好的感觉，好的保护软件应该在客户没有感觉到不方便的情况提供保护，而后我又仔细看了DoDragDrop的参数想发现有没有什么可以利用的地方，我发现它有四个参数：
<ul><li>IDataObject * pDataObject； 
</li><li>IDropSource * pDropSource； 
</li><li>DWORD dwOKEffect； 
</li><li>DWORD * pdwEffect； </li></ul><p>　　后两个参数基本上没有什么利用价值，我想到Hook IDataObject的GetData函数，可是在Ole Drop客户端编程时，通常当我调用COleDataObject的相关成员函数时拖放已经差不多完成，鼠标已经在我的程序窗口上了。<br />　　而我现在的想法是在拖放操作刚离开Word的文档窗口，还没有到达外部程序窗口时就让它失效，这样Hook IDataObject的虚函数肯定不行，我只有再研究一下最后一个没有研究过的参数pDropSource，它是一个IDropSource类型指针，我发现它有一个虚函数QueryContinueDrag查看了一下MSDN发现它似乎就是我要找的。<br />　　我的理解是这个函数是让Ole拖放的服务端在调用DoDragDrop启动Ole拖放操作后，有机会取消拖放操作而设的一个CallBack，于是我写了一段代码Hook住DoDragDrop并从DoDragDrop中进一步Hook住IDropSource的QueryContinueDrag虚函数，我发现它会全程跟踪整个拖放操作，只要这个CallBack一返回DRAGDROP_S_CANCEL整个拖放操作就会被取消，这样我只要知道当前鼠标下的窗口是否是文档窗口就可以了，一旦离开了文档窗口我就让这个CallBack返回DRAGDROP_S_CANCEL取消整个拖放操作。<br />　　这样做就可以不影响文档窗口内部的拖放操作，又可以阻止将文档窗口内部的东西拖放到其它程序中，基本上不会让客户感到不方便，这很有意思！不是吗?<br />　　那么从鼠标位置得到窗口句柄可能吗?答案是肯定的！ GetCursorPos函数可以返回一个POINT变量，它指示当前的鼠标位置，而WindowFromPoint则可以返回某一个POINT位置下的窗口句柄。写到这里我想差不多已经说完了我的思路，不知道你是否看得明白。<br />　　总结一下，用ATL向导生成一个COM框架，增加一个ATL简单对象，在这个对象上实现_IDTExtensibility2接口，在_IDTExtensibility2的OnConnection中Hook住DoDragDrop API，在Word调用DoDragDrop时记录下当前的文档窗口句柄，并Hook住第二个参数pDropSource的QueryContinueDrag虚函数，在QueryContinueDrag里跟踪当前鼠下的窗口是否还是文档窗口(比较句柄是否等于DoDragDrop时记录下的文档窗口句柄)，如果不是则返回DRAGDROP_S_CANCE取消拖放操作，并弹出一个警告信息的MessageBox，否则执行原有的操作(让拖放操作正常进行)。<br /><br />最后，别忘了注册你的Word插件(用Regsvr32。exe)，详细的键值和代码细节见源程序吧！<br /><br />2005年10月15日夜<br /><br />参考资料：</p><ul><li>MSDN October 2001 
</li><li>Microsoft Office 2000/Visual Basic Programmer''s Guide 
</li><li>ATL Internals 
</li><li>Inside C++ Object Model </li></ul><img src ="http://www.cppblog.com/Lee/aggbug/79392.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee/" target="_blank">David Lee</a> 2009-04-09 22:55 <a href="http://www.cppblog.com/Lee/archive/2009/04/09/79392.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用VC6.0编写Word插件(Office2K、XP、03)（转）</title><link>http://www.cppblog.com/Lee/archive/2009/04/09/79391.html</link><dc:creator>David Lee</dc:creator><author>David Lee</author><pubDate>Thu, 09 Apr 2009 14:53:00 GMT</pubDate><guid>http://www.cppblog.com/Lee/archive/2009/04/09/79391.html</guid><wfw:comment>http://www.cppblog.com/Lee/comments/79391.html</wfw:comment><comments>http://www.cppblog.com/Lee/archive/2009/04/09/79391.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee/comments/commentRss/79391.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee/services/trackbacks/79391.html</trackback:ping><description><![CDATA[
		<a href="http://www.vcgood.com/bbs/forum_posts.asp?tid=1534" target="_blank">http://www.vcgood.com/bbs/forum_posts.asp?tid=1534</a>
		<br />
		<br />
		<p>最近因为工作的需要，学习了一下Office插件的编写方法。在走了不少弯路以后，最后终于把编写插件的原理给搞清楚了，不敢独享，拿出来跟大家共享一下。下面就以Word 2003为例，向大家简单介绍一下。<br />第一步，利用向导生成一个ATL COM AppWizard的新工程。<br /><br /><img id="chkImg1" height="359" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin01.jpg" width="554" border="0" name="chkImg2" /><br /><strong>图1</strong></p>
		<p>在向导的第一个对话框中，服务器类型选择Dynamic Link Library(DLL)，然后单击Finish即可。 
</p>
		<p>
				<img id="chkImg1" height="422" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin02.jpg" width="553" border="0" name="chkImg2" />
		</p>
		<p>
				<strong>图2</strong>
		</p>
		<p>然后，选取菜单Insert-&gt;New ATL Object项，在弹出的ATL对象向导对话框中选中相应Objects对应右侧的Simple Object选项，点击下一步。 
</p>
		<p>
				<img id="chkImg1" height="257" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin03.jpg" width="412" border="0" name="chkImg2" />
		</p>
		<p>
				<strong>图3</strong>
		</p>
		<p>在弹出的对话框中ShortName中输入相应名称，点确定完成插入ATL对象。 
</p>
		<p>
				<img id="chkImg1" height="261" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin04.jpg" width="419" border="0" name="chkImg2" />
		</p>
		<p>
				<strong>图4</strong>
		</p>
		<p>这样一个简单的基于ATL的COM组件工程就建立成功了。 
</p>
		<p>第二步，通过导入类型库来实现_IDTExtensibility2接口。在ClassView中的新加的类上点鼠标右键，在弹出的右键菜单中选Implement Interface项。 
</p>
		<p>
				<img id="chkImg1" height="462" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin05.jpg" width="363" border="0" name="chkImg2" />
		</p>
		<p>
				<strong>图5</strong>
		</p>
		<p>在弹出的实现接口对话框中点击Add Typelib 
</p>
		<p>
				<img id="chkImg1" height="337" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin06.jpg" width="425" border="0" name="chkImg2" />
		</p>
		<p>
				<strong>图6</strong>
		</p>
		<p>在弹出的Browse Type Libraries对话框中，选取Microsoft Add-in Designer(1.0)子项，点OK按钮 
</p>
		<p>
				<img id="chkImg1" height="344" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin07.jpg" width="386" border="0" name="chkImg2" />
		</p>
		<p>
				<strong>图7</strong>
		</p>
		<p>在弹出的接口列表对话框中选中_IDTExtensibility2接口，点OK按钮完成导入 
</p>
		<p>
				<img id="chkImg1" height="337" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin08.jpg" width="425" border="0" name="chkImg2" />
		</p>
		<p>这样的话，系统将会自动为你生成空的五个所需接口函数，分别是OnConnection、OnDisconnection、OnAddInsUpdate、OnStartupComplete、OnBeginShutdown。 
</p>
		<p>第三步，通过上面的两个步骤，我们的插件框架已经形成，但是Office怎么知道启动的时候要来把我们的插件Load起来呢？Office的不同组件，例如Word、Excel、Outlook等怎么知道去Load自己的插件呢？答案就是在注册表中加入相应的键值。打开文件视图FileView—&gt;Resource File中的rgs文件，加入以下代码：</p>
		<pre>HKCU
    {
      Software
       {
        Microsoft
        {
          Office
             { 
            Word
               {
             Addins
               {
               ''TestAddin.SimAddin''
                { 
                 val FriendlyName = s ''WORD Custom Addin''
                 val Description = s ''Word Custom Addin''
                 val LoadBehavior = d ''00000003''
                 val CommandLineSafe = d ''00000001''
                 }
               }
             }
          }
       }
   }
}
</pre>以上代码由三个需要注意的地方：<br />1. Office下面的那个子项代表了这个插件是属于那个组件，Word、Excel、Outlook等等。<br />2. Addins下面的那个子项要写成你添加的COM组件的名字，千万不要照着我的工程的名字照抄。<br />3. 所有的值两边加的都是单引号，而且要用英文下的单引号，不能用双引号。<br />这样一个Office插件的框架才算完成，你可以在OnConnection函数中加一些测试代码，看看有没有执行到，如果执行成功才能继续，否则检查上面的步骤有没有错误。 
<p>第四步，同时需要import两个office的文件，一个是MSO.dll，另一个是MSWORD.OLB。这两个文件可以在以下位置找到(具体位置与office安装路径有关):<br />C:\Program Files\Common Files\Microsoft Shared\OFFICE11<br />C:\Program Files\Microsoft Office\OFFICE11<br />然后在stdafx.h中加入如下语句： </p><pre>#import "C:\\Program Files\\Common Files\\Microsoft Shared\\OFFICE11\\mso.dll" 
        \
        rename_namespace("Office") named_guids,exclude("Pages")
using namespace Office;

#import "C:\\Program Files\\Common Files\\Microsoft Shared\\VBA\\VBA6\\VBE6EXT.olb" rename_namespace("VBE6")
using namespace VBE6;

#import "C:\\Program Files\\Microsoft Office\\OFFICE11\\MSWORD.OLB" rename("ExitWindows","ExitWindowsEx")
#import "C:\\Program Files\\Microsoft Office\\OFFICE11\\MSWORD.OLB" 
        \
        rename_namespace("Word"), raw_interfaces_only, named_guids ,exclude("Pages")
using namespace Word;</pre>加完以上代码以后一定要编译一下，看看是否能够成功。引入这两个文件的原因，主要是为了引入一些变量类型，为后面的创建UI作准备。<br />最后一步，编写代码。在OnConnection加入如下代码：<br /><pre>      CComPtr &lt; Office::_CommandBars&gt; spCmdBars; 
      CComQIPtr &lt;Word::_Application&gt; spApp(Application); 
      ATLASSERT(spApp);
      HRESULT hr = spApp-&gt;get_CommandBars(&amp;spCmdBars);
      if(FAILED(hr))
      return hr;
      ATLASSERT(spCmdBars);
      CComVariant vName("MyAddin");
      CComPtr &lt;Office::CommandBar&gt; spNewCmdBar;
      CComVariant vPos(1); 
      CComVariant vTemp(VARIANT_TRUE); 
      CComVariant vEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR); 
      spNewCmdBar = spCmdBars-&gt;Add(vName, vPos, vEmpty, vTemp);
       
      CComPtr &lt; Office::CommandBarControls&gt; spBarControls;
      spBarControls = spNewCmdBar-&gt;GetControls();
      ATLASSERT(spBarControls);
       
      CComVariant vToolBarType(1);
      CComVariant vShow(VARIANT_TRUE);
      CComPtr &lt; Office::CommandBarControl&gt; spNewBar; 
      spNewBar = spBarControls-&gt;Add(vToolBarType, vEmpty, vEmpty, vEmpty, vShow); 
      ATLASSERT(spNewBar);
        
      CComQIPtr &lt; Office::_CommandBarButton&gt; spCmdButton(spNewBar);
      ATLASSERT(spCmdButton);
        
      HBITMAP hBmp =(HBITMAP)::LoadImage(_Module.GetResourceInstance(),
      MAKEINTRESOURCE(IDB_BITMAP),IMAGE_BITMAP,0,0,LR_LOADMAP3DCOLORS);
        
      ::OpenClipboard(NULL);
      ::EmptyClipboard();
      ::SetClipboardData(CF_BITMAP, (HANDLE)hBmp);
      ::CloseClipboard();
      ::DeleteObject(hBmp); 
        
      spCmdButton-&gt;PutStyle(Office::msoButtonIconAndCaption);
      hr = spCmdButton-&gt;PasteFace();
      if (FAILED(hr))
      return hr;
        
      spCmdButton-&gt;PutVisible(VARIANT_TRUE); 
      spCmdButton-&gt;PutCaption(OLESTR("myAddin")); 
      spCmdButton-&gt;PutEnabled(VARIANT_TRUE);
      spCmdButton-&gt;PutTooltipText(OLESTR("test1")); 
      spCmdButton-&gt;PutTag(OLESTR("test1")); 
      spNewCmdBar-&gt;PutVisible(VARIANT_TRUE); 
        
      m_spCmdButton = spCmdButton;</pre><p>这样，再次打开word，就可以看到如图一所示的界面效果了。</p><p><img id="chkImg1" height="127" src="mhtml:file://C:\Documents and Settings\Administrator\桌面\C语言帝国 用VC6_0编写Word插件(Office2K、XP、03).mht!http://www.vckbase.com/document/journal/vckbase50/images/addin09.jpg" width="218" border="0" name="chkImg2" /></p><p><strong>图9</strong></p><p>但是点击时没有响应，最后就让我们来解决这个问题。<br />1. 在COutlookAddin继承类中加入IDispEventSimpleImpl继承，代码如下: </p><pre>class ATL_NO_VTABLE COutlookAddin : 
        public CComObjectRootEx&lt;CComSingleThreadModel&gt;,
        ……
        public IDispEventSimpleImpl&lt;1,COutlookAddin,&amp;__uuidof(Office::_CommandBarButtonEvents)&gt;
        </pre>2. 声明_ATL_SINK_INFO结构回调参数信息。在OutlookAddin.h文件中加入下面语句： <pre>// 按钮事件响应信息声明
extern _ATL_FUNC_INFO OnClickButtonInfo;</pre>在OutlookAddin.cpp文件中加入定义语句，如下： <pre>// 按钮事件响应信息定义
_ATL_FUNC_INFO OnClickButtonInfo ={CC_STDCALL,VT_EMPTY,2,{VT_DISPATCH,VT_BYREF 
        | VT_BOOL}};</pre>3. 加入Sink映射，如下： <pre>EGIN_SINK_MAP(COutlookAddin)
      SINK_ENTRY_INFO(1, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 
      0x01, OnClickButton1, &amp;OnClickButtonInfo)
      SINK_ENTRY_INFO(2, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 
      0x01, OnClickButton2, &amp;OnClickButtonInfo)
      SINK_ENTRY_INFO(3, __uuidof(Office::_CommandBarButtonEvents),/*dispid*/ 
      0x01, OnClickMenu, &amp;OnClickButtonInfo)
      END_SINK_MAP()</pre><p>4. 加入事件函数。在OutlookAddin.h中加入声明： </p><pre>void __stdcall OnClickButton1(IDispatch * /*Office::_CommandBarButton**/ 
Ctrl,VARIANT_BOOL * CancelDefault);</pre>在OutlookAddin.cpp中加入实现： <br /><pre>// 工具条按钮1点击事件响应函数<br />
void __stdcall CWordAddin::OnClickButton1(IDispatch * 
	/*Office::_CommandBarButton**/ Ctrl,VARIANT_BOOL * CancelDefault)
{
		MessageBox(NULL, "hello", "world", MB_OK);
}</pre><br />5. 最后，打开或断开与接口的连接。方法如下<br />在OnConnection接口函数的最后部分，加入下面代码来打开连接： 
<ul><li>在OnConnection接口函数的最后部分，加入下面代码来打开连接： <pre>CommandButton1Events::DispEventAdvise((IDispatch*)m_spButton);</pre></li><li>在OnDisconnection接口函数中，加入下面代码来断开连接： <pre>CommandButton1Events::DispEventUnadvise((IDispatch*)m_spButton);</pre></li></ul><p>综上所述，编写一个简单的office的插件，其实并不难，只要按照步骤一步一步进行，肯定能成功，如果大家在使用过程中有什么疑问，欢迎一起探讨。</p><img src ="http://www.cppblog.com/Lee/aggbug/79391.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee/" target="_blank">David Lee</a> 2009-04-09 22:53 <a href="http://www.cppblog.com/Lee/archive/2009/04/09/79391.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Word手写签名插件(COM加载项、VC6.0ATL)开发思路（转）</title><link>http://www.cppblog.com/Lee/archive/2009/04/09/79389.html</link><dc:creator>David Lee</dc:creator><author>David Lee</author><pubDate>Thu, 09 Apr 2009 14:52:00 GMT</pubDate><guid>http://www.cppblog.com/Lee/archive/2009/04/09/79389.html</guid><wfw:comment>http://www.cppblog.com/Lee/comments/79389.html</wfw:comment><comments>http://www.cppblog.com/Lee/archive/2009/04/09/79389.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee/comments/commentRss/79389.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee/services/trackbacks/79389.html</trackback:ping><description><![CDATA[
		<div class="wr f14">开发思路：</div>
		<div class="wr f14">　　写这个东东，其实就是写一个COM加载项。可以使用MFC、也可以使用ATL，也可以使用VB，我最终选用了ATL。主要是VC我用得比较多，而ATL通过模板库会给开发带来极大的便利，参考资料也比较多，因此选用了ATL。事实证明我的选择是正确的。不过使用VB相对要方便一些，VB可以很方便地对COM进行编程，编程中也可以直接使用Word的宏代码，根本不用做代码转换。</div>
		<div class="wr f14">　　开始编程，使用VC向导，可以很快的生成COM的框架，然后向工程里插入一个simple object（在菜单插入－＞插入ATL对象里面）。通过这个对象来改变WORD的菜单、TOOLBAR，这方面的文章很多，我的开发就是介绍了徐景周的一篇文章，到网上找一下，很多转载（我发现网上原创的东西实在不多呀）。这样一个简单的COM加载项的框架就建好了。</div>
		<div class="wr f14">　　手写签名部分的实现，这部分都是一些相对编程者容易的问题。简单说一下，首选插入一个对话框（在菜单插入－＞插入ATL对象里面），加入几个按钮，写一个单向链表用来存签名的笔画，用兼容DC、兼容位图、OleCreatePictureIndirect，把图片创建成一个IPictureDisp对象，以供下面的使用。</div>
		<div class="wr f14">　　再插入一个Full Control对象，方法同上。把上面一步生成的IPictureDisp写进Full Control对象，再调用WORD的AddOleCtrol方法将这个东东插入就可以了。</div>
		<div class="wr f14">　　这就是一个简单的流程。说的很粗略，因为不知道感兴趣的人多不多。</div>
		<div class="wr f14">　　在开发的过程中我遇到了以下这样一些问题，后来慢慢解决了，如果大家有兴趣可以来交流一下。</div>
		<div class="wr f14">　　1.如何在插入对象中取到WORD的ActiveDocument的指针（这个不能通过保存的方法来）。</div>
		<div class="wr f14">　　　　取Container的指针，再查IDispatch的接口。 </div>
		<div class="wr f14">      2.如果在程序里控制控件的删除，如在控件内点击，通过上下文菜单文菜单删除控件。</div>
		<div class="wr f14">　　　　可以给控件设置一下标志，然后通过Word的方法遍历对象组，检查对应的标志，然后删除。</div>
		<div class="wr f14">      3.如何保存。</div>
		<div class="wr f14">　　　可以重载框架的Save和Load方法，把对象的相关属性保存。这两个方法会由WORD自动调用。</div>
		<div class="wr f14">      4.如何使用TOOLTIP。</div>
		<div class="wr f14">　　　　这个在MSDN里有详细的帮助，可以参照解决。</div>
		<div class="wr f14">      5.如何移动控件。</div>
		<div class="wr f14">　　　　处理控件的OnLButtonDown/OnMouseMove/OnLButtonUp消息，然后通过Word的方法移动控件。</div>
		<div class="wr f14">
		</div>
		<div class="wr f14">     简单写了一下思路，欢迎交流。</div>
<img src ="http://www.cppblog.com/Lee/aggbug/79389.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee/" target="_blank">David Lee</a> 2009-04-09 22:52 <a href="http://www.cppblog.com/Lee/archive/2009/04/09/79389.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>