0

コンソール アプリから Microsoft Word で特定のページ範囲を印刷しようとすると、奇妙な問題が発生し、奇妙な結果が表示されます。これは、ページ範囲を指定するときに誤って実行したものであると想定しています。

ページ範囲を印刷してWord文書の合計ページ数を取得すると、特定の範囲を印刷するとこの数が変化するようです。もう 1 つの奇妙な点は、これがデバッグ モードでは機能するが、リリース モードでは機能しないことです。

元。Word 文書は 2 ページで構成されます。 ページ 1-1 を印刷します。ページ数を取得すると 2 が返されます

ページを印刷 2-2 ページ数を取得すると 1 が返される

ページの範囲を印刷するためのコードは次のとおりです。

int CWordComm::PrintAndCloseActiveDocument(int iNumOfCopies, short nTray, int pageNumber)
{
    // Convenient values declared as ColeVariants.
    COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);

    _Document oActiveDoc = m_oWord.GetActiveDocument();

    if(!this->m_szOutputFilename.IsEmpty())
    {
        //If we are outputting the document to a file then we need to print a single page at a time
        //This is because of a limitation on the ikonprinter/requisition printer side that can only handle
        //one page at a time
        // Print out to file
        CString szCurrentPage, szPrintRange;
        szCurrentPage.Format("%d", pageNumber);
        szPrintRange.Format("%d", PRINT_FROM_TO);  //PRINT_FROM_TO is #define PRINT_FROM_TO 3

        COleVariant printRange(szPrintRange, VT_BSTR);
        COleVariant currentPage(szCurrentPage, VT_BSTR);

        sprintf(m_szLogMessage, "Printing page %d of requisition", pageNumber);
        LogMessage(m_szLogMessage);

        oActiveDoc.PrintOut(covFalse,          // Background.
            covOptional,           // Append.
            printRange,             // Range.
            COleVariant(szFileName,VT_BSTR),  // OutputFileName.
            currentPage,           // From.
            currentPage,           // To.
            covOptional,           // Item.
            COleVariant((long)1),  // Copies.
            covOptional,           // Pages.
            covOptional,           // PageType.
            covTrue,               // PrintToFile.
            covOptional,           // Collate.
            covOptional,           // ActivePrinterMacGX.
            covOptional            // ManualDuplexPrint.
            );
    }
    else
    {
        // Print out to file
        oActiveDoc.PrintOut(covFalse,          // Background.
            covOptional,           // Append.
            covOptional,           // Range.
            COleVariant(szFileName,VT_BSTR),  // OutputFileName.
            covOptional,           // From.
            covOptional,           // To.
            covOptional,           // Item.
            COleVariant((long)1),  // Copies.
            covOptional,           // Pages.
            covOptional,           // PageType.
            covTrue,               // PrintToFile.
            covOptional,           // Collate.
            covOptional,           // ActivePrinterMacGX.
            covOptional            // ManualDuplexPrint.
            );
    }

    //Get the number of pages in the word document
    iNumPages=GetActiveDocPageCount();

    //omitted code
}

Get pages メソッド

int CWordComm::GetActiveDocPageCount()
{
    try
    {
        _Document oActiveDoc; 
        //Get the Active Document
        oActiveDoc = m_oWord.GetActiveDocument();

        //Get the BuiltinDocumentProperties collection for the 
        //document
        LPDISPATCH lpdispProps;
        lpdispProps = oActiveDoc.GetBuiltInDocumentProperties();

        //Get the requested Item from the BuiltinDocumentProperties 
        //collection
        //NOTE:  The DISPID of the "Item" property of a 
        //       DocumentProperties object is 0x0
        VARIANT vResult;
        DISPPARAMS dpItem;
        VARIANT vArgs[1];
        vArgs[0].vt = VT_BSTR;

        //property name for the number of pages in the active document
        _bstr_t btVal("Number of pages");

        vArgs[0].bstrVal = btVal;
        dpItem.cArgs=1;
        dpItem.cNamedArgs=0;
        dpItem.rgvarg = vArgs;
        HRESULT hr = lpdispProps->Invoke(0x0, IID_NULL, 
            LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, 
            &dpItem, &vResult, NULL, NULL);

        //Get the Value property of the BuiltinDocumentProperty
        //NOTE:  The DISPID of the "Value" property of a 
        //       DocumentProperty object is 0x0
        DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0};
        LPDISPATCH lpdispProp;
        lpdispProp = vResult.pdispVal;
        hr = lpdispProp->Invoke(0x0, IID_NULL, LOCALE_USER_DEFAULT, 
            DISPATCH_PROPERTYGET, &dpNoArgs, &vResult, 
            NULL, NULL);

        CString sPropValue = "";
        switch (vResult.vt)
        {
        case VT_BSTR:
            sPropValue = vResult.bstrVal;
            break;
        case VT_I4:
            sPropValue.Format("%d",vResult.lVal);
            break;
        case VT_DATE:
            {
                COleDateTime dt (vResult);
                sPropValue = dt.Format(0, LANG_USER_DEFAULT);
                break;
            }
        default:
//          sPropValue = "<Information for the property you selected is not available>";
            sPropValue = "-4";
            break;
        }

        //Release the no longer needed IDispatch pointers
        lpdispProp->Release();
        lpdispProps->Release();

        return atoi(sPropValue);

    }
    catch(...)
    {
        return FUNC_ERROR;
    }
}

質問

ここで私が間違っていることは明らかですか?ある範囲のページを印刷したい場合、別の方法で Word とやり取りする必要がありますか?

4

2 に答える 2

0

デバッグ モードで正常に動作する場合は、値 (ページ数、印刷中のページなど) をテキスト ファイルに書き込むことをお勧めします。デバッグ ログ出力とリリース ログ出力を比較します。ここにあなたを助けるかもしれないリンクがあります。リンクは C++ ではありませんが、正しい方法で案内してくれるかもしれません。

于 2013-07-10T14:51:28.567 に答える