www.pudn.com > WORD_xoffice_src.rar > CntrItem.cpp


// CntrItem.cpp : implementation of the CXOfficeCntrItem class 
// 
 
#include "stdafx.h" 
#include "XOffice.h" 
 
#include "XOfficeDoc.h" 
#include "XOfficeView.h" 
#include "CntrItem.h" 
#include "Office.h" 
 
#ifdef _DEBUG 
#define new DEBUG_NEW 
#undef THIS_FILE 
static char THIS_FILE[] = __FILE__; 
#endif 
 
 
void 
ComMessage (const _com_error& e)                                /// 
{ 
	CString msg; 
 
	msg.Format("Error: %08lx",e.Error()); 
	msg += '\n'; 
	msg += e.ErrorMessage(); 
	msg += '\n'; 
	msg += e.Source(); 
	msg += '\n'; 
	msg += e.Description(); 
 
	AfxMessageBox(msg); 
} 
 
static IDispatchPtr 
GetObject (BSTR name)                                           /// 
{ 
  IDispatchPtr  ret; 
  CLSID clsid; 
  if (::CLSIDFromProgID(name,&clsid) == S_OK) { 
    IUnknown *pUnk; 
    if (::GetActiveObject(clsid,NULL,&pUnk) == S_OK) { 
      IDispatch *pDisp; 
      if (pUnk->QueryInterface(IID_IDispatch,(void**)&pDisp) == S_OK) { 
        ret = pDisp; 
        pDisp->Release(); 
      } 
      pUnk->Release(); 
    } 
  } 
  return ret; 
} 
 
 
///////////////////////////////////////////////////////////////////////////// 
// CXOfficeCntrItem implementation 
 
IMPLEMENT_SERIAL(CXOfficeCntrItem, COleDocObjectItem, 0) 
 
CXOfficeCntrItem::CXOfficeCntrItem(CXOfficeDoc* pContainer) 
	: COleDocObjectItem(pContainer), m_isCreate(false) 
{ 
	((CXOfficeApp*)AfxGetApp())->m_active = pContainer; 
} 
 
CXOfficeCntrItem::~CXOfficeCntrItem() 
{ 
	if (((CXOfficeApp*)AfxGetApp())->m_active == GetDocument()) 
	    ((CXOfficeApp*)AfxGetApp())->m_active = 0; 
} 
 
void CXOfficeCntrItem::OnChange(OLE_NOTIFICATION nCode, DWORD dwParam) 
{ 
	ASSERT_VALID(this); 
 
	BOOL modified = m_pDocument->IsModified(); 
	COleDocObjectItem::OnChange(nCode, dwParam); 
	m_pDocument->SetModifiedFlag(modified); 
 
	// When an item is being edited (either in-place or fully open) 
	//  it sends OnChange notifications for changes in the state of the 
	//  item or visual appearance of its content. 
 
	// TODO: invalidate the item by calling UpdateAllViews 
	//  (with hints appropriate to your application) 
 
	GetDocument()->UpdateAllViews(NULL); 
		// for now just update ALL views/no hints 
} 
 
BOOL CXOfficeCntrItem::OnChangeItemPosition(const CRect& rectPos) 
{ 
	ASSERT_VALID(this); 
 
  // During in-place activation CXOfficeCntrItem::OnChangeItemPosition 
	//  is called by the server to change the position of the in-place 
	//  window.  Usually, this is a result of the data in the server 
	//  document changing such that the extent has changed or as a result 
	//  of in-place resizing. 
	// 
	// The default here is to call the base class, which will call 
	//  COleDocObjectItem::SetItemRects to move the item 
	//  to the new position. 
 
	if (!COleDocObjectItem::OnChangeItemPosition(rectPos)) 
		return FALSE; 
 
	// TODO: update any cache you may have of the item's rectangle/extent 
 
	return TRUE; 
} 
 
 
void CXOfficeCntrItem::OnActivate() 
{ 
	((CXOfficeApp*)AfxGetApp())->m_active = GetDocument(); 
} 
 
void CXOfficeCntrItem::OnDeactivateUI(BOOL bUndoable) 
{ 
	if (((CXOfficeApp*)AfxGetApp())->m_active == GetDocument()) 
		((CXOfficeApp*)AfxGetApp())->m_active = 0; 
	 
	COleDocObjectItem::OnDeactivateUI(bUndoable); 
 
    // Hide the object if it is not an outside-in object 
    DWORD dwMisc = 0; 
    m_lpObject->GetMiscStatus(GetDrawAspect(), &dwMisc); 
    if (dwMisc & OLEMISC_INSIDEOUT) 
        DoVerb(OLEIVERB_HIDE, NULL); 
} 
 
void CXOfficeCntrItem::Serialize(CArchive& ar) 
{ 
	ASSERT_VALID(this); 
 
	// Call base class first to read in COleDocObjectItem data. 
	// Since this sets up the m_pDocument pointer returned from 
  //  CXOfficeCntrItem::GetDocument, it is a good idea to call 
	//  the base class Serialize first. 
	COleDocObjectItem::Serialize(ar); 
 
  // now store/retrieve data specific to CXOfficeCntrItem 
	if (ar.IsStoring()) 
	{ 
		// TODO: add storing code here 
	} 
	else 
	{ 
		// TODO: add loading code here 
	} 
} 
 
