FIX: SuperPad Resizes Indefinitely When Activated In-Place

Last reviewed: September 18, 1997
Article ID: Q121948
1.50 WINDOWS kbole kbprg kbbuglist kbfixlist kbcode

The information in this article applies to:

  • The Microsoft Foundation Classes (MFC), included with Microsoft Visual C++ for Windows, version 1.5

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 reference words: 1.50 2.50
KBCategory: kbole kbprg kbbuglist kbfixlist kbcode
KBSubcategory: MfcOLE
Keywords : kb16bitonly MfcOLE kbbuglist kbcode kbfixlist kbole kbprg
Technology : kbMfc
Version : 1.50
Platform : WINDOWS
Solution Type : kbfix


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 18, 1997
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.