⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch21.htm

📁 VC使用大全。里面集合了VC使用的各种使用技巧。非常有用。
💻 HTM
📖 第 1 页 / 共 5 页
字号:
<pre><font color="#008000">     public IOleObjectImpl&lt;CDieRoll&gt;,</font></pre>
<pre><font color="#008000">     
public IOleInPlaceActiveObjectImpl&lt;CDieRoll&gt;,</font></pre>
<pre><font color="#008000">     public IViewObjectExImpl&lt;CDieRoll&gt;,</font></pre>
<pre><font color="#008000">     public IOleInPlaceObjectWindowlessImpl&lt;CDieRoll&gt;,</font></pre>

<pre><font color="#008000">     public IDataObjectImpl&lt;CDieRoll&gt;,</font></pre>
<pre><font color="#008000">     public ISupportErrorInfo,</font></pre>
<pre><font color="#008000">     public IConnectionPointContainerImpl&lt;CDieRoll&gt;,</font></pre>

<pre><font color="#008000">     public ISpecifyPropertyPagesImpl&lt;CDieRoll&gt;</font></pre>
<P>Now you can see where the T in ATL comes in: all these classes are template classes. (If you aren't familiar with templates, read <A HREF="index26.htm" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/index26.htm" 
target="text">Chapter 26</A>,&quot;Exceptions, Templates, and the Latest Additions to C++.&quot;) You add support for an interface to a control by adding another entry to this list of interface classes from which it inherits. </P>
<blockquote><p><img 
src="note.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/note.gif">
<P>Notice the names follow the pattern <font color="#008000">IxxxImpl</font>: that means that this class implements the <font color="#008000">Ixxx</font> interface. Classes inheriting from <font color="#008000">IxxxImpl</font> inherit code 
as well as function names. For example, <font color="#008000">CDieRoll</font> inherits from <font color="#008000">ISupportErrorInfo</font>, not <font color="#008000">ISupportErrorInfoImpl&lt;CDieRoll&gt;</font>, even though such a template does exist. That 
is because the code in that template implementation class is not appropriate for an ATL control, so the control only inherits the names of the functions from the original interface, and provides code for them in the source file as you will shortly see.</P>

<p><img src="bottom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/bottom.gif"></blockquote>
<P>Futher down the header file you will find the COM map, shown in Listing 21.2.</P>
<P><I>Listing 21.2&#151;excerpt from DieRollControl.h&#151;COM Map</I></P>
<pre><font 
color="#008000">BEGIN_COM_MAP(CDieRoll)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY(IDieRoll)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY(IDispatch)</font></pre>
<pre><font color="#008000">     
COM_INTERFACE_ENTRY_IMPL(IViewObjectEx)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject2, IViewObjectEx)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL_IID(IID_IViewObject, 
IViewObjectEx)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceObjectWindowless)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleInPlaceObject, IOleInPlaceObjectWindowless)</font></pre>

<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL_IID(IID_IOleWindow, IOleInPlaceObjectWindowless)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL(IOleInPlaceActiveObject)</font></pre>
<pre><font color="#008000">     
COM_INTERFACE_ENTRY_IMPL(IOleControl)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL(IOleObject)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL(IQuickActivate)</font></pre>
<pre><font color="#008000">     
COM_INTERFACE_ENTRY_IMPL(IPersistStorage)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL(IPersistStreamInit)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL(ISpecifyPropertyPages)</font></pre>
<pre><font 
color="#008000">     COM_INTERFACE_ENTRY_IMPL(IDataObject)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY(IProvideClassInfo)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY(IProvideClassInfo2)</font></pre>
<pre><font 
color="#008000">     COM_INTERFACE_ENTRY(ISupportErrorInfo)</font></pre>
<pre><font color="#008000">     COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)</font></pre>
<pre><font color="#008000">END_COM_MAP()</font></pre>
<P>This COM map is the 
connection between <font color="#008000">IUnknown::QueryInterface()</font> and all the interfaces supported by the control. All COM objects must implement <font color="#008000">IUnknown</font>, and <font color="#008000">QueryInterface()</font> can be used 
to determine what other interfaces the control supports and obtain a pointer to them. The macros connect the <font color="#008000">Ixxx</font> interfaces to the <font color="#008000">IxxxImpl</font> classes from which <font color="#008000">CDieRoll</font> 
inherits.</P>
<P>Looking back at the inheritance list for CDieRoll, most of the templates take only one parameter, the name of this class, and came from AppWizard. This entry came from ObjectWizard:</P>
<pre><font color="#008000">     public 
CStockPropImpl&lt;CDieRoll, IDieRoll, &amp;IID_IDieRoll, </font></pre>
<pre><font color="#008000">         [ccc]&amp;LIBID_DIEROLLCONTROLLib&gt;,</font></pre>
<P>This line is how ObjectWizard arranged for support for stock properties. Notice there is no 
indication which properties are supported. Further down the header file, two member variables have been added to CDieRoll:</P>
<pre><font color="#008000">    OLE_COLOR m_clrBackColor;</font></pre>
<pre><font color="#008000">    OLE_COLOR m_clrForeColor; 
</font></pre>
<P>The ObjectWizard also updated DieRollControl.idl, the interface definition file, to show these two stock properties, as shown in Listing 21.3.</P>
<P><I>Listing 21.3&#151;Excerpt From DieRollControl.idl&#151;Stock Properties</I></P>

<pre><font color="#008000">    [</font></pre>
<pre><font color="#008000">        object,</font></pre>
<pre><font color="#008000">        uuid(2DE15F32-8A71-11D0-9B10-0080C81A397C),</font></pre>
<pre><font color="#008000">        dual,</font></pre>

<pre><font color="#008000">        helpstring(&quot;IDieRoll Interface&quot;),</font></pre>
<pre><font color="#008000">        pointer_default(unique)</font></pre>
<pre><font color="#008000">    ]</font></pre>
<pre><font color="#008000">    interface 
IDieRoll : IDispatch</font></pre>
<pre><font color="#008000">    {</font></pre>
<pre><font color="#008000">    [propput, id(DISPID_BACKCOLOR)]</font></pre>
<pre><font color="#008000">        HRESULT BackColor([in]OLE_COLOR clr);</font></pre>
<pre><font 
color="#008000">    [propget, id(DISPID_BACKCOLOR)]</font></pre>
<pre><font color="#008000">        HRESULT BackColor([out,retval]OLE_COLOR* pclr);</font></pre>
<pre><font color="#008000">    [propput, id(DISPID_FORECOLOR)]</font></pre>
<pre><font 
color="#008000">        HRESULT ForeColor([in]OLE_COLOR clr);</font></pre>
<pre><font color="#008000">    [propget, id(DISPID_FORECOLOR)]</font></pre>
<pre><font color="#008000">        HRESULT ForeColor([out,retval]OLE_COLOR* pclr);</font></pre>

<pre><font color="#008000">    };</font></pre>
<P>This class will provide all the support for the <font color="#008000">get</font> and <font color="#008000">put</font> funtions and will notify the container when one of these properties changes. </P>

<P><B>Adding the ReadyState Stock Property</B></P>
<P>Although ReadyState was not on the stock property list in the ATL Object Wizard, it is supported by <font color="#008000">CStockPropImpl</font>. You can add another stock property by editing the header 
and idl files. In the header file, immediately after the lines that declared <font color="#008000">m_clrBackColor</font> and <font color="#008000">m_clrForeColor</font>, declare another member variable:</P>
<pre><font color="#008000">.</font></pre>

