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 | Вернуться в корень Архива |