///////////////////////////////////////////////////////////////////////////// 
// CXOfficeCntrItem diagnostics 
 
#ifdef _DEBUG 
void CXOfficeCntrItem::AssertValid() const 
{ 
	COleDocObjectItem::AssertValid(); 
} 
 
void CXOfficeCntrItem::Dump(CDumpContext& dc) const 
{ 
	COleDocObjectItem::Dump(dc); 
} 
#endif 
 
///////////////////////////////////////////////////////////////////////////// 
 
CXOfficeCntrItem::CXOfficeCntrItem(CXOfficeDoc* pContainer,LPCTSTR templ) 
	: COleDocObjectItem(pContainer), m_isCreate(false), m_who(0) 
{ 
	((CXOfficeApp*)AfxGetApp())->m_active = pContainer; 
	CreateItem(templ); 
} 
 
bool CXOfficeCntrItem::CreateItem(LPCTSTR templ) 
{ 
	USES_CONVERSION; 
 
	// get storage for the object via virtual function call 
	m_dwItemNumber = GetNewItemNumber(); 
	GetItemStorage(); 
 
	// add AfxOleInit(); in CXOfficeApp::InitInstance 
	AfxOleGetMessageFilter()->EnableNotRespondingDialog(FALSE); 
 
	// attempt to create the object 
	LPOLECLIENTSITE lpClientSite = GetClientSite(); 
	SCODE sc = ::OleCreateFromFile(CLSID_NULL, 
	                               T2COLE(templ), 
	                               IID_IUnknown, 
	                               OLERENDER_DRAW, 
	                               NULL, 
	                               lpClientSite, 
	                               m_lpStorage, 
	                               (LPVOID*)&m_lpObject); 
	return m_isCreate = FinishCreate(sc) == TRUE; 
} 
 
LPDISPATCH CXOfficeCntrItem::GetIDispatch() 
{ 
	ASSERT_VALID(this); 
	ASSERT(m_lpObject != NULL); 
   
	LPUNKNOWN lpUnk = m_lpObject; 
 
	Run();    // must be running 
   
	LPOLELINK lpOleLink = NULL; 
	if (m_lpObject->QueryInterface(IID_IOleLink, 
	                               (LPVOID FAR*)&lpOleLink) == NOERROR) { 
		ASSERT(lpOleLink != NULL); 
		lpUnk = NULL; 
		if (lpOleLink->GetBoundSource(&lpUnk) != NOERROR) { 
			TRACE0("Warning: Link is not connected!\n"); 
			lpOleLink->Release(); 
			return NULL; 
		} 
//		lpOleLink->Release(); 
		ASSERT(lpUnk != NULL); 
	} 
   
	LPDISPATCH lpDispatch = NULL; 
	if (lpUnk->QueryInterface(IID_IDispatch,(void**)&lpDispatch) != NOERROR) { 
		TRACE0("Warning: does not support IDispatch!\n"); 
		return NULL; 
	} 
   
	ASSERT(lpDispatch != NULL); 
	return lpDispatch; 
} 
 
void CXOfficeCntrItem::AttachDisp() 
{ 
	LPDISPATCH  lpDispatch = GetIDispatch(); 
	if (lpDispatch != 0) { 
		m_disp.Attach(lpDispatch,false); 
	} else { 
		m_disp = GetObject(L"Word.Application"); 
	} 
 
	if (m_disp != 0) try { 
		Word::_DocumentPtr  doc = m_disp; 
		if (doc) { 
			m_who = 1; 
		} else { 
			Excel::_WorkbookPtr book = m_disp; 
			if (book) { 
				m_who = 2; 
			} 
		} 
	} catch (_com_error& er) { 
		ComMessage(er); 
	} 
} 
 
void CXOfficeCntrItem::ActivateDisp() 
{ 
	if (m_disp != 0) try { 
		Word::_DocumentPtr  doc = m_disp; 
		if (doc) { 
			doc->RunAutoMacro(Word::wdAutoNew); 
		} 
	} catch (_com_error& er) { 
		ComMessage(er); 
	} 
} 
 
void CXOfficeCntrItem::CloseDisp() 
{ 
	m_disp = 0; 
} 
 
void CXOfficeCntrItem::SetIcon(CFrameWnd *frame) 
{ 
  if (m_disp != 0) try { 
    CString ver; 
 
	if (m_who == 1) { 
		Word::_DocumentPtr  doc = m_disp; 
		if (doc) { 
			ver = (BSTR)doc->Application->Version; 
			ver = ver.Left(3); 
			if (ver == "8.0") { 
				frame->SetIcon(AfxGetApp()->LoadIcon(IDI_WORD8),TRUE); 
			} else if (ver == "9.0") { 
				frame->SetIcon(AfxGetApp()->LoadIcon(IDI_WORD9),TRUE); 
			} 
		} 
	} else if (m_who == 2) { 
		Excel::_WorkbookPtr book = m_disp; 
		if (book) { 
			ver = (BSTR)book->Application->Version; 
			ver = ver.Left(3); 
			if (ver == "8.0") { 
				frame->SetIcon(AfxGetApp()->LoadIcon(IDI_EXCEL8),TRUE); 
			} else if (ver == "9.0") { 
				frame->SetIcon(AfxGetApp()->LoadIcon(IDI_EXCEL9),TRUE); 
			} 
		} 
	} 
  } catch (_com_error& er) { 
	ComMessage(er); 
  } 
}