Resizing embedded doc
David Shillito -- David_Shillito@msn.com
Thursday, February 06, 1997
Environment: MFC 4.2b, VC++ 4.2b, NT4.0
Can anyone tell me how to achieve the effect found in MSGraph where resizing
the graph while it is open in the Graph application causes it to be resized in
the container(e.g. Excel) and vice versa.
To observe the effect:
1. Start Excel 97
2. Insert Object: Microsoft Graph 97 Chart
3. Click outside the new chart to deactivate it.
4. Right-click on the chart and select Chart Object: Open
5. Position the Microsoft Graph Application window so the Excel window with
the chart is also visible.
6. Use the sizing border to resize the graph window in Graph and see the graph
object in Excel change size too.
7. Use the sizing handles on the graph object in Excel to resize it and
observe the graph window in the Graph aplication change size too.
I have tried many different approaches in my MFC OLE server app to get this
effect but none have been successful. I suspect the answer involves using
RequestPositionChange but so far that only makes things worse.
David Shillito
Bing Hou -- hou@tfn.com
Monday, February 10, 1997
[Mini-digest: 2 responses]
Override your COleServerItem's OnGetExtent(DVASPECT, CSize&) function. This
function is called whenever the client needs to draw the object, and draws
the object according to the returned size in the CSize& param.
However, the client will not redraw your object unless you tell the client
that you have changed the object and ask it to update. There are different
ways to do this. In your case, if your object represents a child
window(like MS Graph), you may simply insert the following lines of code at
the end of the OnSize function.
CMyDocDrivedFromOleDoc *pDoc = GetDocument();
pDoc->NotifyChanged();
If you aren't using MFC's classes, the idea should be the same.
Bing Hou
hou@tfn.com
------------------------------------------------------------------------
Recall it as often as you wish, a happy memory never wears out.
______________________________ Reply Separator _________________________________
Subject: Resizing embedded doc
Author: "David Shillito" at Internet
Date: 2/6/97 12:04 AM
Environment: MFC 4.2b, VC++ 4.2b, NT4.0
Can anyone tell me how to achieve the effect found in MSGraph where resizing
the graph while it is open in the Graph application causes it to be resized in
the container(e.g. Excel) and vice versa.
To observe the effect:
1. Start Excel 97
2. Insert Object: Microsoft Graph 97 Chart
3. Click outside the new chart to deactivate it.
4. Right-click on the chart and select Chart Object: Open
5. Position the Microsoft Graph Application window so the Excel window with
the chart is also visible.
6. Use the sizing border to resize the graph window in Graph and see the graph
object in Excel change size too.
7. Use the sizing handles on the graph object in Excel to resize it and
observe the graph window in the Graph aplication change size too.
I have tried many different approaches in my MFC OLE server app to get this
effect but none have been successful. I suspect the answer involves using
RequestPositionChange but so far that only makes things worse.
David Shillito
-----From: "David Shillito"
Thanks for your reply. I have already tried the items you suggest but have not
been able to get it to work.
I have code in CMyDoc::SetItemRects to capture any change in the container and
save it in my document. I have code in CMySrvrItem::OnGetExtent to return the
most recent size from the container - converted to HIMETRIC. I have code in
CMyMDICildFrame::OnSize to call RequestPositionChange and NotifyChanged.
It seems the most basic problem exists - OnSetItemRects is not called when the
object is resized in ther container. Without this notification I cannot adjust
the size that I return in OnGetExtent.
Can you suggest any other areas I might have overlooked?
David Shillito
david_shillito@msn.com
--------------------------------------------------------
Override your COleServerItem's OnGetExtent(DVASPECT, CSize&) function. This
function is called whenever the client needs to draw the object, and draws
the object according to the returned size in the CSize& param.
However, the client will not redraw your object unless you tell the client
that you have changed the object and ask it to update. There are different
ways to do this. In your case, if your object represents a child
window(like MS Graph), you may simply insert the following lines of code at
the end of the OnSize function.
CMyDocDrivedFromOleDoc *pDoc = GetDocument();
pDoc->NotifyChanged();
If you aren't using MFC's classes, the idea should be the same.
Bing Hou
David Shillito -- David_Shillito@msn.com
Monday, February 17, 1997
I eventually found the recipe for achieving most of the behavior exhibited by
MS Graph. Only point 7 is different now - I can resize in Excel and have the
new size used by my server, but only if I resize while the object is in-place
active, not while it is open in a server window. The solution did not involve
using RequestPositionChange.
Thanks to those who offered advice.
David Shillito
Here are the areas where I added code to my AppWizard-generated OLE Server
application:
class CSVRDoc : public COleServerDoc
{
// ...
CSize CalculateExtent();
CSize m_sizeExtent;
// ...
};
CSVRDoc::CSVRDoc()
{
// ...
m_sizeExtent = CSize(0,0);
// ...
}
void CSVRDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// TODO: add storing code here
// ...
ar << m_sizeExtent;
// ...
}
else
{
// TODO: add loading code here
// ...
ar >> m_sizeExtent;
// ...
}
// Calling the base class COleServerDoc enables serialization
// of the container document's COleClientItem objects.
COleServerDoc::Serialize(ar);
}
void CSVRDoc::OnSetItemRects(LPCRECT lpPosRect, LPCRECT lpClipRect)
{
// Save size of posRect to use as our extent
COleServerDoc::OnSetItemRects(lpPosRect, lpClipRect);
CRect rItem(lpPosRect);
m_sizeExtent = rItem.Size();
}
CSize CSVRDoc::CalculateExtent()
{
if (m_sizeExtent == CSize (0,0))
return (5000, 5000);
else
{
CClientDC dc(NULL);
CSize rSize = m_sizeExtent;
dc.DPtoHIMETRIC (&rSize);
return rSize;
}
}
void CChildFrame::ActivateFrame(int nCmdShow)
{
// TODO: Add your specialized code here and/or call the base class
// This code added to get the doc to open in the server
// in a window sized the same as the inplace object in the container.
//
CSVRDoc* pDoc = (CSVRDoc*) GetActiveDocument();
ASSERT (pDoc);
// should we test nCmdShow == SW_NORMAL etc
if (pDoc->m_sizeExtent != CSize(0,0))
{
CRect r(CPoint (0,0), pDoc->m_sizeExtent);
CalcWindowRect (&r);
SetWindowPos (NULL, 0, 0, r.Width(), r.Height(), SWP_NOZORDER);
}
CMDIChildWnd::ActivateFrame(nCmdShow);
}
void CChildFrame::OnSize(UINT nType, int cx, int cy)
{
CMDIChildWnd::OnSize(nType, cx, cy);
// User has resized frame in server
// Ask the container to do the same.
CSVRDoc* pDoc = (CSVRDoc*) GetActiveDocument();
// pDoc will be NULL for WM_SIZE during window creation
if (pDoc)
{
CSize rSize(cx, cy);
pDoc->m_sizeExtent = rSize;
pDoc->SetModifiedFlag(TRUE);
pDoc->NotifyChanged();
}
}
BOOL CSVRSrvrItem::OnGetExtent(DVASPECT dwDrawAspect, CSize& rSize)
{
// Most applications, like this one, only handle drawing the content
// aspect of the item. If you wish to support other aspects, such
// as DVASPECT_THUMBNAIL (by overriding OnDrawEx), then this
// implementation of OnGetExtent should be modified to handle the
// additional aspect(s).
if (dwDrawAspect != DVASPECT_CONTENT)
return COleServerItem::OnGetExtent(dwDrawAspect, rSize);
// CSVRSrvrItem::OnGetExtent is called to get the extent in
// HIMETRIC units of the entire item. The default implementation
// here simply returns a hard-coded number of units.
CSVRDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: replace this arbitrary size
rSize = pDoc->CalculateExtent(); // <<<<
return TRUE;
}
BOOL CSVRSrvrItem::OnDraw(CDC* pDC, CSize& rSize)
{
CSVRDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: set mapping mode and extent
// (The extent is usually the same as the size returned from OnGetExtent)
pDC->SetMapMode(MM_ANISOTROPIC);
pDC->SetWindowOrg(0,0);
// ...
rSize = pDoc->CalculateExtent(); // <<<<
pDC->SetWindowExt(rSize.cx, rSize.cy);
// ...
}
------------------------------------------------------------------------------
--------------------------------
Original message text:
Environment: MFC 4.2b, VC++ 4.2b, NT4.0
Can anyone tell me how to achieve the effect found in MSGraph where resizing
the graph while it is open in the Graph application causes it to be resized in
the container(e.g. Excel) and vice versa.
To observe the effect:
1. Start Excel 97
2. Insert Object: Microsoft Graph 97 Chart
3. Click outside the new chart to deactivate it.
4. Right-click on the chart and select Chart Object: Open
5. Position the Microsoft Graph Application window so the Excel window with
the chart is also visible.
6. Use the sizing border to resize the graph window in Graph and see the graph
object in Excel change size too.
7. Use the sizing handles on the graph object in Excel to resize it and
observe the graph window in the Graph aplication change size too.
I have tried many different approaches in my MFC OLE server app to get this
effect but none have been successful. I suspect the answer involves using
RequestPositionChange but so far that only makes things worse.
David Shillito
Become an MFC-L member
| Вернуться в корень Архива
|