示例#1
0
文件: Reference.cpp 项目: jbroll/tcom
HRESULT
Reference::invoke (MEMBERID memberid,
                   WORD dispatchFlags,
                   const TypedArguments &arguments,
                   VARIANT *pResult)
{
    if (m_pInterface != 0 && !m_pInterface->dispatchOnly()) {
        EXCEPINFO excepInfo;
        memset(&excepInfo, 0, sizeof(excepInfo));
        unsigned argErr;

        // Invoke through virtual function table.
        ITypeInfo *pTypeInfo = interfaceDesc()->typeInfo();
        HRESULT hr = pTypeInfo->Invoke(
            m_pUnknown,
            memberid,
            dispatchFlags,
            arguments.dispParams(),
            pResult,
            &excepInfo,
            &argErr);

        if (SUCCEEDED(hr)) {
            return hr;
        }

        if (hr == DISP_E_EXCEPTION) {
            throwDispatchException(excepInfo);
        } else if (hr == DISP_E_TYPEMISMATCH || hr == DISP_E_PARAMNOTFOUND) {
            throw InvokeException(hr, arguments.dispParams()->cArgs - argErr);
        }
    }

    return invokeDispatch(memberid, dispatchFlags, arguments, pResult);
}
示例#2
0
Error WordViewer::closeLastViewedDocument()
{
   Error errorHR = Success();
   HRESULT hr = S_OK;

   if (idispWord_ == NULL)
      return Success();

   // Find the open document corresponding to the one we last rendered. If we
   // find it, close it; if we can't find it, do nothing.
   IDispatch* idispDoc = NULL;
   errorHR = getDocumentByPath(docPath_, &idispDoc);
   if (errorHR)
      return errorHR;
   if (idispDoc == NULL)
      return Success();

   errorHR = getDocumentPosition(idispDoc, &docScrollX_, &docScrollY_);
   if (errorHR)
      LOG_ERROR(errorHR);

   VERIFY_HRESULT(invokeDispatch(DISPATCH_METHOD, NULL, idispDoc, L"Close", 0));

LErrExit:
   return errorHR;
}
示例#3
0
Error WordViewer::setDocumentPosition(IDispatch* idispDoc, int xPos, int yPos)
{
   Error errorHR = Success();
   HRESULT hr = S_OK;

   IDispatch* idispWindow = NULL;
   VARIANT varPos;
   varPos.vt = VT_INT;

   VERIFY_HRESULT(getIDispatchProp(idispDoc, L"ActiveWindow", &idispWindow));
   varPos.intVal = xPos;
   VERIFY_HRESULT(invokeDispatch(DISPATCH_PROPERTYPUT, NULL, idispWindow,
                                 L"HorizontalPercentScrolled", 1, varPos));
   varPos.intVal = yPos;
   VERIFY_HRESULT(invokeDispatch(DISPATCH_PROPERTYPUT, NULL, idispWindow,
                                 L"VerticalPercentScrolled", 1, varPos));
LErrExit:
   return errorHR;
}
示例#4
0
Error WordViewer::showWord()
{
   Error errorHR = Success();
   HRESULT hr = S_OK;

   VARIANT visible;
   visible.vt = VT_BOOL;
   visible.boolVal = true;
   VERIFY_HRESULT(invokeDispatch(DISPATCH_PROPERTYPUT, NULL, idispWord_,
                                 L"Visible", 1, visible));
LErrExit:
   return errorHR;
}
示例#5
0
// Given a path, searches for the document in the Documents collection that
// has the path given. The out parameter is set to that document's IDispatch
// pointer, or NULL if no document with the path could be found.
Error WordViewer::getDocumentByPath(QString& path, IDispatch** pidispDoc)
{
   Error errorHR = Success();
   HRESULT hr = S_OK;

   IDispatch* idispDocs = NULL;
   IDispatch* idispDoc = NULL;
   VARIANT varDocIdx;
   VARIANT varResult;
   int docCount = 0;

   *pidispDoc = NULL;

   VERIFY_HRESULT(getIDispatchProp(idispWord_, L"Documents", &idispDocs));
   VERIFY_HRESULT(getIntProp(idispDocs, L"Count", &docCount));

   varDocIdx.vt = VT_INT;
   for (int i = 1; i <= docCount; i++)
   {
      VariantInit(&varResult);
      varDocIdx.intVal = i;
      VERIFY_HRESULT(invokeDispatch(DISPATCH_METHOD, &varResult, idispDocs,
                                    L"Item", 1, varDocIdx));
      idispDoc = varResult.pdispVal;
      VERIFY_HRESULT(invokeDispatch(DISPATCH_PROPERTYGET, &varResult, idispDoc,
                                    L"FullName", 0));
      if (path.toStdWString() == varResult.bstrVal)
      {
         *pidispDoc = idispDoc;
         break;
      }
   }

LErrExit:
   return errorHR;
}
示例#6
0
Error WordViewer::showDocument(QString& path)
{
   Error errorHR = Success();
   HRESULT hr = S_OK;

   // Allow Word to become the foreground window. CoAllowSetForegroundWindow
   // would be preferable here, since we'd be able to restrict activation to
   // only the process we started, but it is not exposed by MinGW headers.
   // Note that AllowSetForegroundWindow already limits activation to processes
   // initiated by the foreground process, and self-expires on user input.
   AllowSetForegroundWindow(ASFW_ANY);

   // If we have an active IDispatch pointer to Word, check to see whether
   // it has been closed
   if (idispWord_ != NULL)
   {
      // Test the interface by looking up a known DISPID
      const WCHAR* wstrQuit = L"Quit";
      DISPID dispid;
      hr = idispWord_->GetIDsOfNames(IID_NULL, const_cast<WCHAR**>(&wstrQuit),
                                     1, LOCALE_USER_DEFAULT, &dispid);

      // If the lookup fails, release this IDispatch pointer--it's stale.
      // We'll CoCreate a new instance of Word below.
      if (FAILED(hr) &&
          SCODE_CODE(hr) == RPC_S_SERVER_UNAVAILABLE)
      {
         idispWord_->Release();
         idispWord_ = NULL;
      }
   }

   // Get an IDispatch for the Word Application root object
   if (idispWord_ == NULL)
   {
      CLSID clsid;
      LPCOLESTR progId = L"Word.Application";
      CoInitialize(NULL);
      VERIFY_HRESULT(CLSIDFromProgID(progId, &clsid));
      VERIFY_HRESULT(CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER,
                                      IID_IDispatch,
                                      reinterpret_cast<void**>(&idispWord_)));
      idispWord_->AddRef();
   }

   // Make Word visible
   errorHR = showWord();
   if (errorHR)
      return errorHR;

   IDispatch* idispDocs;
   IDispatch* idispDoc;
   VERIFY_HRESULT(getIDispatchProp(idispWord_, L"Documents", &idispDocs));

   // Open the documenet
   path = path.replace(QChar(L'/'), QChar(L'\\'));
   errorHR = openDocument(path, idispDocs, &idispDoc);
   if (errorHR)
      return errorHR;
   if (docPath_ == path)
   {
      // Reopening the last-opened doc: apply the scroll position if we have
      // one cached
      if (docScrollX_ > 0 || docScrollY_ > 0)
         setDocumentPosition(idispDoc, docScrollX_, docScrollY_);
   }
   else
   {
      // Opening a different doc: forget scroll position and save the doc name
      docScrollX_ = 0;
      docScrollY_ = 0;
      docPath_ = path;
   }

   // Bring Word to the foreground
   VERIFY_HRESULT(invokeDispatch(DISPATCH_METHOD, NULL, idispWord_,
                                 L"Activate", 0));

LErrExit:
   return errorHR;
}