15 мая 2023 года "Исходники.РУ" отмечают своё 23-летие!
Поздравляем всех причастных и неравнодушных с этим событием!
И огромное спасибо всем, кто был и остаётся с нами все эти годы!

Главная Форум Журнал Wiki DRKB Discuz!ML Помощь проекту


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