<pre><font color="#008000">         long m_nReadyState;</font></pre>
<P>This property will be used in the same way as the <font color="#008000">ReadyState</font> property in the MFC version of Dieroll: to implement <font color="#008000">Image</font> as an 
asynchronous property. In DieRollControl.idl, add these lines to the IDispatch block, after the lines for BackColor and ForeColor:</P>
<pre><font color="#008000">    [propget, id(DISPID_READYSTATE)]</font></pre>
<pre><font color="#008000">    HRESULT 
ReadyState([out,retval]long* pclr);</font></pre>
<P>You don't need to add a pair of lines to implement <font color="#008000">put</font> for this property, since external objects cannot update <font color="#008000">ReadyState</font>. Save the header and idl 
files to update ClassView&#151;if you do not, you will not be able to add more properties with ClassView. Expand <font color="#008000">CDieRoll</font> and <font color="#008000">IDieRoll</font> in ClassView to see that the member variable has been added to 
<font color="#008000">CDieRoll</font> and a <font color="#008000">ReadyState()</font> function has been added to <font color="#008000">IDieRoll</font>.</P>
<P><B> Adding Custom Properties</B></P>
<P>To add custom properties, you will use an ATL tool 
similar to the MFC ClassWizard. Right-click on <font color="#008000">IDieRoll</font> (the top-level one, not the one under <font color="#008000">CDieRoll</font>) in ClassView to bring up the shortcut menu shown in Figure 21.9, and choose Add 
<U>P</U>roperty.</P>
<A HREF="KKfig09.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch21/KKfig09.gif"><b>Fig. 21.9</b></A>
<P><I>ATL projects have a different ClassView shortcut menu than MFC projects.</I></P>
<P>The Add Property to Interface dialog box, shown in Figure 21.10, appears. Choose <font 
color="#008000">short</font> for the type and fill in <font color="#008000">Number</font> for the name. Deselect Put Function since containers will not need to change the number showing on the die. Leave the rest of the settings unchanged and click OK to 
add the property.</P>
<A HREF="KKfig10.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/figs/ch21/KKfig10.gif"><b>Fig. 21.10</b></A>
<P><I>Add </I><I><font color="#008000">Number</font></I><I> as a Read-Only Property.</I></P>
<P>Repeat this process for the <font color="#008000">BOOL</font> <font 
color="#008000">Dots</font>, which should have both <font color="#008000">get</font> and <font color="#008000">put</font> functions. (Leave the put radio button at PropPut.) The ClassView now shows entries under both CDieRoll and IDieRoll related to these 
new properties, as shown in Figure 21.11. Try double-clicking on the new entries. For example, double-clicking on <font color="#008000">get_Dots()</font> under the <font color="#008000">IDieRoll</font> that is under <font color="#008000">CDieRoll</font> 
opens the source (cpp) file scrolled to the <font color="#008000">get_Dots()</font> function. Double-clicking on <font color="#008000">Dots()</font> under the top-level <font color="#008000">IDieRoll</font> opens the idl file scrolled to the <font 
color="#008000">propget</font> entry for <font color="#008000">Dots</font>.</P>

<P>Although a number of entries have been added to CDieRoll, no member variables have been added. Only you can add the member variables that correspond to the new properties. 
While in many cases it's safe to assume that the new properties are simply member variables of the control class, they might not be. For example, Number might have been the dimension of some array kept within the class rather than a variable of its 
own..</P>
<P>Add to the header file, after the declarations of <font color="#008000">m_clrBackColor</font>, <font color="#008000">m_clrForeColor</font>, and <font color="#008000">m_nReadyState</font>:</P>
<pre><font color="#008000">     short 
m_sNumber;</font></pre>
<pre><font color="#008000">     BOOL m_bDots;</font></pre>
<P>In the idl file, the new propget and propput entries use hard coded dispids of 1 and 2, like this:</P>
<pre><font color="#008000">[propget, id(1), 
helpstring(&quot;property Number&quot;)] </font></pre>
<pre><font color="#008000">    HRESULT Number([out, retval] short *pVal);</font></pre>
<pre><font color="#008000">[propget, id(2), helpstring(&quot;property Dots&quot;)] </font></pre>
<pre><font 
color="#008000">    HRESULT Dots([out, retval] BOOL *pVal);</font></pre>
<pre><font color="#008000">[propput, id(2), helpstring(&quot;property Dots&quot;)] </font></pre>
<pre><font color="#008000">    HRESULT Dots([in] BOOL newVal); </font></pre>
<P>To 
make the code more readable, use an <font color="#008000">enum of dispids</font>. Adding the declaration of the enum to the idl file will make it usable in both the idl and header file. Add these lines to the beginning of DieRollControl.idl:</P>
<pre><font 
color="#008000">     typedef enum propertydispids</font></pre>
<pre><font color="#008000">          {</font></pre>
<pre><font color="#008000">               dispidNumber = 1,</font></pre>
<pre><font color="#008000">          dispidDots = 2,</font></pre>

<pre><font color="#008000">          }PROPERTYDISPIDS;</font></pre>
<P>Now you can change the propget and propput lines:</P>
<pre><font color="#008000">[propget, id(</font><B><font color="#008000">dispidNumber</font></B><font color="#008000">), 
helpstring(&quot;property Number&quot;)] </font></pre>
<pre><font color="#008000">    HRESULT Number([out, retval] short *pVal);</font></pre>
<pre><font color="#008000">[propget, id(</font><B><font color="#008000">dispidDots</font></B><font 
color="#008000">), helpstring(&quot;property Dots&quot;)] </font></pre>
<pre><font color="#008000">    HRESULT Dots([out, retval] BOOL *pVal);</font></pre>
<pre><font color="#008000">[propput, id(</font><B><font color="#008000">dispidDots</font></B><font 
color="#008000">), helpstring(&quot;property Dots&quot;)] </font></pre>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -