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

📄 ch14.htm

📁 VC使用所有细节的逻列
💻 HTM
📖 第 1 页 / 共 5 页
字号:

<pre><font color="#008000">     m_pSelection-&gt;Draw(pDC, m_pSelection-&gt;m_rect);</font></pre>

<P>Next, change <font color="#008000">CShowStringCntrItem::OnGetItemPosition()</font>, which needs to return this rectangle. Take away all the comments and the old hardcoded rectangle (leave the <font color="#008000">ASSERT_VALID</font> macro call), and 
add this line:</P>

<pre><font color="#008000">     rPosition = m_rect;</font></pre>

<P>The partner function</P>

<pre><font color="#008000">CShowStringCntrItem::OnChangeItemPosition()</font></pre>

<P>is called when the user moves the item. Here is where <font color="#008000">m_rect</font> is changed from the initial value. Remove the comments and add code immediately after the the call to the base class function, <font 
color="#008000">COleClientItem::OnChangeItemPosition()</font>. The code to add is:</P>

<pre><font color="#008000">      m_rect = rectPos;</font></pre>

<pre><font color="#008000">     GetDocument()-&gt;SetModifiedFlag();</font></pre>

<pre><font color="#008000">     GetDocument()-&gt;UpdateAllViews(NULL);</font></pre>

<P>Finally, the new member variable needs to be incorporated into <font color="#008000">CShowStringCntrItem::Serialize()</font>. Remove the comments and add lines in the storing and saving blocks so that the function looks like Listing 14.24.</P>

<P><I>Listing 14.24&#151;CntrItem.cpp&#151;</I>CShowStringCntrItem::Serialize()</P>

<pre><font color="#008000">void CShowStringCntrItem::Serialize(CArchive&amp; ar)</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">     ASSERT_VALID(this);</font></pre>

<pre><font color="#008000">     // Call base class first to read in COleClientItem data.</font></pre>

<pre><font color="#008000">     // Because this sets up the m_pDocument pointer returned from</font></pre>

<pre><font color="#008000">//  CShowStringCntrItem::GetDocument, it is a good idea to call</font></pre>

<pre><font color="#008000">     //  the base class Serialize first.</font></pre>

<pre><font color="#008000">     COleClientItem::Serialize(ar);</font></pre>

<pre><font color="#008000">     // now store/retrieve data specific to CShowStringCntrItem</font></pre>

<pre><font color="#008000">     if (ar.IsStoring())</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">          ar &lt;&lt; m_rect;</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><font color="#008000">     else</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">          ar &gt;&gt; m_rect;</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><font color="#008000">}</font></pre>

<P>Build and execute the application, insert a bitmap, and scribble something in it. Press Esc to cancel editing in place, and your scribble shows up in the top-right corner, next to <font color="#008000">Hello, world!</font>. Choose <U>E</U>dit, Bitmap 
Image <U>O</U>bject and then <U>E</U>dit. (Choosing <U>O</U>pen allows you to edit it in a different window.) Use the resizing handles that appear to drag the image over to the left, then press Esc to cancel editing in place. The image is drawn at the new 
position, as expected.</P>

<P>Now for the tracker rectangle. The Microsoft tutorials recommend writing a helper function, <font color="#008000">SetupTracker()</font>, to handle this. Add these lines to <font color="#008000">CShowStringView::OnDraw()</font>, just after the call to 
<font color="#008000">m_pSelection-&gt;Draw()</font>:</P>

<pre><font color="#008000">          CRectTracker trackrect;</font></pre>

<pre><font color="#008000">          SetupTracker(m_pSelection,&amp;trackrect);</font></pre>

<pre><font color="#008000">          trackrect.Draw(pDC);</font></pre>

<P>(The one-line statement after the <font color="#008000">if</font> was not in brace brackets before; don't forget to add them.)</P>

<P>Add the following public function to ShowStringView.h (inside the class definition):</P>

<pre><font color="#008000">     void SetupTracker(CShowStringCntrItem* item, </font></pre>

<pre><font color="#008000">     CRectTracker* track);</font></pre>

<P>Add the code in Listing 14.25 to ShowStringView.cpp immediately after the destructor.</P>

<P><I>Listing 14.25&#151;ShowStringView.cpp&#151;</I>CShowStringView::SetupTracker()</P>

<pre><font color="#008000">void CShowStringView::SetupTracker(CShowStringCntrItem* item, </font></pre>

<pre><font color="#008000">     CRectTracker* track)</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">     track-&gt;m_rect = item-&gt;m_rect;</font></pre>

<pre><font color="#008000">     if (item == m_pSelection)</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">          track-&gt;m_nStyle |= CRectTracker::resizeInside;</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><font color="#008000">     if (item-&gt;GetType() == OT_LINK)</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">          track-&gt;m_nStyle |= CRectTracker::dottedLine;</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><font color="#008000">     else</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">          track-&gt;m_nStyle |= CRectTracker::solidLine;</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><font color="#008000">     if (item-&gt;GetItemState() == COleClientItem::openState ||</font></pre>

<pre><font color="#008000">          item-&gt;GetItemState() == COleClientItem::activeUIState)</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">          track-&gt;m_nStyle |= CRectTracker::hatchInside;</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><font color="#008000">}</font></pre>

<P>This code first sets the tracker rectangle to the container item rectangle. Then it adds styles to the tracker. The styles available are as follows:</P>

<ul>

<li> <font color="#008000">solidLine</font>. Used for an embedded item.</P>

<li> <font color="#008000">dottedLine</font>. Used for a linked item.</P>

<li> <font color="#008000">hatchedBorder</font>. Used for an in-place active item.</P>

