﻿<?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++博客-    Update 牌...@ Blog-随笔分类-ATL COM</title><link>http://www.cppblog.com/Lee7/category/8391.html</link><description>  当华美的叶片落尽，生命的脉络才历历可见。 －－ 聂鲁达    
</description><language>zh-cn</language><lastBuildDate>Tue, 07 Jul 2009 13:32:30 GMT</lastBuildDate><pubDate>Tue, 07 Jul 2009 13:32:30 GMT</pubDate><ttl>60</ttl><item><title>11</title><link>http://www.cppblog.com/Lee7/archive/2009/07/06/89400.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Mon, 06 Jul 2009 13:05:00 GMT</pubDate><guid>http://www.cppblog.com/Lee7/archive/2009/07/06/89400.html</guid><wfw:comment>http://www.cppblog.com/Lee7/comments/89400.html</wfw:comment><comments>http://www.cppblog.com/Lee7/archive/2009/07/06/89400.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee7/comments/commentRss/89400.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee7/services/trackbacks/89400.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">HRESULT&nbsp;CUnknownImpl::QueryInterface&nbsp;(&nbsp;REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppv&nbsp;)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hrRet&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;S_OK;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;标准QI()初始化&nbsp;&#8211;&nbsp;置&nbsp;*ppv&nbsp;为&nbsp;NULL.&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;如果客户端请求提供的接口，给&nbsp;*ppv.赋值&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;IsEqualIID&nbsp;(&nbsp;riid,&nbsp;IID_IUnknown&nbsp;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;不提供客户端请求的接口</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hrRet&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;E_NOINTERFACE;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;如果返回一个接口指针。&nbsp;调用AddRef()增加引用计数.&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;S_OK&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;hrRet&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv)</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">AddRef();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;hrRet;<br>}<br>在QI()中做了三件不同的事情：</span><span style="color: #000000;">1</span><span style="color: #000000;">、初始化传入的指针为NULL[</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;]。</span><span style="color: #000000;">2</span><span style="color: #000000;">、检查riid，确定组件对象类（coclass）实现了客户端所请求接口.[</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;IsEqualIID&nbsp;(&nbsp;riid,&nbsp;IID_IUnknown&nbsp;))]</span><span style="color: #000000;">3</span><span style="color: #000000;">、如果确实实现勒索请求的接口，则增加COM对象的引用计数。[((IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv)</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">AddRef();]AddRef()调用很关键。&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">;</span></div>
<br><br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;IClassFactory&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;IUnknown<br>{&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;CreateInstance(&nbsp;IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pUnkOuter,&nbsp;REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppvObject&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;LockServer(&nbsp;BOOL&nbsp;fLock&nbsp;);<br>};</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;ISimpleMsgBox&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;IUnknown<br>{&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;IUnknown&nbsp;方法&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;AddRef();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;Release();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;QueryInterface(&nbsp;REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppv&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;ISimpleMsgBox方法&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;DoSimpleMsgBox(&nbsp;HWND&nbsp;hwndParent,&nbsp;BSTR&nbsp;bsMessageText&nbsp;);<br>};<br></span><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;__declspec(uuid(</span><span style="color: #000000;">"</span><span style="color: #000000;">{7D51904D-1645-4a8c-BDE0-0F4A44FC38C4}</span><span style="color: #000000;">"</span><span style="color: #000000;">))&nbsp;ISimpleMsgBox;</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CSimpleMsgBoxImpl&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;ISimpleMsgBox&nbsp;&nbsp;<br>{<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;CSimpleMsgBoxImpl();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">CSimpleMsgBoxImpl();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;IUnknown&nbsp;方法&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;AddRef();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;Release();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;QueryInterface(&nbsp;REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppv&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;ISimpleMsgBox&nbsp;方法&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;DoSimpleMsgBox(&nbsp;HWND&nbsp;hwndParent,&nbsp;BSTR&nbsp;bsMessageText&nbsp;);<br></span><span style="color: #0000ff;">protected</span><span style="color: #000000;">:&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;m_uRefCount;<br>};<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;&nbsp;__declspec(uuid(</span><span style="color: #000000;">"</span><span style="color: #000000;">{7D51904E-1645-4a8c-BDE0-0F4A44FC38C4}</span><span style="color: #000000;">"</span><span style="color: #000000;">))&nbsp;CSimpleMsgBoxImpl;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">当某一客户端想要创建一个SimpleMsgBox&nbsp;COM对象时，它应该用下面这样的代码：</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;ISimpleMsgBox</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pIMsgBox;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hr;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;组件对象类的CLSID&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CoCreateInstance&nbsp;(&nbsp;__uuidof(CSimpleMsgBoxImpl),&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;非聚合&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLSCTX_INPROC_SERVER,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;进程内服务器&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__uuidof(ISimpleMsgBox),&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;所请求接口的IID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pIMsgBox&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;返回的接口指针的地址</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">class</span><span style="color: #000000;">&nbsp;CSimpleMsgBoxClassFactory&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;IClassFactory<br>{<br></span><span style="color: #0000ff;">public</span><span style="color: #000000;">:&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;CSimpleMsgBoxClassFactory();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">virtual</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">~</span><span style="color: #000000;">CSimpleMsgBoxClassFactory();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;IUnknown方法&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;AddRef();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;Release();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;QueryInterface(&nbsp;REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppv&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;IClassFactory方法</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;CreateInstance(&nbsp;IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pUnkOuter,&nbsp;REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppv&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;LockServer(&nbsp;BOOL&nbsp;fLock&nbsp;);</span><span style="color: #0000ff;">protected</span><span style="color: #000000;">:&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;ULONG&nbsp;m_uRefCount;<br>};<br></span><span style="color: #008000;">//</span><span style="color: #008000;">构造函数、析构函数和IUnknown方法都和前面例子中的一样，不同的只有IClassFactory的方法，LockServer()，看起来相当更简单：</span><span style="color: #008000;"><br></span><span style="color: #000000;">HRESULT&nbsp;CSimpleMsgBoxClassFactory::LockServer&nbsp;(&nbsp;BOOL&nbsp;fLock&nbsp;)<br>{&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;fLock&nbsp;</span><span style="color: #000000;">?</span><span style="color: #000000;">&nbsp;g_uDllLockCount</span><span style="color: #000000;">++</span><span style="color: #000000;">&nbsp;:&nbsp;g_uDllLockCount</span><span style="color: #000000;">--</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;S_OK;<br>}</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">HRESULT&nbsp;DllGetClassObject&nbsp;(&nbsp;REFCLSID&nbsp;rclsid,&nbsp;REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppv&nbsp;)<br>{&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;检查客户端所要的CSimpleMsgBoxImpl类工厂&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;</span><span style="color: #000000;">!</span><span style="color: #000000;">InlineIsEqualGUID&nbsp;(&nbsp;rclsid,&nbsp;__uuidof(CSimpleMsgBoxImpl)&nbsp;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;CLASS_E_CLASSNOTAVAILABLE;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">检查指针ppv是不是void*类型&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;IsBadWritePtr&nbsp;(&nbsp;ppv,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;E_POINTER;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;<br><br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CSimpleMsgBoxClassFactory</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pFactory;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;构造一个新的类工厂对象&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pFactory&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;CSimpleMsgBoxClassFactory;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pFactory&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;E_OUTOFMEMORY;</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;调用AddRef()增加一个类工厂引用计数，因为我们正在使用它</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pFactory</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">AddRef();<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hrRet;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;调用QI()查询客户端所要的类工厂接口&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;hrRet&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pFactory</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">QueryInterface&nbsp;(&nbsp;riid,&nbsp;ppv&nbsp;);&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;使用完类工厂后调用Release()释放它&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pFactory</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Release();&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;hrRet;<br>}</span></div>
<br></span></div>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">HRESULT&nbsp;CSimpleMsgBoxClassFactory::CreateInstance&nbsp;(&nbsp;IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pUnkOuter,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;REFIID&nbsp;&nbsp;&nbsp;&nbsp;riid,&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;ppv&nbsp;)<br>{&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;因为不支持聚合，所以这个参数pUnkOuter必须为NULL.&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;NULL&nbsp;</span><span style="color: #000000;">!=</span><span style="color: #000000;">&nbsp;pUnkOuter&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;CLASS_E_NOAGGREGATION;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">检查指针ppv是不是void*类型&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;IsBadWritePtr&nbsp;(&nbsp;ppv,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;E_POINTER;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;</span><span style="color: #008000;">//</span><span style="color: #008000;">检查完参数的有效性后，就可以创建一个新的对象了。</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CSimpleMsgBoxImpl</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pMsgbox;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;创建一个新的COM对象&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pMsgbox&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">new</span><span style="color: #000000;">&nbsp;CSimpleMsgBoxImpl;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;NULL&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;pMsgbox&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;E_OUTOFMEMORY;</span><span style="color: #008000;">//</span><span style="color: #008000;">最后，用QI()来查询客户端所请求的新对象的接口。如果QI()失败，则这个对象不可用，必须删除它。</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hrRet;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;用QI查询客户端所请求的对象接口&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;hrRet&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pMsgbox</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">QueryInterface&nbsp;(&nbsp;riid,&nbsp;ppv&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;如果QI失败，则删除这个COM对象，因为客户端不能使用它（客户端没有&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">这个对象的任何接口）&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;FAILED(hrRet)&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;delete&nbsp;pMsgbox;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;hrRet;<br>}</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">HRESULT&nbsp;CSimpleMsgBoxClassFactory::QueryInterface(&nbsp;REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppv&nbsp;)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hrRet&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;S_OK;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">检查指针ppv是不是void*类型&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;IsBadWritePtr&nbsp;(&nbsp;ppv,&nbsp;</span><span style="color: #0000ff;">sizeof</span><span style="color: #000000;">(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;E_POINTER;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">标准的QI初始化，将赋值为NULL.&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;NULL;</span><span style="color: #008000;">//</span><span style="color: #008000;">接下来检查riid，看看它是不是类工厂实现的接口之一：IUnknown&nbsp;或&nbsp;IclassFactory。&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;如果客户端请求一个有效接口，则扶植给&nbsp;*ppv.&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;InlineIsEqualGUID&nbsp;(&nbsp;riid,&nbsp;IID_IUnknown&nbsp;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;InlineIsEqualGUID&nbsp;(&nbsp;riid,&nbsp;IID_IClassFactory&nbsp;))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(IClassFactory</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #0000ff;">this</span><span style="color: #000000;">;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">else</span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;hrRet&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;E_NOINTERFACE;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}</span><span style="color: #008000;">//</span><span style="color: #008000;">最后，如果riid是有效接口，则调用接口的AddRef()，然后返回。&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">如果返回有效接口指针，则调用AddRef()&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;S_OK&nbsp;</span><span style="color: #000000;">==</span><span style="color: #000000;">&nbsp;hrRet&nbsp;)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((IUnknown</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">ppv)</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">AddRef();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;hrRet;<br>}<br></span></div>
<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #000000;">HRESULT&nbsp;CSimpleMsgBoxImpl::DoSimpleMsgBox&nbsp;(&nbsp;HWND&nbsp;hwndParent,&nbsp;BSTR&nbsp;bsMessageText&nbsp;)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;_bstr_t&nbsp;bsMsg&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;bsMessageText;<br>&nbsp;&nbsp;&nbsp;&nbsp;LPCTSTR&nbsp;szMsg&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;(TCHAR</span><span style="color: #000000;">*</span><span style="color: #000000;">)&nbsp;bsMsg;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;如果需要的话，用_bstr_t将串转换为ANSI&nbsp;做完转换的工作后，显示信息框，然后返回。&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;MessageBox&nbsp;(&nbsp;hwndParent,&nbsp;szMsg,&nbsp;_T(</span><span style="color: #000000;">"</span><span style="color: #000000;">Simple&nbsp;Message&nbsp;Box</span><span style="color: #000000;">"</span><span style="color: #000000;">),&nbsp;MB_OK&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;S_OK;<br>}</span></div>
<br><br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;DoMsgBoxTest(HWND&nbsp;hMainWnd)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;ISimpleMsgBox</span><span style="color: #000000;">*</span><span style="color: #000000;">&nbsp;pIMsgBox;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hr;<br>&nbsp;&nbsp;&nbsp;&nbsp;hr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;CoCreateInstance&nbsp;(&nbsp;__uuidof(CSimpleMsgBoxImpl),&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;组件对象类的CLSID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;NULL,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;非聚合&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;CLSCTX_INPROC_SERVER,&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;只使用进程内服务器&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;__uuidof(ISimpleMsgBox),&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;所请求接口的IID&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">)&nbsp;</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pIMsgBox&nbsp;);&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;容纳接口指针的缓冲&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">&nbsp;(&nbsp;FAILED(hr)&nbsp;)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">然后调用DoSimpleMsgBox()方法并释放接口。&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pIMsgBox</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">DoSimpleMsgBox&nbsp;(&nbsp;hMainWnd,&nbsp;_bstr_t(</span><span style="color: #000000;">"</span><span style="color: #000000;">Hello&nbsp;COM!</span><span style="color: #000000;">"</span><span style="color: #000000;">)&nbsp;);&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;pIMsgBox</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Release();<br>}</span></div>
<br>
<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="color: #0000ff;">struct</span><span style="color: #000000;">&nbsp;ISimpleMsgBox&nbsp;:&nbsp;</span><span style="color: #0000ff;">public</span><span style="color: #000000;">&nbsp;IUnknown<br>{&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;IUnknown&nbsp;方法&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;STDMETHOD_(ULONG,&nbsp;AddRef)()&nbsp;PURE;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;STDMETHOD_(ULONG,&nbsp;Release)()&nbsp;PURE;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;STDMETHOD(QueryInterface)(REFIID&nbsp;riid,&nbsp;</span><span style="color: #0000ff;">void</span><span style="color: #000000;">**</span><span style="color: #000000;">&nbsp;ppv)&nbsp;PURE;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">&nbsp;ISimpleMsgBox&nbsp;方法&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;STDMETHOD(DoSimpleMsgBox)(HWND&nbsp;hwndParent,&nbsp;BSTR&nbsp;bsMessageText)&nbsp;PURE;<br>};</span></div>
<br><img src ="http://www.cppblog.com/Lee7/aggbug/89400.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee7/" target="_blank">isabc</a> 2009-07-06 21:05 <a href="http://www.cppblog.com/Lee7/archive/2009/07/06/89400.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>利用VC++与MSXML解析XML文档</title><link>http://www.cppblog.com/Lee7/archive/2009/06/13/87599.html</link><dc:creator>isabc</dc:creator><author>isabc</author><pubDate>Sat, 13 Jun 2009 11:25:00 GMT</pubDate><guid>http://www.cppblog.com/Lee7/archive/2009/06/13/87599.html</guid><wfw:comment>http://www.cppblog.com/Lee7/comments/87599.html</wfw:comment><comments>http://www.cppblog.com/Lee7/archive/2009/06/13/87599.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/Lee7/comments/commentRss/87599.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/Lee7/services/trackbacks/87599.html</trackback:ping><description><![CDATA[<div style="border: 1px solid #cccccc; padding: 4px 5px 4px 4px; background-color: #eeeeee; font-size: 13px; width: 98%;"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><br>
<p class="p0" style="margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">利用<font face="Times New Roman">VC++</font><font face="宋体">与</font><font face="Times New Roman">MSXML</font><font face="宋体">解析</font><font face="Times New Roman">XML</font><font face="宋体">文档</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">一、</span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">文档对象模型（<font face="Times New Roman">DOM</font><font face="宋体">）</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">DOM</font><font face="宋体">是</font><font face="Times New Roman">Document&nbsp;Object&nbsp;Model</font><font face="宋体">（文档对象模型）的简称，是对</font><font face="Times New Roman">XML</font><font face="宋体">文档进行应用开发、编程的应用程序接口（</font><font face="Times New Roman">API</font><font face="宋体">）。作为</font><font face="Times New Roman">W3C</font><font face="宋体">公布的一种跨平台、与语言无关的接口规范，</font><font face="Times New Roman">DOM</font><font face="宋体">提供了在不同环境和应用中的标准程序接口，可以用任何语言实现。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">DOM</font><font face="宋体">采用对象模型和一系列的接口来描述</font><font face="Times New Roman">XML</font><font face="宋体">文档的内容和结构，即利用对象把文档模型化。这种对象模型实现的基本功能包括：</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">●&nbsp;</font><font face="宋体">描述文档表示和操作的接口；</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">●&nbsp;</font><font face="宋体">接口的属性和方法；</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">●&nbsp;</font><font face="宋体">接口之间的关系以及互操作。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">DOM</font><font face="宋体">可对结构化的</font><font face="Times New Roman">XML</font><font face="宋体">文档进行解析，文档中的指令、元素、实体、属性等所有内容个体都用对象模型表示，整个文档被看成是一个有结构的</font></span><span style="color: #ff0000; font-size: 9pt; font-family: 'Times New Roman';">信息树</span><span style="font-size: 9pt; font-family: 'Times New Roman';">，而不是简单的文本流，生成的对象模型就是树的节点，对象同时包含了</span><span style="color: #ff0000; font-size: 9pt; font-family: 'Times New Roman';">方法</span><span style="font-size: 9pt; font-family: 'Times New Roman';">和</span><span style="color: #ff0000; font-size: 9pt; font-family: 'Times New Roman';">属性</span><span style="font-size: 9pt; font-family: 'Times New Roman';">。因此，对文档的所有操作都是在</span><span style="color: #ff0000; font-size: 9pt; font-family: 'Times New Roman';">对象树</span><span style="font-size: 9pt; font-family: 'Times New Roman';">上的进行。在<font face="Times New Roman">DOM</font><font face="宋体">中，树中的一切都是对象，不管是根节点还是实体的属性。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　在<font face="Times New Roman">DOM</font><font face="宋体">中主要有以下三个对象：</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">●</font></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">&nbsp;XML<font face="宋体">文档对象</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">XML<font face="宋体">文档既是一种对象，同时又代表整个</font><font face="Times New Roman">XML</font><font face="宋体">文档。它由</font></span><span style="color: #ff0000; font-size: 9pt; font-family: 'Times New Roman';">根元素</span><span style="font-size: 9pt; font-family: 'Times New Roman';">和</span><span style="color: #ff0000; font-size: 9pt; font-family: 'Times New Roman';">子元素</span><span style="font-size: 9pt; font-family: 'Times New Roman';">组成。</span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">●</font></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">&nbsp;XML<font face="宋体">节点对象</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">XML<font face="宋体">节点对象代表的是</font><font face="Times New Roman">XML</font><font face="宋体">文档内部的节点，如元素、注释、名字空间等。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">●&nbsp;</font></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">XML<font face="宋体">节点列表</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">XML<font face="宋体">文档模块列表代表了节点的集合。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　利用<font face="Times New Roman">DOM</font><font face="宋体">，开发人员可以动态地创建</font><font face="Times New Roman">XML</font><font face="宋体">文档，</font></span><span style="color: #ff0000; font-size: 9pt; font-family: 'Times New Roman';">遍历</span><span style="font-size: 9pt; font-family: 'Times New Roman';">结构，</span><span style="color: #ff0000; font-size: 9pt; font-family: 'Times New Roman';">添加、修改、删除</span><span style="font-size: 9pt; font-family: 'Times New Roman';">内容等。其面向对象的特性，使人们在处理<font face="Times New Roman">XML</font><font face="宋体">解析相关的事务时节省大量的精力，是一种符合代码重用思想的强有力编程工具。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">二、<font face="Times New Roman">DOM</font><font face="宋体">的四个基本接口</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';">(<font face="宋体">引用自：</font></span><span><a href="http://bbs.xml.org.cn/dispbbs.asp?boardID=11&amp;ID=9220"><span style="color: #0000ff; text-decoration: underline; font-size: 9pt; font-family: 'Times New Roman';">http://bbs.xml.org.cn/dispbbs.asp?boardID=11&amp;ID=9220</span></a></span><span style="font-size: 9pt; font-family: 'Times New Roman';">)</span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">在<font face="Times New Roman">DOM</font><font face="宋体">接口规范中，有四个基本的接口</font></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">：<font face="Times New Roman">Document</font><font face="宋体">，</font><font face="Times New Roman">Node</font><font face="宋体">，</font><font face="Times New Roman">NodeList</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';">以及</span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">NamedNodeMap</span><span style="font-size: 9pt; font-family: 'Times New Roman';">。在这四个基本接口&nbsp;中，<font face="Times New Roman">Document</font><font face="宋体">接口是对文档进行操作的入口，它是从</font><font face="Times New Roman">Node</font><font face="宋体">接口继承过来的。</font><font face="Times New Roman">Node</font><font face="宋体">接口是其他大多数接口的父类，象&nbsp;</font><font face="Times New Roman">Documet</font><font face="宋体">，</font><font face="Times New Roman">Element</font><font face="宋体">，</font><font face="Times New Roman">Attribute</font><font face="宋体">，</font><font face="Times New Roman">Text</font><font face="宋体">，</font><font face="Times New Roman">Comment</font><font face="宋体">等接口都是从</font><font face="Times New Roman">Node</font><font face="宋体">接口继承过来的。</font><font face="Times New Roman">NodeList</font><font face="宋体">接口是一个节点的集合，它包含了某个节点中的所有子节点。</font><font face="Times New Roman">NamedNodeMap</font><font face="宋体">接口也是一个节点的集合，通过该接口，可以建立节点名和节点之间的一一映射关系，从而利&nbsp;用节点名可以直接访问特定的节点。下面将对这四个接口分别做一些简单的介绍。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">&nbsp;1<font face="宋体">、</font><font face="Times New Roman">Document</font><font face="宋体">接口</font></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">Document<font face="宋体">接口代表了整个</font><font face="Times New Roman">XML/HTML</font><font face="宋体">文档，因此，它是整棵文档树的根，提供了对文档中的数据进行访问和操作的入口。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">由于元素、文本节点、注释、处理指令等都不能脱离文档的上下文关系而独立存在，所以在<font face="Times New Roman">Document</font><font face="宋体">接口提供了创建其他节点对象的方法，通过该方法创建的节点对象都有一个</font><font face="Times New Roman">ownerDocument</font><font face="宋体">属性，用来表明当前节点是由谁所创建的以及节点同</font><font face="Times New Roman">Document</font><font face="宋体">之间的联系。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">在<font face="Times New Roman">DOM</font><font face="宋体">树中，</font><font face="Times New Roman">Document</font><font face="宋体">节点是</font><font face="Times New Roman">DOM</font><font face="宋体">树中的根节点，也即对</font><font face="Times New Roman">XML</font><font face="宋体">文档进行操作的入口节点。通过</font><font face="Times New Roman">Docuemt</font><font face="宋体">节点，可以访问到文档中的其他节点，&nbsp;如处理指令、注释、文档类型以及</font><font face="Times New Roman">XML</font><font face="宋体">文档的根元素节点等等。另外，在一棵</font><font face="Times New Roman">DOM</font><font face="宋体">树中，</font><font face="Times New Roman">Document</font><font face="宋体">节点可以包含多个处理指令、多个注释作为其子节&nbsp;点，而文档类型节点和</font><font face="Times New Roman">XML</font><font face="宋体">文档根元素节点都是唯一的。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">关于<font face="Times New Roman">Document</font><font face="宋体">接口的</font><font face="Times New Roman">IDL</font><font face="宋体">（</font><font face="Times New Roman">Interface&nbsp;Definition&nbsp;Language</font><font face="宋体">接口定义语言）定义和其中一些比较常用的属性和方法的详细介绍可以在</font><font face="Times New Roman">MSDN</font><font face="宋体">中找到。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;</span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">2<font face="宋体">、</font><font face="Times New Roman">Node</font><font face="宋体">接口</font></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">Node<font face="宋体">接口在整个</font><font face="Times New Roman">DOM</font><font face="宋体">树中具有举足轻重的地位，</font><font face="Times New Roman">DOM</font><font face="宋体">接口中有很大一部分接口是从</font><font face="Times New Roman">Node</font><font face="宋体">接口继承过来的，例如，</font><font face="Times New Roman">Element</font><font face="宋体">、</font><font face="Times New Roman">Attr</font><font face="宋体">、</font><font face="Times New Roman">CDATASection</font><font face="宋体">等接口，都是从</font><font face="Times New Roman">Node</font><font face="宋体">继承过来的。在</font><font face="Times New Roman">DOM</font><font face="宋体">树中，</font><font face="Times New Roman">Node</font><font face="宋体">接口代表了树中的一个节点。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">&nbsp;3<font face="宋体">、</font><font face="Times New Roman">NodeList</font><font face="宋体">接口</font></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">NodeList<font face="宋体">接口提供了对节点集合的抽象定义，它并不包含如何实现这个节点集的定义。</font><font face="Times New Roman">NodeList</font><font face="宋体">用于表示有顺序关系的一组节点，比如某个节点的子节点序列。另外，它还出现在一些方法的返回值中，例如</font><font face="Times New Roman">GetNodeByName</font><font face="宋体">。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">在<font face="Times New Roman">DOM</font><font face="宋体">中，</font><font face="Times New Roman">NodeList</font><font face="宋体">的对象是</font><font face="Times New Roman">"live"</font><font face="宋体">的，换句话说，对文档的改变，会直接反映到相关的</font><font face="Times New Roman">NodeList</font><font face="宋体">对象中。例如，如果通过</font><font face="Times New Roman">DOM</font><font face="宋体">获得一&nbsp;个</font><font face="Times New Roman">NodeList</font><font face="宋体">对象，该对象中包含了某个</font><font face="Times New Roman">Element</font><font face="宋体">节点的所有子节点的集合，那么，当再通过</font><font face="Times New Roman">DOM</font><font face="宋体">对</font><font face="Times New Roman">Element</font><font face="宋体">节点进行操作（添加、删除、改&nbsp;动节点中的子节点）时，这些改变将会自动地反映到</font><font face="Times New Roman">NodeList</font><font face="宋体">对象中，而不需</font><font face="Times New Roman">DOM</font><font face="宋体">应用程序再做其他额外的操作。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">NodeList<font face="宋体">中的每个</font><font face="Times New Roman">item</font><font face="宋体">都可以通过一个索引来访问，该索引值从</font><font face="Times New Roman">0</font><font face="宋体">开始。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">&nbsp;4<font face="宋体">、</font><font face="Times New Roman">NamedNodeMap</font><font face="宋体">接口</font></span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">实现了<font face="Times New Roman">NamedNodeMap</font><font face="宋体">接口的对象中包含了可以通过名字来访问的一组节点的集合。不过注意，</font><font face="Times New Roman">NamedNodeMap</font><font face="宋体">并不是从</font><font face="Times New Roman">NodeList</font><font face="宋体">继&nbsp;承过来的，它所包含的节点集中的节点是无序的。尽管这些节点也可以通过索引来进行访问，但这只是提供了枚举</font><font face="Times New Roman">NamedNodeMap</font><font face="宋体">中所包含节点的一种简&nbsp;单方法，并不表明在</font><font face="Times New Roman">DOM</font><font face="宋体">规范中为</font><font face="Times New Roman">NamedNodeMap</font><font face="宋体">中的节点规定了一种排列顺序。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;NamedNodeMap<font face="宋体">表示的是一组节点和其唯一名字的一一对应关系，这个接口主要用在属性节点的表示上。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="text-indent: 20.97pt; margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';">与<font face="Times New Roman">NodeList</font><font face="宋体">相同，在</font><font face="Times New Roman">DOM</font><font face="宋体">中，</font><font face="Times New Roman">NamedNodeMap</font><font face="宋体">对象也是</font><font face="Times New Roman">"live"</font><font face="宋体">的。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="margin-bottom: 0pt; margin-top: 0pt; text-align: justify; line-height: 10pt; vertical-align: baseline;"><span style="font-size: 9pt; font-family: 'Times New Roman';"><o:p></o:p></span></p>
<p class="p0" style="margin-bottom: 0pt; margin-top: 0pt;"><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">三、<font face="Times New Roman">MSXML</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;&nbsp;&nbsp;&nbsp;从理论上说，根据<font face="Times New Roman">XML</font><font face="宋体">的格式定义，我们可以自己编写一个</font><font face="Times New Roman">XML</font><font face="宋体">的语法分析器，但实际上微软已经给我们提供了一个</font><font face="Times New Roman">XML</font><font face="宋体">语法解析器，即一个叫做&nbsp;</font><font face="Times New Roman">MSXML.DLL</font><font face="宋体">的动态链接库，实际上它是一个</font><font face="Times New Roman">COM</font><font face="宋体">（</font><font face="Times New Roman">Component&nbsp;Object&nbsp;Model</font><font face="宋体">）对象库，里面封装了进行</font><font face="Times New Roman">XML</font><font face="宋体">解析时所需要的所有对象。因为</font><font face="Times New Roman">COM</font><font face="宋体">是一种以二进制格式出现的和语言无关的可重用对象，所以你可以用任何语言&nbsp;</font><font face="Times New Roman">(</font><font face="宋体">比如</font><font face="Times New Roman">VB</font><font face="宋体">，</font><font face="Times New Roman">VC</font><font face="宋体">，</font><font face="Times New Roman">DELPHI</font><font face="宋体">，</font><font face="Times New Roman">C++&nbsp;Builder</font><font face="宋体">甚至是脚本语言等等</font><font face="Times New Roman">)</font><font face="宋体">对它进行调用，在你的应用中实现对</font><font face="Times New Roman">XML</font><font face="宋体">文档的解析。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;　　<font face="Times New Roman">MSXML.DLL</font><font face="宋体">所包括的主要</font><font face="Times New Roman">COM</font><font face="宋体">接口有：</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;　</span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">　<font face="Times New Roman">1.&nbsp;IXMLDOMDocument(Document</font><font face="宋体">接口</font><font face="Times New Roman">)</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">DOMDocument<font face="宋体">对象是</font><font face="Times New Roman">XML&nbsp;DOM</font><font face="宋体">的基础，你可以利用它所暴露的属性和方法来浏览、查询和修改</font><font face="Times New Roman">XML</font><font face="宋体">文档的内容和结构。</font><font face="Times New Roman">DOMDocument</font><font face="宋体">表示了树的顶层节点，它实现了</font><font face="Times New Roman">DOM</font><font face="宋体">文&nbsp;档的所有的基本方法，并且提供了额外的成员函数来支持</font><font face="Times New Roman">XSL</font><font face="宋体">和</font><font face="Times New Roman">XSLT</font><font face="宋体">。它创建了一个文档对象，所有其他的对象都可以从这个文档对象中得到和创建。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;</span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">　　<font face="Times New Roman">2.&nbsp;IXMLDOMNode(Node</font><font face="宋体">接口</font><font face="Times New Roman">)</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;　　<font face="Times New Roman">IXMLDOMNode</font><font face="宋体">是文档对象模型</font><font face="Times New Roman">(DOM)</font><font face="宋体">中的基本对象，元素、属性、注释、过程指令和其他的文档组件都可以认为是</font><font face="Times New Roman">IXMLDOMNode</font><font face="宋体">。事实上，</font><font face="Times New Roman">DOMDocument</font><font face="宋体">对象本身也是一个</font><font face="Times New Roman">IXMLDOMNode</font><font face="宋体">对象。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;　</span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">　<font face="Times New Roman">3.&nbsp;IXMLDOMNodeList</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;　　<font face="Times New Roman">IXMLDOMNodeList</font><font face="宋体">实际上是一个节点</font><font face="Times New Roman">(Node)</font><font face="宋体">对象的集合，节点的增加、删除和变化都可以在集合中立刻反映出来，可以通过</font><font face="Times New Roman">"for.</font><font face="宋体">循环&nbsp;</font><font face="Times New Roman">"</font><font face="宋体">结构来遍历所有的节点。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;　　</span><span style="font-weight: bold; font-size: 9pt; font-family: 'Times New Roman';">4.&nbsp;IXMLDOMParseError</span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">&nbsp;　　<font face="Times New Roman">IXMLDOMParseError</font><font face="宋体">接口用来返回在解析过程中所出现的详细的信息，包括错误号、行号、字符位置和文本描述。</font></span><span style="font-size: 9pt; font-family: 'Times New Roman';"><br></span><span style="font-size: 9pt; font-family: 'Times New Roman';">　　在具体应用时可以用<font face="Times New Roman">DOMDocument</font><font face="宋体">的</font><font face="Times New Roman">Load</font><font face="宋体">方法来装载</font><font face="Times New Roman">XML</font><font face="宋体">文档，用</font><font face="Times New Roman">IXMLDOMNode&nbsp;</font><font face="宋体">的</font><font face="Times New Roman">selectNodes</font><font face="宋体">（查询的结果有多个，得到存放搜索结果的链表）或</font><font face="Times New Roman">selectSingleNode</font><font face="宋体">（查询的结果有一个，在有多个的情况下返回找&nbsp;到的第一个节点）方法进行查询，用</font><font face="Times New Roman">createNode</font><font face="宋体">和</font><font face="Times New Roman">appendChild</font><font face="宋体">方法来创建节点和追加节点，用</font><font face="Times New Roman">IXMLDOMElement</font><font face="宋体">的&nbsp;</font><font face="Times New Roman">setAttribute</font><font face="宋体">和</font><font face="Times New Roman">getAttribute</font><font face="宋体">方法来设置和获得节点的属性。</font></span></p>
<p class="p0" style="margin-bottom: 0pt; margin-top: 0pt; font-weight: bold;">四、编程举例</p>
<span style="color: #000000;">1</span><span style="color: #000000;">、目标文档：&nbsp;&nbsp;<br><br></span><span style="color: #000000;">&lt;</span><span style="color: #000000;">book&nbsp;id</span><span style="color: #000000;">=</span><span style="color: #000000;">"</span><span style="color: #000000;">bk101</span><span style="color: #000000;">"</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">author</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">lizlex</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">author</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">title</span><span style="color: #000000;">&gt;</span><span style="color: #000000;">XML&nbsp;Developer</span><span style="color: #000000;">'</span><span style="color: #000000;">s&nbsp;Guide&lt;/title&gt;</span><span style="color: #000000;"><br></span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">&lt;/</span><span style="color: #000000;">book</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br></span><span style="color: #000000;">2</span><span style="color: #000000;">、步骤：<br><br>(</span><span style="color: #000000;">1</span><span style="color: #000000;">)在StdAfx.h中引入动态链接库&nbsp;MSXML.DLL(C:\windows\system32\msxml4.dll)<br>&nbsp;#import&nbsp;</span><span style="color: #000000;">&lt;</span><span style="color: #000000;">msxml4.dll</span><span style="color: #000000;">&gt;</span><span style="color: #000000;"><br><br>(</span><span style="color: #000000;">2</span><span style="color: #000000;">)界面设计：<br>分别放入三个Text，用于输入数据，与显示文档内容用，并添加关联的成员变量m_strId,m_strAuthor,&nbsp;m_strTitle；并添加确定按钮：<br><br>(</span><span style="color: #000000;">3</span><span style="color: #000000;">)产生文档的程序片断<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;CXmlparseDlg::OnButtonGenerate()<br>&nbsp;{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UpdateData();<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSXML2::IXMLDOMDocumentPtr&nbsp;pDoc;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSXML2::IXMLDOMElementPtr&nbsp;&nbsp;xmlRoot&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">创建DOMDocument对象</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hr&nbsp;</span><span style="color: #000000;">=</span><span style="color: #000000;">&nbsp;pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(</span><span style="color: #000000;">!</span><span style="color: #000000;">SUCCEEDED(hr))<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox(</span><span style="color: #000000;">"</span><span style="color: #000000;">无法创建DOMDocument对象，请检查是否安装了MS&nbsp;XML&nbsp;Parser&nbsp;运行库!</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">根节点的名称为Book<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">创建元素并添加到文档中</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlRoot</span><span style="color: #000000;">=</span><span style="color: #000000;">pDoc</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">createElement((_bstr_t)</span><span style="color: #000000;">"</span><span style="color: #000000;">Book</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">设置属性</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlRoot</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">setAttribute(</span><span style="color: #000000;">"</span><span style="color: #000000;">id</span><span style="color: #000000;">"</span><span style="color: #000000;">,(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)m_strId);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDoc</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">appendChild(xmlRoot);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MSXML2::IXMLDOMElementPtr&nbsp;pNode;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">添加&#8220;author&#8221;元素</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">=</span><span style="color: #000000;">pDoc</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">createElement((_bstr_t)</span><span style="color: #000000;">"</span><span style="color: #000000;">Author</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Puttext((_bstr_t)(</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)m_strAuthor);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlRoot</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">appendChild(pNode);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">添加&#8220;Title&#8221;元素</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">=</span><span style="color: #000000;">pDoc</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">createElement(</span><span style="color: #000000;">"</span><span style="color: #000000;">Title</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">Puttext((</span><span style="color: #0000ff;">const</span><span style="color: #000000;">&nbsp;</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)m_strTitle);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;xmlRoot</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">appendChild(pNode);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">保存到文件<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">如果不存在就建立,存在就覆盖</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pDoc</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">save(</span><span style="color: #000000;">"</span><span style="color: #000000;">d:\\he.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;}<br><br>(</span><span style="color: #000000;">4</span><span style="color: #000000;">)读取XML文档的程序片断<br></span><span style="color: #0000ff;">void</span><span style="color: #000000;">&nbsp;CXmlparseDlg::OnButtonLoad()<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;MSXML2::IXMLDOMDocumentPtr&nbsp;pDoc;<br>&nbsp;&nbsp;&nbsp;&nbsp;HRESULT&nbsp;hr;<br>&nbsp;&nbsp;&nbsp;&nbsp;hr</span><span style="color: #000000;">=</span><span style="color: #000000;">pDoc.CreateInstance(__uuidof(MSXML2::DOMDocument40));<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">if</span><span style="color: #000000;">(FAILED(hr))<br>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;MessageBox(</span><span style="color: #000000;">"</span><span style="color: #000000;">无法创建DOMDocument对象，请检查是否安装了MS&nbsp;XML&nbsp;Parser&nbsp;运行库!</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">return</span><span style="color: #000000;">&nbsp;;<br>&nbsp;&nbsp;&nbsp;&nbsp;}<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">加载文件</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pDoc</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">load(</span><span style="color: #000000;">"</span><span style="color: #000000;">d:\\he.xml</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;MSXML2::IXMLDOMNodePtr&nbsp;&nbsp;pNode;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">在树中查找名为Book的节点,"</span><span style="color: #008000;">//</span><span style="color: #008000;">"表示在任意一层查找</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">=</span><span style="color: #000000;">pDoc</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">selectSingleNode(</span><span style="color: #000000;">"</span><span style="color: #000000;">//Book</span><span style="color: #000000;">"</span><span style="color: #000000;">);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;MSXML2::DOMNodeType&nbsp;nodeType;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">得到节点类型</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">get_nodeType(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">nodeType);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">节点名称</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;CString&nbsp;strName;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;strName</span><span style="color: #000000;">=</span><span style="color: #000000;">(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">GetnodeName();<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">节点属性,放在链表中</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;MSXML2::IXMLDOMNamedNodeMapPtr&nbsp;pAttrMap</span><span style="color: #000000;">=</span><span style="color: #000000;">NULL;<br>&nbsp;&nbsp;&nbsp;&nbsp;MSXML2::IXMLDOMNodePtr&nbsp;&nbsp;&nbsp;pAttrItem;<br>&nbsp;&nbsp;&nbsp;&nbsp;_variant_t&nbsp;variantValue;<br>&nbsp;&nbsp;&nbsp;&nbsp;pNode</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">get_attributes(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pAttrMap);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000ff;">long</span><span style="color: #000000;">&nbsp;count;<br>&nbsp;&nbsp;&nbsp;&nbsp;count</span><span style="color: #000000;">=</span><span style="color: #000000;">pAttrMap</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">get_length(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">count);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;pAttrMap</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">get_item(</span><span style="color: #000000;">0</span><span style="color: #000000;">,</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">pAttrItem);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000;">//</span><span style="color: #008000;">取得节点的值</span><span style="color: #008000;"><br></span><span style="color: #000000;">&nbsp;&nbsp;&nbsp;&nbsp;pAttrItem</span><span style="color: #000000;">-&gt;</span><span style="color: #000000;">get_nodeTypedValue(</span><span style="color: #000000;">&amp;</span><span style="color: #000000;">variantValue);<br>&nbsp;&nbsp;&nbsp;&nbsp;m_strId</span><span style="color: #000000;">=</span><span style="color: #000000;">(</span><span style="color: #0000ff;">char</span><span style="color: #000000;">&nbsp;</span><span style="color: #000000;">*</span><span style="color: #000000;">)(_bstr_t)variantValue;<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;UpdateData(FALSE);<br>&nbsp;&nbsp;&nbsp;&nbsp;<br>}</span></div>
<br>  <img src ="http://www.cppblog.com/Lee7/aggbug/87599.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/Lee7/" target="_blank">isabc</a> 2009-06-13 19:25 <a href="http://www.cppblog.com/Lee7/archive/2009/06/13/87599.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>