FIX: SuperPad Resizes Indefinitely When Activated In-Place

ID: Q121948


The information in this article applies to:


SYMPTOMS

The in-place window resizes indefinitely if you insert a SuperPad object into an OLE 2.0 container application, and then either type characters into it or resize the in-place window.


CAUSE

The problem is caused by some incorrect code in the CEmbeddedItem::OnDraw and CPadView::OnSize functions. The primary problem occurs because the Windows edit control reports its border as part of its client area, so the call to pView->GetClientRect(&rectClient) in the CEmbededItem::OnDraw function is two pixels off, length and width wise.


RESOLUTION

Substitute the CPadView::OnSize and CEmbeddedItem::OnDraw functions located in the PADVIEW.CPP and PADITEM.CPP files respectively, with these functions:


void CPadView::OnSize(UINT nType, int cx, int cy)
{
   CWaitCursor wait;
   CEditView::OnSize(nType, cx, cy);
   CFrameWnd* pFrameWnd = GetParentFrame();
   ASSERT_VALID(pFrameWnd);
   if ((pFrameWnd->GetStyle() & WS_VISIBLE) &&
      pFrameWnd->IsKindOf(RUNTIME_CLASS(COleIPFrameWnd)))
   {
      // update the cx part of the extent to the width of the control
      CEmbeddedItem* pItem =
         (CEmbeddedItem*)GetDocument()->GetEmbeddedItem();
      // only update if it has actually changed
      if (pItem->m_sizeExtent.cx != cx)
      {
         pItem->m_sizeExtent.cx = cx;
         OnEditChange();  // will notify client later
      }
   }
}
BOOL CEmbeddedItem::OnDraw(CDC* pDC, CSize& rSize)
{
   // get view attached to the item
   CPadView* pView = GetView();

   // In some situations, OLE1 servers will ask for
   //  the presentation data during shutdown, even though it is not
   //  necessary (since the picture has not changed). This will
   //  happen when closing a frame window for example. By this time
   //  all the views are gone and there is no way to produce the
   //  metafile data, since the actual text is stored by the edit
   //  control (the view). In this case, we simply fail the call.
   if (pView == NULL)
      return FALSE;

   // edit controls have a border around them
   CRect rectClient;
   CRect margin;

   { // Calculate correct ClientRect
      pView->GetClientRect(&rectClient);
      rectClient.InflateRect(-1,-1);
      if (pView->GetStyle() & WS_HSCROLL)
         rectClient.bottom++;
      if (pView->GetStyle() & WS_VSCROLL)
         rectClient.right++;
   }
   { // Calculate margins
      CRect rectEdit;
      pView->GetEditCtrl().GetRect(&rectEdit);
      int HorzMargin = rectEdit.left - rectClient.left;
      int VertMargin = rectEdit.top - rectClient.top;
      margin.SetRect(HorzMargin,VertMargin,HorzMargin,VertMargin);
      if (pView->GetStyle() & WS_HSCROLL)
         margin.bottom++;
      if (pView->GetStyle() & WS_VSCROLL)
         margin.right++;
   }
   // get the font from the CEditView
   CFont* pFont = pView->GetFont();
   CFont* pOldFont = NULL;
   if (pFont != NULL)
      pOldFont = pDC->SelectObject(pFont);
   // get formatting rectangle
   CRect rect(rectClient);
   rect.left += margin.left;
   rect.top += margin.top;
   rect.right -= margin.right;
   rect.bottom = INT_MAX;
   pDC->SetBkMode(TRANSPARENT);

   // first just determine the correct extents of the text
   pDC->SaveDC();
   pDC->IntersectClipRect(0, 0, 0, 0);
                          // no drawing with NULL clipping
   if (pView->PrintInsideRect(pDC, rect, m_nBeg, m_nEnd) == 0)
   {
      TEXTMETRIC tm;
      pDC->GetTextMetrics(&tm);
      rect.bottom = rect.top + tm.tmHeight + tm.tmExternalLeading;
   }
   pDC->RestoreDC(-1);

   // then, really output the text
   pDC->SetWindowOrg(rect.left-margin.left,rect.top-margin.top);
   pDC->SetWindowExt(margin.left + rect.Width() + margin.right,
      margin.top + rect.Height() + margin.bottom);
   pView->PrintInsideRect(pDC, rect, m_nBeg, m_nEnd);

   // adjust for border (rect.left is already adjusted)
   rect.left -= margin.left;
   rect.top -= margin.top;
   rect.right += margin.right;
   rect.bottom += margin.bottom;

   // select previous font
   if (pOldFont != NULL)
      pDC->SelectObject(pOldFont);

   // return HIMETRIC size
   rSize = rect.Size();
   pDC->LPtoHIMETRIC(&rSize);
   return TRUE;
} 


STATUS

Microsoft has confirmed this to be a bug in the Microsoft products listed at the beginning of this article. This bug was corrected in Visual C++ version 1.51 for Windows.

NOTE: The problem does not occur in Visual C++ version 2.0.

Additional query words: 1.50 2.50


Keywords          : kbcode kbole kb16bitonly kbMFC kbVC 
Version           : 1.50
Platform          : WINDOWS 
Issue type        : 

Last Reviewed: July 22, 1999