To implement OLE in-place support in the view class, you must:
Before Scribble was enhanced to be an OLE in-place editing server, it was lazy about its device context coordinates using MM_LOENGLISH: Scribble did not adjust for how many logical pixels per inch were on the screen display. Most serious Windows applications scale their screen output because small fonts are rarely readable when displayed in their true (physical) size. Applications can adjust for the number of pixels in the logical inch by applying the kind of logic illustrated by the following code sample. This logic relies primarily on values returned by CDC::GetDeviceCaps(LOGPIXELSX) and GetDeviceCaps(LOGPIXELSY). Now that Scribble is an OLE server, it should scale according to logical pixels per inch. Otherwise, you (and your user) will notice a difference in the scaling of a Scribble drawing when the Scribble server is fully open versus its scaling when it is displayed embedded in the container.
To implement logical MM_LOENGLISH rather than physical MM_LOENGLISH
CScribbleView
is selected in the Class name and Object IDs boxes.OnPrepareDC
as follows:void CScribbleView::OnPrepareDC(CDC* pDC, CPrintInfo* pInfo)
{
CScribbleDoc* pDoc = GetDocument();
CScrollView::OnPrepareDC(pDC, pInfo);
pDC->SetMapMode(MM_ANISOTROPIC);
CSize sizeDoc = pDoc->GetDocSize();
sizeDoc.cy = -sizeDoc.cy;
pDC->SetWindowExt(sizeDoc);
CSize sizeNum, sizeDenom;
pDoc->GetZoomFactor(&sizeNum, &sizeDenom);
int xLogPixPerInch = pDC->GetDeviceCaps(LOGPIXELSX);
int yLogPixPerInch = pDC->GetDeviceCaps(LOGPIXELSY);
long xExt = (long)sizeDoc.cx * xLogPixPerInch * sizeNum.cx;
xExt /= 100 * (long)sizeDenom.cx;
long yExt = (long)sizeDoc.cy * yLogPixPerInch * sizeNum.cy;
yExt /= 100 * (long)sizeDenom.cy;
pDC->SetViewportExt((int)xExt, (int)-yExt);
}
In the following procedure, you’ll implement the ResyncScrollSizes
helper function mentioned previously.
To adjust the scroll view’s scroll bars to reflect the use of the logical MM_LOENGLISH mapping mode
CScribbleView
.void
.ResyncScrollSizes()
.Click OK.
CClientDC dc(NULL);
OnPrepareDC(&dc);
CSize sizeDoc = GetDocument()->GetDocSize();
dc.LPtoDP(&sizeDoc);
SetScrollSizes(MM_TEXT, sizeDoc);
CScribbleView::OnInitialUpdate
and replace the call to CScrollView::SetScrollSizes with the call to the helper function, ResyncScrollSizes
:void CScribbleView::OnInitialUpdate()
{
ResyncScrollSizes();
CScrollView::OnInitialUpdate();
}
In the next several steps you’ll use WizardBar to add a function that updates the scroll bars appropriately when the window is sized.
CScribbleView
The New Windows Message and Event Handlers dialog box appears.
ResyncScrollSizes
:ResyncScrollSizes(); // ensure that scroll info is up-to-date
CScribbleView
constructor and replace the comment with the following code:SetScrollSizes(MM_TEXT, CSize(0,0));
You must initialize the scroll sizes in the CScribbleView
constructor to default values, so that the extent is defined before the first call to OnPrepareDC
.
When Scribble’s view finishes adding a new stroke in CScribbleView::OnLButtonDown
, it calls the document’s UpdateAllViews
to inform other views that they need to invalidate a portion of the client area occupied by the new stroke. This notification is fine for Scribble when it is running stand-alone, but it is not adequate when Scribble is fully opened and editing an embedded object. In the latter case, Scribble needs to inform the container that the object has changed. This requires an additional call to COleServerDoc::NotifyChanged.
To notify OLE when the embedded item changes
CScribbleView::OnLButtonUp
and add the call to NotifyChanged just after the ReleaseCapture function call, before the final return: pDoc->NotifyChanged();