﻿<?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>博客园-Clingingboy</title><link>http://www.cnblogs.com/Clingingboy/</link><description>&amp;lt;developer name=’'clingingboy"&amp;gt;&amp;lt;i:Interaction.Behaviors&amp;gt;&amp;lt;clingingboy:madeControlBehavior /&amp;gt;&amp;lt;/i:Interaction.Behaviors&amp;gt;&amp;lt;/developer&amp;gt;</description><language>zh-cn</language><lastBuildDate>Mon, 06 Jul 2009 02:03:15 GMT</lastBuildDate><pubDate>Mon, 06 Jul 2009 02:03:15 GMT</pubDate><ttl>60</ttl><item><title>com学习笔记(4)动态链接</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517365.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Sun, 05 Jul 2009 15:13:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517365.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1517365.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517365.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1517365.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1517365.html</trackback:ping><description><![CDATA[<p>先发贴，后更新，防止自己偷懒</p><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1517365.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>com学习笔记(3)基本的com接口-引用计数的实现</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517362.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Sun, 05 Jul 2009 15:12:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517362.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1517362.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517362.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1517362.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1517362.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp; clr内存是托管的，但c++不是.我们用完组件还得回收。那么就有一个问题。我们需要知道使用中的组件可以释放了吗？必须想一种机制在适当的时候来释放资源，于是就有了引用计数的概念.IUnknown还有其他两个成员，我们没有讲过</p> <p>即AddRef和Release方法.用这两个方法可以有效的管理组件的生命周期。</p> <p><strong>AddRef则计数加1</strong></p> <p><strong>Release则计数减1,若等于0则释放资源</strong></p><pre class="code"><span style="color: blue">interface </span>IUnknown
{
    <span style="color: blue">virtual </span>HRESULT <span style="color: blue">__stdcall </span>QueryInterface(<span style="color: blue">const </span>IID&amp; iid, <span style="color: blue">void</span>** ppv) =0;            
    <span style="color: blue">virtual </span>ULONG <span style="color: blue">__stdcall </span>AddRef() =0 ;
    <span style="color: blue">virtual </span>ULONG <span style="color: blue">__stdcall </span>Release() =0 ;
};</pre>
<p>&nbsp;</p>
<h2>一.引用计数三大规则</h2>
<p>&nbsp;</p>
<p>1.在返回接口指针时调用AddRef.</p><pre class="code">IUnknown* CreateInstance()
{
    IUnknown* pI = <span style="color: blue">static_cast</span>&lt;IX*&gt;(<span style="color: blue">new </span>CA) ;
    pI-&gt;AddRef() ;
    <span style="color: blue">return </span>pI ;
}</pre><a href="http://11011.net/software/vspaste"></a><br>
<p>2.在使用完接口时调用Release.用户很懒，总是想让系统自己释放资源,但只有用户自己才知道什么时候不需要使用了.还得用户自己来调</p>
<p><strong>记得接口用完后调用Release</strong></p>
<p>如下代码</p><pre class="code"><span style="color: blue">int </span>main()
{
    HRESULT hr ;

    trace(<span style="color: #a31515">"Client: Get an IUnknown pointer."</span>) ;
    IUnknown* pIUnknown = CreateInstance() ;


    trace(<span style="color: #a31515">"Client: Get interface IX."</span>) ;

    IX* pIX = NULL ; 
    hr = pIUnknown-&gt;QueryInterface(IID_IX, (<span style="color: blue">void</span>**)&amp;pIX) ;

    <span style="color: blue">if </span>(SUCCEEDED(hr))
    {
        trace(<span style="color: #a31515">"Client: Succeeded getting IX."</span>) ;
        pIX-&gt;Fx() ;          <span style="color: green">// Use interface IX.
        </span>pIX-&gt;Release() ;
    }


    trace(<span style="color: #a31515">"Client: Get interface IY."</span>) ;

    IY* pIY = NULL ;
    hr = pIUnknown-&gt;QueryInterface(IID_IY, (<span style="color: blue">void</span>**)&amp;pIY) ;
    <span style="color: blue">if </span>(SUCCEEDED(hr))
    {
        trace(<span style="color: #a31515">"Client: Succeeded getting IY."</span>) ;
        pIY-&gt;Fy() ;          <span style="color: green">// Use interface IY.
        </span>pIY-&gt;Release() ;
    }


    trace(<span style="color: #a31515">"Client: Ask for an unsupported interface."</span>) ;

    IZ* pIZ = NULL ;
    hr = pIUnknown-&gt;QueryInterface(IID_IZ, (<span style="color: blue">void</span>**)&amp;pIZ) ;
    <span style="color: blue">if </span>(SUCCEEDED(hr))
    {
        trace(<span style="color: #a31515">"Client: Succeeded in getting interface IZ."</span>) ;
        pIZ-&gt;Fz() ;
        pIZ-&gt;Release() ;
    }
    <span style="color: blue">else
    </span>{
        trace(<span style="color: #a31515">"Client: Could not get interface IZ."</span>) ;
    }


    trace(<span style="color: #a31515">"Client: Release IUnknown interface."</span>) ;
    pIUnknown-&gt;Release() ;

    <span style="color: blue">return </span>0;
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>&nbsp;</p>
<p>3.在赋值后调用AddRef.</p><pre class="code">pIX-&gt;Fx() ;          <span style="color: green">// Use interface IX.
</span><strong>IX* pIX2=pIX;
pIX2-&gt;AddRef();</strong>
pIX2-&gt;Fx();
pIX2-&gt;Release() ;
pIX-&gt;Release() ;</pre>
<p>&nbsp;</p>
<h2>二.引用计数接口单一维护</h2>
<p>&nbsp;</p>
<p>上面我们可以看到,每个引用计数接口都是单一维护,很麻烦.</p>
<p>为何不在同一个组件统一维护呢?解释是为了方便后续调试和资源的释放.等接口多了就很难管理,万一是全局设计,就很难找出是哪个接口的问题了.(我感觉这完全是设计问题,但确实是个问题)</p>
<h2>三.引用计数的实现</h2>
<p>&nbsp;</p>
<p>返回值供调试使用，其他地方意义不大。</p><pre class="code">ULONG <span style="color: blue">__stdcall </span>CA::AddRef()
{
    cout &lt;&lt; <span style="color: #a31515">"CA:     AddRef = " </span>&lt;&lt; m_cRef+1 &lt;&lt; <span style="color: #a31515">'.' </span>&lt;&lt; endl ;
    <span style="color: blue">return </span>InterlockedIncrement(&amp;m_cRef) ;
}

ULONG <span style="color: blue">__stdcall </span>CA::Release() 
{
    cout &lt;&lt; <span style="color: #a31515">"CA:     Release = " </span>&lt;&lt; m_cRef-1 &lt;&lt; <span style="color: #a31515">'.' </span>&lt;&lt; endl ;

    <span style="color: blue">if </span>(InterlockedDecrement(&amp;m_cRef) == 0)
    {
        <span style="color: blue">delete this </span>;
        <span style="color: blue">return </span>0 ;
    }
    <span style="color: blue">return </span>m_cRef ;
}</pre>
<p>&nbsp;</p>
<p>到此为止,用户的使用从直接用<span style="color: blue">delete</span>关键字变成用Release释放资源.</p>
<h2>四.何时进行引用计数</h2>
<p>&nbsp;</p>
<p>1.若生命周期包含，可以省却引用计数</p><pre class="code">pIX-&gt;Fx() ;          <span style="color: green">// Use interface IX.
</span>IX* pIX2=pIX;
<strong><strike>pIX2-&gt;AddRef();</strike></strong>
pIX2-&gt;Fx();
<strike>pIX2-&gt;Release() ;</strike>
pIX-&gt;Release() ;</pre>
<p>&nbsp;</p>
<p>2.生命周期不包含则无法省却</p>
<p>顺序换一下就大不一样了.</p><pre class="code">IX* pIX2=pIX;
 pIX-&gt;Fx() ;
 pIX2-&gt;AddRef();
 pIX-&gt;Release() ;
 pIX2-&gt;Fx();
 pIX2-&gt;Release() ;</pre>
<p>&nbsp;</p>
<h2>五.引用计数规则</h2>
<p>&nbsp;</p>
<p>下次继续</p><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1517362.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>com学习笔记(2)基本的com接口-QueryInterface的实现</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517222.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Sun, 05 Jul 2009 08:56:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517222.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1517222.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517222.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1517222.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1517222.html</trackback:ping><description><![CDATA[<p>QueryInterface&nbsp;&nbsp; <a href="http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517121.html">接上篇</a></p> <p>&nbsp;</p> <h2>一.COM接口的开始IUnknown</h2> <p>&nbsp;</p> <p>com起于接口，又归于接口.</p> <p>com之所以是com,是因为其继承了一个名为<strong>IUnknown接口</strong>.</p> <p>IUnknown接口是一个非常有趣的名字.我们第一次看到这个接口,都会非常好奇,名字的由来开发内部肯定是有故事的,或者他们想不出啥好名字也是有可能的.</p> <p>下面我们来看一下IUnknown接口定义了哪些成员,这篇只讲<strong>QueryInterface</strong></p><pre class="code"><span style="color: blue">interface </span>IUnknown
{
    <span style="color: blue">virtual </span>HRESULT <span style="color: blue">__stdcall </span>QueryInterface(<span style="color: blue">const </span>IID&amp; iid, <span style="color: blue">void</span>** ppv) =0;            
<strike>    <span style="color: blue">virtual </span>ULONG <span style="color: blue">__stdcall </span>AddRef() =0 ;
    <span style="color: blue">virtual </span>ULONG <span style="color: blue">__stdcall </span>Release() =0 ;</strike>
};</pre>
<p>&nbsp;</p>
<h2>二.QueryInterface的实现与使用</h2>
<p>&nbsp;</p>
<p><strong>1.作用</strong></p>
<p>看命名就可以猜这个方法是用来查询组件是否支持某个特定接口。若支持泽返回指向此接口的指针。</p>
<p><strong>2.参数</strong></p>
<p>QueryInterface方法有两个参数,</p>
<p>第一个为接口标识符,简称IID,全名(Interface Identifier),现在可以只理解为一个常量</p>
<p>第二个参数即为返回的接口指针</p>
<p><strong>3.使用方法</strong> </p>
<p>我们先来看示例代码</p>
<p>定义一个继承自IUnknown接口的IX</p><pre class="code"><span style="color: blue">interface </span>IX : IUnknown
{
    <span style="color: blue">virtual void __stdcall </span>Fx() = 0 ;
} ;</pre>
<p>&nbsp;</p>
<p>若CA实现了该IX接口,则使用如下</p><pre class="code"><span style="color: blue">static const </span>IID IID_IX = 
    {0x32bb8320, 0xb41b, 0x11cf,
    {0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;

<span style="color: blue">void </span>foo(IUnknown* pI)
{
    IX* pIX=NULL;
    HRESULT hr=pI-&gt;QueryInterface(IID_IX,(<span style="color: blue">void</span>**)&amp;pIX);

    <span style="color: blue">if</span>(SUCCEEDED(hr)
    {
       pIX-&gt;Fx();
    }
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>&nbsp;</p>
<p><strong>3.1 HRESULT</strong></p>
<p>HRESULT是一个查询结果状态集合，并非true或false可以表示的，所以用SUCCEEDED方法来判断查询结果是否成功，失败的话，接口指针为NULL.</p>
<p><strong>4.QueryInterface的实现</strong></p>
<p>CA继承了IX，由于IX继承了IUnknown接口，所以CA也必须实现IUnknown接口成员,我们重新来看一下QueryInterface方法的参数</p>
<p><span style="color: blue">virtual </span>HRESULT <span style="color: blue">__stdcall </span>QueryInterface(<span style="color: blue">const </span>IID&amp; iid, <span style="color: blue">void</span>** ppv) =0; </p>
<p>该方法会根据传输不同iid,而返回相对应的接口指针,为了演示，我们再定义一个接口IY,CA实现IX和IY，</p>
<p>如下实现</p><pre class="code">HRESULT <span style="color: blue">__stdcall </span>CA::QueryInterface(<span style="color: blue">const </span>IID&amp; iid, <span style="color: blue">void</span>** ppv)
{     
    <span style="color: blue">if </span>(iid == IID_IUnknown)
    {
        *ppv = <span style="color: blue">static_cast</span>&lt;IX*&gt;(<span style="color: blue">this</span>) ;
    }
    <span style="color: blue">else if </span>(iid == IID_IX)
    {
        *ppv = <span style="color: blue">static_cast</span>&lt;IX*&gt;(<span style="color: blue">this</span>) ;
    }
    <span style="color: blue">else if </span>(iid == IID_IY)
    {
        *ppv = <span style="color: blue">static_cast</span>&lt;IY*&gt;(<span style="color: blue">this</span>) ;
    }
    <span style="color: blue">else
    </span>{         
        *ppv = NULL ;
        <span style="color: blue">return </span>E_NOINTERFACE;
    }
    <span style="color: blue">return </span>S_OK ;
}</pre>
<p>&nbsp;</p>
<p>是不是很简单？,获取到以后用<span style="color: blue">static_cast</span>来转换类型。IID_IUnknown,S_OK，E_NOINTERFACE等都是内置的状态码</p>
<p><strong>5.简单创建IUnknown</strong></p><pre class="code">IUnknown* CreateInstance()
{
    IUnknown* pI = <span style="color: blue">static_cast</span>&lt;IX*&gt;(<span style="color: blue">new </span>CA) ;
    pI-&gt;AddRef() ;
    <span style="color: blue">return </span>pI ;
}</pre>
<p><a href="http://11011.net/software/vspaste"></a>&nbsp;</p>
<p><strong>6.调用接口</strong></p><pre class="code"><span style="color: blue">int </span>main()
{
    HRESULT hr ;    
    IUnknown* pIUnknown = CreateInstance() ;
   
    IX* pIX = NULL ; 
    hr = pIUnknown-&gt;QueryInterface(IID_IX, (<span style="color: blue">void</span>**)&amp;pIX) ;
    <span style="color: blue">if </span>(SUCCEEDED(hr))
    {
        pIX-&gt;Fx() ;          <span style="color: green">// Use interface IX.
    </span>}

    IY* pIY = NULL ;
    hr = pIUnknown-&gt;QueryInterface(IID_IY, (<span style="color: blue">void</span>**)&amp;pIY) ;
    <span style="color: blue">if </span>(SUCCEEDED(hr))
    {
        pIY-&gt;Fy() ;          <span style="color: green">// Use interface IY.
    </span>}

    <span style="color: green">// Delete the component.
    </span><span style="color: blue">delete </span>pIUnknown ;
    <span style="color: blue">return </span>0 ;
}</pre><a href="http://11011.net/software/vspaste"></a>
<p>&nbsp;</p>
<h2>三.QueryInterface实现准则</h2>
<p><br><strong>1.QueryInterface返回的总是同一IUnknown指针</strong>,贴图了</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_thumb.png" width="542" height="287"></a> </p>
<p><strong>2.若用户曾获取过某个接口，那么它将总能获取此接口</strong></p>
<p><strong>3.用户可获取再次获取过的接口</strong></p>
<p><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_4.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_thumb_1.png" width="512" height="207"></a> </p>
<p><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_6.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_thumb_2.png" width="361" height="172"></a> </p>
<p><strong>4.用户可以返回到起始接口</strong></p>
<p><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_8.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_thumb_3.png" width="562" height="345"></a> </p>
<p>3和4都可以理解为接口之间的切换。</p>
<p>5.接口<strong>可获取-</strong><strong>获取到</strong>接口的接口</p>
<p>通过A接口得到B接口，B接口可以获取C接口，那么A接口可以直接获取C接口．</p>
<p><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_10.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_thumb_4.png" width="215" height="59"></a><br><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_12.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/com2ccom_D743/image_thumb_5.png" width="520" height="327"></a> </p>
<p>以上就如数学公式一般，犹如com编程的不变真理．</p><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1517222.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>com学习笔记(1)基础接口的定义</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517121.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Sun, 05 Jul 2009 04:08:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517121.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1517121.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/07/05/1517121.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1517121.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1517121.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 看com组件方面的东西大概也有3个多月了.看到com本质论的作者说6个月才对com有感觉,所以我深感欣慰哈…之前学习com完全是为了wpf,然后就一发不可收拾,知识体系发生非常大的变化.看的第一本书是潘爱民的 <strong>com原理与应用</strong>,此书是作者看了n多书总结的,像我等初学者看了这么多理论，非常之艰难,这书可不是什么武打小说,均是密密麻麻的理论...不过还是苦苦坚持看了2个月,后来发现com技术内幕和com本质论,先从com技术内幕开始就好多了。我们还是少一些理论,多一些代码,学起来就有乐趣多了.然后提出疑问.</p> <p>所以学习的资料则是</p> <ol> <li>com技术内幕  <li>com本质论  <li>com原理与应用</li></ol> <h2>一.c++接口的实现</h2> <p>&nbsp;</p> <p>c++没有接口概念，只有抽象类.<br></p> <h1>1.定义接口(纯抽象类)</h1> <p><br>如下,用<span style="color: blue">virtual</span>关键字表明该方法为抽象方法,未实现的方法后面+ <strong>=0</strong></p> <p><strong></strong>&nbsp;</p><pre class="code"><span style="color: blue">class </span>IX
{
<span style="color: blue">public</span>:
    <span style="color: blue">virtual void </span>Fx1() = 0 ;
    <span style="color: blue">virtual void </span>Fx2() = 0 ;
} ;</pre>
<h1>2.实现接口</h1>
<p>类可以多重继承,但为了简单,所以就用一个接口.</p><pre class="code"><span style="color: blue">class </span>CA : <span style="color: blue">public </span>IX{
<span style="color: blue">public</span>:
    <span style="color: green">// Implement interface IX.
    </span><span style="color: blue">virtual void </span>Fx1() {cout &lt;&lt; <span style="color: #a31515">"CA::Fx1" </span>&lt;&lt; endl ;}
    <span style="color: blue">virtual void </span>Fx2() {cout &lt;&lt; <span style="color: #a31515">"CA::Fx2" </span>&lt;&lt; endl ;}
}</pre>
<p>&nbsp;</p>
<p>到这里为止跟com一点关系都没有的.</p>
<h2>二.接口定义的简化(伪纯抽象类)<br></h2>
<p>由于c++并无<span style="color: blue">interface</span>关键字,为了编码约定,可以用<span style="color: blue">#define</span>关键字定义,将类改成接口.</p><pre class="code"><span style="color: blue">#define interface struct</span></pre>
<p>&nbsp;</p>
<p>现在我们可以重新定义IX,注意此处不用把方法标记为public,struct默认把成员公开.这样就<strong>简化</strong>了接口的定义</p>
<p>如下</p><pre class="code"><span style="color: blue">interface </span>IX
{
    <span style="color: blue">virtual void </span>Fx1() = 0 ;
    <span style="color: blue">virtual void </span>Fx2() = 0 ;
} ;</pre>
<p>&nbsp;</p>
<p>这样是不是很简单了?</p>
<h2>三.标准调用</h2>
<p>&nbsp;</p>
<p>由于c++编译器各不同,方法的调用方式各有不同,可先参考<a href="http://www.cnitblog.com/sonery/archive/2008/02/19/39925.html">这里</a>.</p>
<p><font color="#000000">微软平台的com接口<strong>大部分(即推荐用法,话不敢说死,所以无需纠缠)</strong>均采用<font color="#031cc2">__stdcall</font></font><font color="#000000">这种标准调用约定</font></p>
<p>现在为每个方法加上<font color="#031cc2">__stdcall</font>调用约定,如下代码</p><pre class="code"><span style="color: blue">interface </span>IX
{
    <span style="color: blue">virtual void __stdcall </span>Fx1() = 0 ;
    <span style="color: blue">virtual void __stdcall </span>Fx2() = 0 ;
} ;</pre>
<p>&nbsp;</p>
<p>当然具体实现的类,也需要改变,如下代码</p><pre class="code"><span style="color: blue">class </span>CA : <span style="color: blue">public </span>IX{
<span style="color: blue">public</span>:
<span style="color: green">    </span><span style="color: blue">virtual void __stdcall </span>Fx1() {cout &lt;&lt; <span style="color: #a31515">"CA::Fx1" </span>&lt;&lt; endl ;}
    <span style="color: blue">virtual void __stdcall </span>Fx2() {cout &lt;&lt; <span style="color: #a31515">"CA::Fx2" </span>&lt;&lt; endl ;}
}</pre>
<p>&nbsp;</p>
<h1>定义好接口和实现这些接口后，我们接下就是要使用这些接口</h1>
<p>&nbsp;</p>
<h2>四.调用接口</h2>
<p>&nbsp;</p><pre class="code"><span style="color: blue">int </span>main()
{
    CA* pA = <span style="color: blue">new </span>CA ;
    <span style="color: green">// Get an IX pointer.
    </span>IX* pIX = pA ;
    pIX-&gt;Fx1() ;
    pIX-&gt;Fx2() ;
    <span style="color: blue">delete </span>pA ;
    <span style="color: blue">return </span>0 ;
}</pre>
<p>&nbsp;</p>
<p>到目前为止,跟com组件根本搭不上边.我们且称这是一个组件(中间件,类库…)都可以.</p>
<h2>五<a href="http://baike.baidu.com/view/161302.htm?func=retitle">.虚拟函数表</a>vtbl(virtual function table)<br></h2>
<p>1.虽然com接口号称语言,无关性,为何我们还是选择c++作为编写的语言,而不是c#或者java?</p>
<p>2.c++抽象基类怎么说成是com接口?<br></p>
<p>我们先重新来看那段接口的代码.</p><pre class="code"><span style="color: blue">interface </span>IX
{
    <span style="color: blue">virtual void __stdcall </span>Fx1() = 0 ;
    <span style="color: blue">virtual void __stdcall </span>Fx2() = 0 ;
} ;</pre><a href="http://11011.net/software/vspaste"></a>
<p>&nbsp;</p>
<p>又是概念</p>
<p>当定义了一个抽象基类，也就定义了相应的内存结构，派生类实现了该抽象类才会被分配.</p>
<p>虚拟函数表包含一组指向虚拟函数实现的指针.</p>
<p>以上可以不管.下面的话才是重要的.</p>
<p>似乎是偶然的巧合,com接口的内存结构同c++编译器为抽象基类等所生成的内存结构是相同的。。。</p>
<p><strong>由于这个巧合,IX即是接口，又是抽象基类。</strong></p>
<p><strong>由于这个巧合，我们就选择了c++,就像阿里的招聘广告 If not you,who?</strong></p>
<h2>六.关于类,接口,组件的一些简单理论概念<br></h2>
<p><strong>1.类非组件</strong></p>
<p>组件这一称法太过专业,可以当作一个功能模块,按我的理解可以<strong>一个控件也是一个组件</strong>,如DataGrid是一个组件,DataGrid是由n多类组成一个功能强大的控件，所以类非组件. 话说话来,简单的组件也可以由一个类组成。概念而已,无需理会.不知道也不会怎么样…</p>
<p><strong>2.接口与类的继承关系</strong></p>
<p>一个类可以继承多个接口实现，也可以由一个接口一个类实现…</p>
<p><strong>3.多重接口继承</strong></p>
<p>即多个类继承相同接口(可以是多个接口)，不同实现…</p>
<p><strong>4.命名冲突</strong></p>
<p>怎么办?改名…要是遇到别人骚扰你，你改名，他也改名就没办法了...</p>
<p>&nbsp;</p>
<p>好了,先写到这里.这篇其实与com组件基本无关的.</p><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1517121.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47995/" target="_blank">Google Voice 上手</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>招聘.net开发工程师或前端开发工程师(地点:杭州)</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/07/02/1515384.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Thu, 02 Jul 2009 04:10:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/07/02/1515384.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1515384.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/07/02/1515384.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1515384.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1515384.html</trackback:ping><description><![CDATA[摘要: 如果你擅长.net平台下的web开发,并对web非常感兴趣。有意向的请联系我.或将简历发到下面邮箱.zxh_zj@hotmail.com  此职位可偏向前端或者后端,但必须有一个是擅长的。 1. 熟悉...&nbsp;&nbsp;<a href='http://www.cnblogs.com/Clingingboy/archive/2009/07/02/1515384.html'>阅读全文</a><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1515384.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47994/" target="_blank">Google号召社区力量为互联网加速</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>show部分书...</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/06/09/1499816.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Tue, 09 Jun 2009 09:08:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/06/09/1499816.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1499816.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/06/09/1499816.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1499816.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1499816.html</trackback:ping><description><![CDATA[<span  style="font-family: Simsun; font-size: 16px; line-height: normal; ">
<div style="font-family: verdana, 'courier new'; font-size: 14px; line-height: 150%; margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 3px; padding-right: 3px; padding-bottom: 3px; padding-left: 3px; cursor: pointer; ">
<p style="margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; ">&nbsp;</p>
<p style="margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; "><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/show_F0BB/20090609044_2.jpg"><img title="20090609044" border="0" alt="20090609044" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/show_F0BB/20090609044_thumb.jpg" width="244" height="184" style="border-bottom-width: 0px; border-bottom-style: initial; border-bottom-color: initial; border-left-width: 0px; border-left-style: initial; border-left-color: initial; display: inline; border-top-width: 0px; border-top-style: initial; border-top-color: initial; border-right-width: 0px; border-right-style: initial; border-right-color: initial; " /></a></p>
<p style="margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; "><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/show_F0BB/20090609045_2.jpg"><img title="20090609045" border="0" alt="20090609045" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/show_F0BB/20090609045_thumb.jpg" width="244" height="184" style="border-bottom-width: 0px; border-bottom-style: initial; border-bottom-color: initial; border-left-width: 0px; border-left-style: initial; border-left-color: initial; display: inline; border-top-width: 0px; border-top-style: initial; border-top-color: initial; border-right-width: 0px; border-right-style: initial; border-right-color: initial; " /></a></p>
<p style="margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; "><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/show_F0BB/20090609047_2.jpg"><img title="20090609047" border="0" alt="20090609047" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/show_F0BB/20090609047_thumb.jpg" width="244" height="184" style="border-bottom-width: 0px; border-bottom-style: initial; border-bottom-color: initial; border-left-width: 0px; border-left-style: initial; border-left-color: initial; display: inline; border-top-width: 0px; border-top-style: initial; border-top-color: initial; border-right-width: 0px; border-right-style: initial; border-right-color: initial; " /></a></p>
<p style="margin-top: 0px; margin-right: auto; margin-bottom: 10px; margin-left: auto; ">继续购入中</p>
</div>
</span><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1499816.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47989/" target="_blank">Twitter无处不在 魔兽世界Twitter发送器插件发布</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>wpf &amp;&amp; silverlight开发框架(prism)系列教程</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/06/01/prsim_tutorial.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Mon, 01 Jun 2009 04:00:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/06/01/prsim_tutorial.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1493591.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/06/01/prsim_tutorial.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1493591.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1493591.html</trackback:ping><description><![CDATA[<p>&nbsp;</p>
<div>
<p>&nbsp;&nbsp; &nbsp; 弄个列表,方便你我,不要问我prism是啥,只要你做wpf or silverlight你就会知道这个东西.</p>
<p><a id="AjaxHolder_ctl01_TitleUrl" href="/Clingingboy/archive/2009/01/06/prism_part1.html">Prism V2之旅(1)-prism基本概览</a></p>
<p>让你了解下,prism里面的一些基本概念</p>
<p><a id="AjaxHolder_ctl01_TitleUrl" href="/Clingingboy/archive/2009/01/07/prism_part2.html">Prism V2之旅(2)-region容器</a></p>
<p>了解region容器的使用方法</p>
<p><a id="ArchiveMonth1_Days_Entries_ctl07_TitleUrl" href="/Clingingboy/archive/2009/01/07/prism_part3.html">Prism V2之旅(3)-regionAdapter</a></p>
<p>region与view容器扩展</p>
<p><a id="ArchiveMonth1_Days_Entries_ctl06_TitleUrl" href="/Clingingboy/archive/2009/01/07/prism_part4.html">Prism V2之旅(4)-attachBehavior</a></p>
<p>region的行为插件扩展机制</p>
<p><a id="ArchiveMonth1_Days_Entries_ctl05_TitleUrl" href="/Clingingboy/archive/2009/01/13/prism_part5.html">Prism V2之旅(5)-Module</a></p>
<p>模块化功能介绍</p>
<p><a id="ArchiveMonth1_Days_Entries_ctl04_TitleUrl" href="/Clingingboy/archive/2009/01/13/prism_part6.html">Prism V2之旅(6)-EventAggregator</a></p>
<p>介绍模块之间的事件交互</p>
<p><a id="ArchiveMonth1_Days_Entries_ctl03_TitleUrl" href="/Clingingboy/archive/2009/01/15/prism_part7.html">prism v2之旅(7)-动态模块加载</a></p>
<p>该篇主要对silverlight技术的动态加载模块进行介绍</p>
<p><a id="ArchiveMonth1_Days_Entries_ctl01_TitleUrl" href="/Clingingboy/archive/2009/02/26/wpf_viewmodel.html">基于wpf的相关设计问题-ViewModel</a></p>
<p>mvvm很重要，一定得看</p>
<p><a id="ArchiveMonth1_Days_Entries_ctl00_TitleUrl" href="/Clingingboy/archive/2009/02/26/1398882.html">基于wpf的相关设计问题-Command的使用</a></p>
<p>command也很重要，也要看的...</p>
<p><a id="AjaxHolder_ctl01_TitleUrl" href="/Clingingboy/archive/2009/05/13/1456092.html">prism behavior图示</a></p>
<p>画的不好，多包含...</p>
<p><a id="ArchiveMonth1_Days_Entries_ctl00_TitleUrl" href="/Clingingboy/archive/2009/03/26/1422351.html">prism模块化问题总结(1)</a></p>
<p><a id="ArchiveMonth1_Days_Entries_ctl00_TitleUrl" href="/Clingingboy/archive/2009/04/09/1432242.html">prism模块化问题总结(2)</a></p>
<p>这两篇属于胡言乱语，是对于prism框架使用的思考</p>
<p>&nbsp;</p>
<p>未完，看情况补充.需要用的人可以看看.对于这个框架有什么问题的,也可以提出来</p>
</div>
<p>&nbsp;</p><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1493591.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47988/" target="_blank">Firefox 3.5匆忙推出漏洞多 Mozilla本月将更新</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>prism behavior图示</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/05/13/1456092.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Wed, 13 May 2009 09:12:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/05/13/1456092.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1456092.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/05/13/1456092.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1456092.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1456092.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp; 怕以后丢失,还是发一下,看起来可能会比较乱</p> <p><a href="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/prismbehavior_F1E5/%E7%BB%98%E5%9B%BE1_2.png"><img title="绘图1" style="border-right: 0px; border-top: 0px; display: inline; border-left: 0px; border-bottom: 0px" height="497" alt="绘图1" src="http://images.cnblogs.com/cnblogs_com/Clingingboy/WindowsLiveWriter/prismbehavior_F1E5/%E7%BB%98%E5%9B%BE1_thumb.png" width="667" border="0"></a></p><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1456092.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47987/" target="_blank">预测：Twitter最可能收购的十家公司</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>prism模块化问题总结(2)</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/04/09/1432242.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Thu, 09 Apr 2009 02:35:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/04/09/1432242.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1432242.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/04/09/1432242.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1432242.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1432242.html</trackback:ping><description><![CDATA[摘要: &nbsp;&nbsp;<a href='http://www.cnblogs.com/Clingingboy/archive/2009/04/09/1432242.html'>阅读全文</a><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1432242.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47986/" target="_blank">网易澄清:与暴雪合资公司仅提供技术支持</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item><item><title>wpf&amp;amp;&amp;amp; silverlight的Behavior</title><link>http://www.cnblogs.com/Clingingboy/archive/2009/04/09/1432193.html</link><dc:creator>Clingingboy</dc:creator><author>Clingingboy</author><pubDate>Thu, 09 Apr 2009 01:24:00 GMT</pubDate><guid>http://www.cnblogs.com/Clingingboy/archive/2009/04/09/1432193.html</guid><wfw:comment>http://www.cnblogs.com/Clingingboy/comments/1432193.html</wfw:comment><comments>http://www.cnblogs.com/Clingingboy/archive/2009/04/09/1432193.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Clingingboy/comments/commentRss/1432193.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Clingingboy/services/trackbacks/1432193.html</trackback:ping><description><![CDATA[<p>对于wpf的附加属性特性,我们可以扩展一些功能.现在微软征对wpf和silverlight发布了一个扩展包</p> <p><strong>Microsoft.Expression.Interactivity</strong>&nbsp; </p> <p>这个dll文件有wpf和silverlight的不同版本,功能相同.</p> <p>这个dll主要加了两个功能.</p> <p>&nbsp;</p> <p>1.一个Behavior集合扩展行为</p> <p>2.一个事件扩展行为</p> <p>&nbsp;</p> <p>第一个大家都看到过了，第二个没人介绍过.</p> <p>wpf有触发器的功能.通常用来改改控件属性，加加动画.</p> <p>如<b><a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://PresentationFramework:3.0.0.0:31bf3856ad364e35/System.Windows.DataTrigger">DataTrigger</a>和EventTrigger.</b></p> <p><strong>接着就是<b><a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://PresentationFramework:3.0.0.0:31bf3856ad364e35/System.Windows.TriggerAction">TriggerAction</a></b>触发了</strong></p> <p><strong>Setter就是其中之一.</strong></p> <p>可惜了<a href="http://www.aisto.com/roeder/dotnet/Default.aspx?Target=code://PresentationFramework:3.0.0.0:31bf3856ad364e35/System.Windows.TriggerAction">TriggerAction</a>抽象方法无法继承,导致无法扩展.微软为何不开放?我们可否用反射来调用抽象类的方法呢?</p> <p>这样就出现了事件扩展行为,这个行为比设置控件的属性灵活多了.</p> <p><br>不管怎么说，这个扩展包还是很有作用的.</p><img src ="http://www.cnblogs.com/Clingingboy/aggbug/1432193.html?type=1" width = "1" height = "1" /><br/><br/>--------------------------<br/>新闻：<a href="http://news.cnblogs.com/n/47986/" target="_blank">网易澄清:与暴雪合资公司仅提供技术支持</a><br/>网站导航: <a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻</a>&nbsp;&nbsp;<a href="http://dotnet.cnblogs.com" target="_blank">.NET频道</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/q/" target="_blank">博问</a>&nbsp;&nbsp;<a href="http://space.cnblogs.com/ing/" target="_blank">闪存</a>&nbsp;&nbsp;<a href="http://zzk.cnblogs.com" target="_blank">找找看</a>]]></description></item></channel></rss>