⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dsofprint.cpp

📁 用于在线office文档编辑的控件。可以在线新建文档、修改文档
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/***************************************************************************
 * DSOFPRINT.CPP
 *
 * CDsoDocObject: Print Code for CDsoDocObject object
 *
 *  Copyright ?999-2004; Microsoft Corporation. All rights reserved.
 *  Written by Microsoft Developer Support Office Integration (PSS DSOI)
 * 
 *  This code is provided via KB 311765 as a sample. It is not a formal
 *  product and has not been tested with all containers or servers. Use it
 *  for educational purposes only. See the EULA.TXT file included in the
 *  KB download for full terms of use and restrictions.
 *
 *  THIS CODE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
 *  EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
 *
 ***************************************************************************/
#include "dsoframer.h"
#include "msoffice.h"
#include <atlbase.h>
#include <atlconv.h>
#include <afxdisp.h>
#include <afxwin.h>
#include <tchar.h>
#include <wininet.h>
#include <afxinet.h>
#include "XMLHttpClient.h"
 
#include <atlbase.h>
#include <mshtml.h> 
#include <mshtmdid.h> 
#include <comdef.h>	

#import "C:\WINDOWS\system32\msxml3.dll"
using namespace MSXML2;
extern char* BSTR2char(const BSTR bstr) ;
////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::_PrintOutOld
//
//  Prints the current object by calling IOleCommandTarget for Print.
//
STDMETHODIMP CDsoFramerControl::_PrintOutOld(VARIANT PromptToSelectPrinter)
{
    DWORD dwOption = BOOL_FROM_VARIANT(PromptToSelectPrinter, FALSE) 
                   ? OLECMDEXECOPT_PROMPTUSER : OLECMDEXECOPT_DODEFAULT;

    TRACE1("CDsoFramerControl::_PrintOutOld(%d)\n", dwOption);
    CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN));

 // Cannot access object if in modal condition...
    if ((m_fModalState) || (m_pDocObjFrame->InPrintPreview()))
        return ProvideErrorInfo(DSO_E_INMODALSTATE);

	return m_pDocObjFrame->DoOleCommand(OLECMDID_PRINT, dwOption, NULL, NULL);
}

////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::PrintOut
//
//  Prints document using either IPrint or IOleCommandTarget, depending
//  on parameters passed. This offers a bit more control over printing if
//  the doc object server supports IPrint interface.
//
STDMETHODIMP CDsoFramerControl::PrintOut(VARIANT PromptUser, VARIANT PrinterName,
                VARIANT Copies, VARIANT FromPage, VARIANT ToPage, VARIANT OutputFile)
{
    HRESULT hr;
    BOOL fPromptUser   = BOOL_FROM_VARIANT(PromptUser, FALSE);
    LPWSTR pwszPrinter = LPWSTR_FROM_VARIANT(PrinterName);
    LPWSTR pwszOutput  = LPWSTR_FROM_VARIANT(OutputFile);
    LONG lCopies       = LONG_FROM_VARIANT(Copies, 1);
    LONG lFrom         = LONG_FROM_VARIANT(FromPage, 0);
    LONG lTo           = LONG_FROM_VARIANT(ToPage, 0);

	TRACE3("CDsoFramerControl::PrintOut(%d, %S, %d)\n", fPromptUser, pwszPrinter, lCopies);
    CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN));

 // First we do validation of all parameters passed to the function...
    if ((pwszPrinter) && (*pwszPrinter == L'\0'))
        return E_INVALIDARG;

    if ((pwszOutput) && (*pwszOutput == L'\0'))
        return E_INVALIDARG;

    if ((lCopies < 1) || (lCopies > 200))
        return E_INVALIDARG;

    if (((lFrom != 0) || (lTo != 0)) && ((lFrom < 1) || (lTo < lFrom)))
        return E_INVALIDARG;

 // Cannot access object if in modal condition...
    if ((m_fModalState) || (m_pDocObjFrame->InPrintPreview()))
        return ProvideErrorInfo(DSO_E_INMODALSTATE);

 // If no printer name was provided, we can print to the default device
 // using IOleCommandTarget with OLECMDID_PRINT...
    if (pwszPrinter == NULL)
        return _PrintOutOld(PromptUser);

 // Ask the embedded document to print itself to specific printer...
    hr = m_pDocObjFrame->PrintDocument(pwszPrinter, pwszOutput, (UINT)lCopies, 
                        (UINT)lFrom, (UINT)lTo, fPromptUser);

 // If call failed because interface doesn't exist, change error
 // to let caller know it is because DocObj doesn't support this command...
    if (FAILED(hr) && (hr == E_NOINTERFACE))
        hr = DSO_E_COMMANDNOTSUPPORTED;

    return ProvideErrorInfo(hr);
}

////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::PrintPreview
//
//  Asks embedded object to attempt a print preview (only Office docs do this).
//
STDMETHODIMP CDsoFramerControl::PrintPreview()
{
    HRESULT hr;
	ODS("CDsoFramerControl::PrintPreview\n");
    CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN));

    if (m_fModalState) // Cannot access object if in modal condition...
        return ProvideErrorInfo(DSO_E_INMODALSTATE);

 // Try to set object into print preview mode...
    hr = m_pDocObjFrame->StartPrintPreview();

 // If call failed because interface doesn't exist, change error
 // to let caller know it is because DocObj doesn't support this command...
    if (FAILED(hr) && (hr == E_NOINTERFACE))
        hr = DSO_E_COMMANDNOTSUPPORTED;

    return ProvideErrorInfo(hr);
}

////////////////////////////////////////////////////////////////////////
// CDsoFramerControl::PrintPreviewExit
//
//  Closes an active preview.
//
STDMETHODIMP CDsoFramerControl::PrintPreviewExit()
{
	ODS("CDsoFramerControl::PrintPreviewExit\n");
    CHECK_NULL_RETURN(m_pDocObjFrame, ProvideErrorInfo(DSO_E_DOCUMENTNOTOPEN));

 // Try to set object out of print preview mode...
    if (m_pDocObjFrame->InPrintPreview())
        m_pDocObjFrame->ExitPrintPreview(TRUE);

    return S_OK;
}


////////////////////////////////////////////////////////////////////////
// CDsoDocObject::PrintDocument
//
//  We can use the IPrint interface for an ActiveX Document object to 
//  selectively print object to a given printer. 
//
STDMETHODIMP CDsoDocObject::PrintDocument(LPCWSTR pwszPrinter, LPCWSTR pwszOutput, UINT cCopies, UINT nFrom, UINT nTo, BOOL fPromptUser)
{
    HRESULT hr;
    IPrint *print;
    HANDLE hPrint;
    DVTARGETDEVICE* ptd = NULL;

    ODS("CDsoDocObject::PrintDocument\n");
    CHECK_NULL_RETURN(m_pole, E_UNEXPECTED);

 // First thing we need to do is ask object for IPrint. If it does not
 // support it, we cannot continue. It is up to DocObj if this is allowed...
    hr = m_pole->QueryInterface(IID_IPrint, (void**)&print);
    RETURN_ON_FAILURE(hr);

 // Now setup printer settings into DEVMODE for IPrint. Open printer 
 // settings and gather default DEVMODE...
    if (FOpenPrinter(pwszPrinter, &hPrint))
    {
        LPDEVMODEW pdevMode     = NULL;
        LPWSTR pwszDefProcessor = NULL;
        LPWSTR pwszDefDriver    = NULL;
        LPWSTR pwszDefPort      = NULL;
        LPWSTR pwszPort;
        DWORD  cbDevModeSize;

        if (FGetPrinterSettings(hPrint, &pwszDefProcessor, 
                &pwszDefDriver, &pwszDefPort, &pdevMode, &cbDevModeSize) && (pdevMode))
        {
            DWORD cbPrintName, cbDeviceName, cbOutputName;
            DWORD cbDVTargetSize;

            pdevMode->dmFields |= DM_COPIES;
            pdevMode->dmCopies = (WORD)((cCopies) ? cCopies : 1);

            pwszPort = ((pwszOutput) ? (LPWSTR)pwszOutput : pwszDefPort);
         
         // We calculate the size we will need for the TARGETDEVICE structure...
            cbPrintName  = ((lstrlenW(pwszDefProcessor) + 1) * sizeof(WCHAR));
            cbDeviceName = ((lstrlenW(pwszDefDriver)    + 1) * sizeof(WCHAR));
            cbOutputName = ((lstrlenW(pwszPort)         + 1) * sizeof(WCHAR));

            cbDVTargetSize = sizeof(DWORD) + sizeof(DEVNAMES) + cbPrintName +
                            cbDeviceName + cbOutputName + cbDevModeSize;

         // Allocate new target device using COM Task Allocator...
            ptd = (DVTARGETDEVICE*)CoTaskMemAlloc(cbDVTargetSize);
            if (ptd)
            {
             // Copy all the data in the DVT...
                DWORD dwOffset = sizeof(DWORD) + sizeof(DEVNAMES);
                ptd->tdSize = cbDVTargetSize;

                ptd->tdDriverNameOffset = (WORD)dwOffset;
                memcpy((BYTE*)(((BYTE*)ptd) + dwOffset), pwszDefProcessor, cbPrintName);
                dwOffset += cbPrintName;

                ptd->tdDeviceNameOffset = (WORD)dwOffset;
                memcpy((BYTE*)(((BYTE*)ptd) + dwOffset), pwszDefDriver, cbDeviceName);
                dwOffset += cbDeviceName;

                ptd->tdPortNameOffset = (WORD)dwOffset;
                memcpy((BYTE*)(((BYTE*)ptd) + dwOffset), pwszPort, cbOutputName);
                dwOffset += cbOutputName;

                ptd->tdExtDevmodeOffset = (WORD)dwOffset;
                memcpy((BYTE*)(((BYTE*)ptd) + dwOffset), pdevMode, cbDevModeSize);
                dwOffset += cbDevModeSize;

                ASSERT(dwOffset == cbDVTargetSize);
            }
            else hr = E_OUTOFMEMORY;

         // We're done with the devmode...
            DsoMemFree(pdevMode);
        }
        else hr = E_WIN32_LASTERROR;

        SAFE_FREESTRING(pwszDefPort);
        SAFE_FREESTRING(pwszDefDriver);
        SAFE_FREESTRING(pwszDefProcessor);
        ClosePrinter(hPrint);
    }
    else hr = E_WIN32_LASTERROR;

 // If we were successful in getting TARGETDEVICE struct, provide the page range
 // for the print job and ask docobj server to print it...
    if (SUCCEEDED(hr))
    {
        PAGESET *ppgset;
        DWORD cbPgRngSize = sizeof(PAGESET) + sizeof(PAGERANGE);
        LONG cPages, cLastPage;
        DWORD grfPrintFlags;

     // Setup the page range to print...
        if ((ppgset = (PAGESET*)CoTaskMemAlloc(cbPgRngSize)) != NULL)
        {
            ppgset->cbStruct = cbPgRngSize;
            ppgset->cPageRange   = 1;
            ppgset->fOddPages    = TRUE;
            ppgset->fEvenPages   = TRUE;
            ppgset->cPageRange   = 1;
            ppgset->rgPages[0].nFromPage = ((nFrom) ? nFrom : 1);
            ppgset->rgPages[0].nToPage   = ((nTo) ? nTo : PAGESET_TOLASTPAGE);

         // Give indication we are waiting (on the print)...
            HCURSOR hCur = SetCursor(LoadCursor(NULL, IDC_WAIT));

            SEH_TRY

        // Setup the initial page number (optional)...
            print->SetInitialPageNum(ppgset->rgPages[0].nFromPage);

            grfPrintFlags = (PRINTFLAG_MAYBOTHERUSER | PRINTFLAG_RECOMPOSETODEVICE);
            if (fPromptUser) grfPrintFlags |= PRINTFLAG_PROMPTUSER;
            if (pwszOutput)  grfPrintFlags |= PRINTFLAG_PRINTTOFILE;

         // Now ask server to print it using settings passed...
            hr = print->Print(grfPrintFlags, &ptd, &ppgset, NULL, (IContinueCallback*)&m_xContinueCallback, 
                    ppgset->rgPages[0].nFromPage, &cPages, &cLastPage);

            SEH_EXCEPT(hr)

            SetCursor(hCur);

            if (ppgset)
                CoTaskMemFree(ppgset);
        }
        else hr = E_OUTOFMEMORY;
    }

 // We are done...
    if (ptd) CoTaskMemFree(ptd);
    print->Release();
    return hr;
}


////////////////////////////////////////////////////////////////////////
// CDsoDocObject::StartPrintPreview
//
//  Ask embedded object to go into print preview (if supportted).
//
STDMETHODIMP CDsoDocObject::StartPrintPreview()
{
    HRESULT hr;
    IOleInplacePrintPreview *prev;
    HCURSOR hCur;

    ODS("CDsoDocObject::StartPrintPreview\n");
    CHECK_NULL_RETURN(m_pole, E_UNEXPECTED);

 // No need to do anything if already in preview...
    if (InPrintPreview()) return S_FALSE;

 // Otherwise, ask document server if it supports preview...
    hr = m_pole->QueryInterface(IID_IOleInplacePrintPreview, (void**)&prev);
    if (SUCCEEDED(hr))
    {
     // Tell user we waiting (switch to preview can be slow for very large docs)...
        hCur = SetCursor(LoadCursor(NULL, IDC_WAIT));

     // If it does, make sure it can go into preview mode...
        hr = prev->QueryStatus();
        if (SUCCEEDED(hr))
        {
            SEH_TRY

            if (m_hwndCtl) // Notify the control that preview started...
                SendMessage(m_hwndCtl, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_INTERACTIVE, (LPARAM)FALSE);

         // We will allow application to bother user and switch printers...
            hr = prev->StartPrintPreview(
                (PREVIEWFLAG_MAYBOTHERUSER | PREVIEWFLAG_PROMPTUSER | PREVIEWFLAG_USERMAYCHANGEPRINTER),
                NULL, (IOlePreviewCallback*)&m_xPreviewCallback, 1);

            SEH_EXCEPT(hr)

         // If the call succeeds, we keep hold of interface to close preview later
            if (SUCCEEDED(hr)) 
			{ 
				SAFE_SET_INTERFACE(m_pprtprv, prev);
			}
			else
			{ // Otherwise, notify the control that preview failed...
				if (m_hwndCtl) 
					PostMessage(m_hwndCtl, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_INTERACTIVE, (LPARAM)TRUE);
			}
        }

        SetCursor(hCur);
        prev->Release();
    }
    return hr;
}

////////////////////////////////////////////////////////////////////////
// CDsoDocObject::ExitPrintPreview
//
//  Drop out of print preview and restore items as needed.
//
STDMETHODIMP CDsoDocObject::ExitPrintPreview(BOOL fForceExit)
{
    TRACE1("CDsoDocObject::ExitPrintPreview(fForceExit=%d)\n", (DWORD)fForceExit);

 // If the user closes the app or otherwise terminates the preview, we need
 // to notify the ActiveDocument server to leave preview mode...
	try{
		if (m_pprtprv)
		{
		   if (fForceExit) // Tell docobj we want to end preview...
			{
 					HRESULT hr = m_pprtprv->EndPrintPreview (TRUE);
					ASSERT(SUCCEEDED(hr));
 
			}
		   if (m_hwndCtl) // Notify the control that preview ended...
			   PostMessage(m_hwndCtl, DSO_WM_ASYNCH_STATECHANGE, DSO_STATE_INTERACTIVE, (LPARAM)TRUE);

		 }
	}catch(...){
	}
 // Free our reference to preview interface...
    SAFE_RELEASE_INTERFACE(m_pprtprv);
    return S_OK;
}


STDMETHODIMP CDsoFramerControl::get_GetApplication(IDispatch** ppdisp)
{
	IDispatch *pActiveDocument;
	this->get_ActiveDocument(&pActiveDocument);
	//DISPID dispid;
	LPOLESTR rgszNames =L"Application";
	//DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};
	VARIANT vResult;
	HRESULT hr;
	if (pActiveDocument){
		hr = DsoDispatchInvoke(pActiveDocument, rgszNames,0, DISPATCH_PROPERTYGET, 0, NULL,&vResult);
		*ppdisp = (vResult.pdispVal);
		vResult.pdispVal->AddRef();
	}
	return ProvideErrorInfo(hr);
}

HRESULT CDsoFramerControl::SetCurrUserName(BSTR strCurrUserName, VARIANT_BOOL* pbool)
{
	char * strCurName = NULL;
	LPWSTR  strwName;
	if ((strCurrUserName) && (SysStringLen(strCurrUserName) > 0)){
		strwName = SysAllocString(strCurrUserName);
		strCurName = DsoConvertToMBCS(strwName);
	}	
	if(!strCurName){
		*pbool = FALSE;
		return S_OK;
	}
	IDispatch * lDisp;
    get_ActiveDocument(&lDisp);
	if(!lDisp){
		return S_OK;
	}
	
	try{
		switch(m_nOriginalFileType){
		case FILE_TYPE_WORD:
			{
				
				CComQIPtr<MSWord::_Document> spDoc(lDisp);
				if(!spDoc)
					break;
				CComPtr<MSWord::_Application> spApp(spDoc->GetApplication());				
				spApp->put_UserName(A2BSTR(strCurName));
				//					spApp->put_PrintPreview(VARIANT_TRUE);
				spApp.Release();
				spDoc.Release();
				
			}	
			break;
		case FILE_TYPE_EXCEL:
			{	
				
				
			}
			break;
		case FILE_TYPE_PPT:
		case FILE_TYPE_PDF:
		case FILE_TYPE_UNK:
		default:
			break;
		}
	}catch(...){
		
	}
	
	
	
	*pbool = TRUE;
	DsoMemFree((void*)(strCurName));
	return S_OK;
}

HRESULT CDsoFramerControl::SetTrackRevisions( long vbool, VARIANT_BOOL* pbool)
{
	IDispatch * lDisp;
    get_ActiveDocument(&lDisp);
	if(!lDisp){
		*pbool = FALSE;
		return S_OK;
	}
	// 	COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
	try{
		switch(m_nOriginalFileType){
		case FILE_TYPE_WORD:
			{	
				
				CComQIPtr<MSWord::_Document> spDoc(lDisp);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -