| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512 |
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1992-1998 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
- #include "stdafx.h"
- #ifdef _DEBUG
- #undef THIS_FILE
- static char BASED_CODE THIS_FILE[] = __FILE__;
- #endif
- #define new DEBUG_NEW
- /////////////////////////////////////////////////////////////////////////////
- // COleDocObjectItem
- IMPLEMENT_DYNAMIC(COleDocObjectItem, COleClientItem)
- BEGIN_INTERFACE_MAP(COleDocObjectItem, COleClientItem)
- INTERFACE_PART(COleDocObjectItem, IID_IOleDocumentSite, OleDocumentSite)
- END_INTERFACE_MAP()
- COleDocObjectItem::COleDocObjectItem(COleDocument* pContainerDoc)
- : COleClientItem(pContainerDoc)
- {
- m_pHelpPopupMenu = NULL;
- m_pActiveView = NULL;
- m_pIPrint = NULL;
- m_bInHelpMenu = FALSE;
- }
- COleDocObjectItem::~COleDocObjectItem()
- {
- if (m_pHelpPopupMenu != NULL)
- m_pHelpPopupMenu->RemoveMenu(0, MF_BYPOSITION);
- delete m_pHelpPopupMenu;
- }
- /////////////////////////////////////////////////////////////////////////////
- // IOleDocumentSite interface
- STDMETHODIMP_(ULONG) COleDocObjectItem::XOleDocumentSite::AddRef()
- {
- METHOD_PROLOGUE_EX(COleDocObjectItem, OleDocumentSite)
- return pThis->ExternalAddRef();
- }
- STDMETHODIMP_(ULONG) COleDocObjectItem::XOleDocumentSite::Release()
- {
- METHOD_PROLOGUE_EX(COleDocObjectItem, OleDocumentSite)
- return pThis->ExternalRelease();
- }
- STDMETHODIMP COleDocObjectItem::XOleDocumentSite::QueryInterface(
- REFIID iid, LPVOID* ppvObj)
- {
- METHOD_PROLOGUE_EX(COleDocObjectItem, OleDocumentSite)
- return pThis->ExternalQueryInterface(&iid, ppvObj);
- }
- STDMETHODIMP COleDocObjectItem::XOleDocumentSite::ActivateMe(
- LPOLEDOCUMENTVIEW pViewToActivate)
- {
- METHOD_PROLOGUE_EX(COleDocObjectItem, OleDocumentSite)
- LPOLEDOCUMENT lpDocument;
- LPOLECLIENTSITE lpClientSite = pThis->GetClientSite();
- LPOLEINPLACESITE lpInPlaceSite =
- (LPOLEINPLACESITE) pThis->GetInterface(&IID_IOleInPlaceSite);
- if (lpClientSite == NULL || lpInPlaceSite == NULL)
- return E_FAIL;
- // if we've gotten a NULL view, we're to create one ourselves
- if (pViewToActivate == NULL)
- {
- // if we already have a view, we can simply activate it
- if (pThis->m_pActiveView != NULL && pThis->m_pView != NULL)
- {
- pThis->ActivateAndShow();
- return NOERROR;
- }
- ASSERT(pThis->m_lpObject != NULL);
- if (pThis->m_lpObject == NULL)
- return E_FAIL;
- lpDocument = QUERYINTERFACE(pThis->m_lpObject, IOleDocument);
- if (lpDocument == NULL)
- return E_FAIL;
- if (FAILED(
- lpDocument->CreateView(lpInPlaceSite, NULL, 0, &pViewToActivate)))
- {
- lpDocument->Release();
- return E_OUTOFMEMORY;
- }
- // we're done with the document pointer
- lpDocument->Release();
- }
- else if (pThis->m_pActiveView != NULL && pThis->m_pActiveView == pViewToActivate)
- {
- // we already own this view, so no need to addref
- // simply make it visible and resize it
- pThis->ActivateAndShow();
- return NOERROR;
- }
- else
- {
- // set the in-place site
- pViewToActivate->SetInPlaceSite(lpInPlaceSite);
- pViewToActivate->AddRef();
- }
- // it must've created
- ASSERT(pThis->m_pView != NULL);
- // if we had an old one, release it
- if (pThis->m_pActiveView != NULL)
- {
- pThis->m_pActiveView->Show(FALSE);
- pThis->m_pActiveView->UIActivate(FALSE);
- pThis->m_pActiveView->Release();
- if (pThis->m_pIPrint != (IPrint*) -1 && pThis->m_pIPrint != NULL)
- pThis->m_pIPrint->Release();
- pThis->m_pIPrint = NULL;
- }
- // remember it for later
- pThis->m_pActiveView = pViewToActivate;
- // activate and position it
- pThis->ActivateAndShow();
- return NOERROR;
- }
- /////////////////////////////////////////////////////////////////////////////
- // IOleDocumentSite implementation helper
- void COleDocObjectItem::ActivateAndShow()
- {
- // set up toolbars and menus for the object
- m_pActiveView->UIActivate(TRUE);
- // set the window size, avoiding new toolbars
- RECT rc;
- m_pView->GetClientRect(&rc);
- m_pActiveView->SetRect(&rc);
- // make everything visible
- m_pActiveView->Show(TRUE);
- return;
- }
- void COleDocObjectItem::OnGetItemPosition(CRect& rPosition)
- {
- ASSERT_VALID(this);
- ASSERT(AfxIsValidAddress(&rPosition, sizeof(RECT)));
- // doc objects [almost] always in the exact rect of the view
- ASSERT_VALID(m_pView);
- m_pView->GetClientRect(&rPosition);
- }
- LPOLEDOCUMENTVIEW COleDocObjectItem::GetActiveView() const
- {
- return m_pActiveView;
- }
- void COleDocObjectItem::Release(OLECLOSE dwCloseOption)
- {
- RELEASE(m_pActiveView);
- if (m_pIPrint != (IPrint*) -1)
- RELEASE(m_pIPrint);
- COleClientItem::Release(dwCloseOption);
- }
- HRESULT COleDocObjectItem::ExecCommand(DWORD nCmdID,
- DWORD nCmdExecOpt /* = OLECMDEXECOPT_DONTPROMPTUSER */,
- const GUID* pguidCmdGroup /* = NULL */)
- {
- LPOLECOMMANDTARGET lpCt = QUERYINTERFACE(m_lpObject, IOleCommandTarget);
- HRESULT hr = E_NOTIMPL;
- if (lpCt != NULL)
- hr = lpCt->Exec(pguidCmdGroup, nCmdID, nCmdExecOpt, NULL, NULL);
- RELEASE(lpCt);
- return hr;
- }
- BOOL COleDocObjectItem::SupportsIPrint()
- {
- // did someone already ask? -1 means we know it doesn't,
- // non-NULL means we know it does (and we point at it)
- // NULL means we don't know
- if (m_pIPrint == NULL)
- {
- // QI for it
- m_pIPrint = QUERYINTERFACE(m_lpObject, IPrint);
- if (m_pIPrint == NULL)
- {
- // if the server isn't running, we'll need to
- // start it in order to print
- if (FAILED(::OleRun(m_lpObject)))
- m_pIPrint = (IPrint*) -1;
- else
- m_pIPrint = QUERYINTERFACE(m_lpObject, IPrint);
- }
- }
- return (m_pIPrint != NULL && m_pIPrint != (IPrint*) -1);
- }
- BOOL COleDocObjectItem::GetPageCount(LPLONG pnFirstPage, LPLONG pcPages)
- {
- if (!SupportsIPrint())
- return FALSE;
- //WINBUG: The proxy in DOCOBJ.DLL is broken; it doesn't allow
- // NULL parameters to IPrint::GetPageInfo(), even though the spec
- // says it should.
- LONG lPages;
- LONG lFirstPage;
- HRESULT hr = m_pIPrint->GetPageInfo(&lFirstPage, &lPages);
- if (pnFirstPage != NULL)
- *pnFirstPage = lFirstPage;
- if (pcPages != NULL)
- *pcPages = lPages;
- if (SUCCEEDED(hr))
- return TRUE;
- else
- return FALSE;
- }
- CMenu* COleDocObjectItem::GetHelpMenu(UINT& nPosition)
- {
- CFrameWnd* pFrame = m_pView->GetTopLevelFrame();
- CMenu* pMenuFrame = CMenu::FromHandle(pFrame->m_hMenuDefault);
- if (pMenuFrame != NULL)
- nPosition = pMenuFrame->GetMenuItemCount() -1;
- return pMenuFrame;
- }
- void COleDocObjectItem::OnInsertMenus(CMenu* pMenuShared,
- LPOLEMENUGROUPWIDTHS lpMenuWidths)
- {
- ASSERT_VALID(this);
- ASSERT_VALID(pMenuShared);
- ASSERT(AfxIsValidAddress(lpMenuWidths, sizeof(OLEMENUGROUPWIDTHS)));
- // initialize the group widths array
- lpMenuWidths->width[0] = 1;
- lpMenuWidths->width[2] = 0;
- lpMenuWidths->width[4] = 0;
- // get menu from document template
- CDocTemplate* pTemplate = GetDocument()->GetDocTemplate();
- HMENU hMenuOLE = pTemplate->m_hMenuInPlace;
- // only copy the popups if there is a menu loaded
- if (hMenuOLE == NULL)
- return;
- UINT nItem;
- CMenu* pMenuFrame = GetHelpMenu(nItem);
- if (pMenuFrame != NULL)
- {
- CString strHelpMenuName;
- int nSeparator = pMenuFrame->GetMenuString(nItem,
- strHelpMenuName, MF_BYPOSITION);
- if (nSeparator == 0)
- {
- TRACE0("Error: COleDocObjectItem::OnInsertMenus() found no help menu!\n");
- return;
- }
- CString strTearOffName;
- strTearOffName.Format(_T("%s %s"), AfxGetAppName(), strHelpMenuName);
- strTearOffName.Remove('&');
- // get the normal frame menu
- int nCount = pMenuFrame->GetMenuItemCount();
- HMENU hMenu = GetSubMenu(pMenuFrame->m_hMenu, nCount-1);
- // clean up old menu and allocate a new one
- if (m_pHelpPopupMenu == NULL)
- {
- m_pHelpPopupMenu = new CMenu;
- // create new sub-popup menu and add container's Help tearoff
- // then add help menu from main window
- m_pHelpPopupMenu->CreateMenu();
- m_pHelpPopupMenu->InsertMenu((UINT) -1, MF_BYPOSITION | MF_POPUP,
- (UINT) hMenu, strTearOffName);
- }
- pMenuShared->InsertMenu(1, MF_BYPOSITION | MF_POPUP,
- (UINT) m_pHelpPopupMenu->m_hMenu, strHelpMenuName);
- // tell the object we added our Help menu
- lpMenuWidths->width[5] = 1;
- }
- // insert our menu items and adjust group widths array
- AfxMergeMenus(pMenuShared->GetSafeHmenu(), hMenuOLE,
- &lpMenuWidths->width[0], 0);
- }
- void COleDocObjectItem::OnRemoveMenus(CMenu *pMenuShared)
- {
- int cItemsShared = pMenuShared->GetMenuItemCount();
- if (cItemsShared != 0)
- {
- CMenu *pMenuHelp = pMenuShared->GetSubMenu(cItemsShared - 1);
- int cItemsHelp = pMenuHelp->GetMenuItemCount();
- int nItem;
- for (nItem = cItemsHelp-1; nItem > 0; nItem--)
- pMenuHelp->DeleteMenu(nItem, MF_BYPOSITION);
- pMenuShared->RemoveMenu(cItemsShared - 1, MF_BYPOSITION);
- }
- COleClientItem::OnRemoveMenus(pMenuShared);
- }
- BOOL COleDocObjectItem::OnPreparePrinting(CView* pCaller,
- CPrintInfo* pInfo, BOOL bPrintAll)
- {
- LONG lDocObjectPages = 0;
- CDocument* pDoc = pCaller->GetDocument();
- COleDocument* pOleDoc = DYNAMIC_DOWNCAST(COleDocument, pDoc);
- if (pOleDoc == NULL)
- return FALSE;
- POSITION pos = pOleDoc->GetStartPosition();
- while (pos != NULL)
- {
- COleClientItem* pItem = pOleDoc->GetNextClientItem(pos);
- COleDocObjectItem* pDocItem =
- DYNAMIC_DOWNCAST(COleDocObjectItem, pItem);
- if (pDocItem == NULL)
- continue;
- // if this isn't the view, continue
- if (!bPrintAll)
- {
- if (pItem->m_pView == NULL ||
- pItem->m_pView->m_hWnd != pCaller->m_hWnd)
- continue;
- }
- if (pDocItem->SupportsIPrint())
- {
- LONG lThisObjectPages;
- if (pDocItem->GetPageCount(NULL, &lThisObjectPages))
- lDocObjectPages += lThisObjectPages;
- pInfo->m_bDocObject = TRUE;
- }
- else
- lDocObjectPages++;
- if (!bPrintAll)
- break;
- }
- if (lDocObjectPages > 0)
- {
- UINT nMaxPage = pInfo->GetMaxPage();
- // set the page count; increment it if previously set
- if (nMaxPage == 0xFFFF)
- pInfo->SetMaxPage(lDocObjectPages);
- else
- pInfo->SetMaxPage(nMaxPage + lDocObjectPages);
- pInfo->m_bDocObject = TRUE;
- }
- if (pInfo->m_bDocObject)
- {
- // we can't show the "selection" button for DocObjects
- pInfo->m_pPD->m_pd.Flags |= PD_NOSELECTION;
- // if it's a doc object, and we're printing all, then we
- // shouldn't show the selection
- if (bPrintAll)
- pInfo->m_pPD->m_pd.Flags |= PD_NOPAGENUMS;
- }
- return TRUE;
- }
- void COleDocObjectItem::OnPrint(CView* pCaller, CPrintInfo* pInfo,
- BOOL bPrintAll)
- {
- // Note that this function ignores pInfo->m_nCurPage, and will always
- // print the whole range of pages in the CPrintInfo object. That's
- // because DocObjects don't support any mechanism to _continue_
- // printing to an existing print job.
- CDocument* pDoc = pCaller->GetDocument();
- COleDocument* pOleDoc = DYNAMIC_DOWNCAST(COleDocument, pDoc);
- if (pOleDoc == NULL)
- return;
- POSITION pos = pOleDoc->GetStartPosition();
- while (pos != NULL)
- {
- COleClientItem* pItem = pOleDoc->GetNextClientItem(pos);
- COleDocObjectItem* pDocItem = DYNAMIC_DOWNCAST(COleDocObjectItem, pItem);
- if (pDocItem == NULL)
- continue;
- // if this isn't the view, continue
- if (!bPrintAll)
- {
- if (pItem->m_pView == NULL || pItem->m_pView->m_hWnd != pCaller->m_hWnd)
- continue;
- }
- HRESULT hrThisPage = E_UNEXPECTED;
- if (pDocItem->SupportsIPrint())
- {
- DVTARGETDEVICE* pTargetDevice = NULL;
- LPDEVNAMES lpDevNames = NULL;
- LPDEVMODE lpDevMode = NULL;
- lpDevNames = (LPDEVNAMES) GlobalLock(pInfo->m_pPD->m_pd.hDevNames);
- if (lpDevNames != NULL)
- {
- lpDevMode = (LPDEVMODE) GlobalLock(pInfo->m_pPD->m_pd.hDevMode);
- if (lpDevMode != NULL)
- {
- pTargetDevice = _AfxOleCreateTargetDevice(lpDevNames, lpDevMode);
- if (pTargetDevice != NULL)
- {
- PAGESET* pps = (PAGESET*) CoTaskMemAlloc(sizeof(PAGESET));
- if (pps != NULL)
- {
- pps->cbStruct = sizeof(PAGESET);
- ASSERT((pps->cbStruct % 4) == 0);
- pps->fOddPages = TRUE;
- pps->fEvenPages = TRUE;
- pps->cPageRange = 1;
- pps->rgPages[0].nFromPage = pInfo->GetFromPage();
- pps->rgPages[0].nToPage = pInfo->GetToPage();
- LONG lLastPage = pps->rgPages[0].nFromPage;
- LONG lPagesPrinted;
- DWORD dwFlags = PRINTFLAG_RECOMPOSETODEVICE;
- if (pInfo->m_pPD->m_pd.Flags & PD_PRINTTOFILE)
- dwFlags |= PRINTFLAG_PRINTTOFILE;
- hrThisPage = pDocItem->m_pIPrint->Print(dwFlags,
- &pTargetDevice, &pps, NULL, NULL,
- pInfo->m_nCurPage, &lPagesPrinted,
- &lLastPage);
- if (!SUCCEEDED(hrThisPage))
- TRACE1("IPrint::Print() returned %8.8X\n", hrThisPage);
- CoTaskMemFree(pps);
- }
- CoTaskMemFree(pTargetDevice);
- }
- GlobalUnlock(pInfo->m_pPD->m_pd.hDevMode);
- }
- GlobalUnlock(pInfo->m_pPD->m_pd.hDevNames);
- }
- }
- else
- {
- // try through IOleCommandTarget
- hrThisPage = pDocItem->ExecCommand(OLECMDID_PRINT);
- if (!SUCCEEDED(hrThisPage))
- TRACE1("IOleCommandTarget::Exec() returned %8.8X\n", hrThisPage);
- }
- }
- return;
- }
|