<li> <font color="#008000">resizeInside</font>. Used for a selected item.</P>

<li> <font color="#008000">resizeOutside</font>. Used for a selected item.</P>

<li> <font color="#008000">hatchInside</font>. Used for an item whose server is open.</P>

</ul>

<P>This code first compares the pointers to this item and the current selection. If they are the same, this item is selected and it gets resize handles. It's up to you whether these handles go on the inside or the outside. Then it asks the item whether it 
is linked (dotted line) or not (solid line.) Finally, it adds hatching to active items.</P>

<P>Build and execute the application, and try it out. You still cannot edit the contained item by double-clicking it: choose <U>E</U>dit from the cascading menu added at the bottom of the <U>E</U>dit menu. You can't move and resize an inactive object, but 
if you activate it, you can resize it while active. Also, when you press Esc, the inactive is drawn at its new position.</P>

<H3><A ID="I20" NAME="I20"><B>Handling Multiple Objects and Object Selection</B></A></H3>

<P>The next step is to catch mouse clicks and double clicks so that the item can be resized, moved, and activated more easily. This involves testing to see if a click is over a contained item or not.</P>

<P><A ID="I21" NAME="I21"><B> Hit Testing</B></A></P>

<P>You need to write a helper function that returns a pointer to the contained item that the user clicked, or <font color="#008000">NULL</font> if the user clicked an area of the view that has no contained item. This function runs through all the items 
contained in the document. Add the code in Listing 14.26 to ShowStringView.cpp immediately after the destructor.</P>

<P><I>Listing 14.26&#151;ShowStringView.cpp&#151;</I>CShowStringView::SetupTracker()</P>

<pre><font color="#008000">CShowStringCntrItem* CShowStringView::HitTest(CPoint point)</font></pre>

<pre><font color="#008000">{</font></pre>

<pre><font color="#008000">     CShowStringDoc* pDoc = GetDocument();</font></pre>

<pre><font color="#008000">     CShowStringCntrItem* pHitItem = NULL;</font></pre>

<pre><font color="#008000">     POSITION pos = pDoc-&gt;GetStartPosition();</font></pre>

<pre><font color="#008000">     while (pos)</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">          CShowStringCntrItem* pCurrentItem = </font></pre>

<pre><font color="#008000">               (CShowStringCntrItem*) pDoc-&gt;GetNextClientItem(pos);</font></pre>

<pre><font color="#008000">          if ( pCurrentItem-&gt;m_rect.PtInRect(point) )</font></pre>

<pre><font color="#008000">          {</font></pre>

<pre><font color="#008000">               pHitItem = pCurrentItem;</font></pre>

<pre><font color="#008000">          }</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><font color="#008000">     return pHitItem;</font></pre>

<pre><font color="#008000">}</font></pre>

<blockquote><p><img src="tip.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/tip.gif">

<P>Don't forget to add the declaration of this <font color="#008000">public</font> function to the header file.</P>

<p><img src="bottom.gif" tppabs="http://www.mcp.com/814147200/0-7897/0-7897-1145-1/bottom.gif"></blockquote>

<P>This function is given a <font color="#008000">CPoint</font> that describes the point on the screen where the user clicked. Each container item has a rectangle, <font color="#008000">m_rect</font>, as you've seen earlier, and the <font 
color="#008000">CRect</font> class has a member function called <font color="#008000">PtInRect()</font> that takes a <font color="#008000">CPoint</font> and returns <font color="#008000">TRUE</font> if the point is in the rectangle or <font 
color="#008000">FALSE</font> if it is not. This code simply loops through the items in this document, using the OLE document member function <font color="#008000">GetNextClientItem()</font>, and calls <font color="#008000">PtInRect()</font> for each.</P>

<P>What happens if there are several items in the container, and the user clicks at a point where two or more overlap? The one on top is selected. That's because <font color="#008000">GetStartPosition()</font> returns a pointer to the bottom item, and 
<font color="#008000">GetNextClientItem()</font> works its way up through the items. If two items cover the spot where the user clicked, <font color="#008000">pHitItem</font> is set to the lower one first, and then on a later iteration of the <font 
color="#008000">while</font> loop, it is set to the higher one. It is the pointer to the higher item that is returned.</P>

<P><A ID="I22" NAME="I22"><B> Drawing Multiple Items</B></A></P>

<P>While that code to loop through all the items is still fresh in your mind, why not fix <font color="#008000">CShowStringView::OnDraw()</font> so it draws all the items? Leave all the code that draws the string, and replace the code in Listing 14.27 
with with that in Listing 14.28.</P>

<P><I>Listing 14.27&#151;ShowStringView.cpp&#151;Iines in </I>OnDraw()<I> to Replace</I></P>

<pre><font color="#008000">     // Draw the selection at an arbitrary position.  This code should </font></pre>

<pre><font color="#008000">     // be removed once your real drawing code is implemented.  This </font></pre>

<pre><font color="#008000">     // position corresponds exactly to the rectangle returned by </font></pre>

<pre><font color="#008000">     // CShowStringCntrItem, to give the effect of in-place editing.</font></pre>

<pre><font color="#008000">     // TODO: remove this code when final draw code is complete.</font></pre>

<pre><font color="#008000">     if (m_pSelection == NULL)</font></pre>

<pre><font color="#008000">     {</font></pre>

<pre><font color="#008000">          POSITION pos = pDoc-&gt;GetStartPosition();</font></pre>

<pre><font color="#008000">          m_pSelection = (CShowStringCntrItem*)pDoc-&gt;GetNextClientItem(pos);</font></pre>

<pre><font color="#008000">     }</font></pre>

<pre><f

⌨️ 快捷键说明

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