invoke ???



  • Jochen Kalmbach schrieb:

    dEUs schrieb:

    Ich füge das COM-Objekt als Referenz hinzu und benutze das ganze dann ganz normal wie jeden anderen Typ auch. Stichwort: Interop

    Und was hat das mit "Late-Binding" zu tun???

    Jaja, habs ja auch grad gemerkt (siehe mein edit) 🤡



  • Sorry ! 😕 Ich blick immer noch nicht richtig durch.

    Jochen Kalmbach schrieb:

    Du musst AFAIK zuerst das IDispathc-Interface von "ParagraphFormat" holen und dann dort das "Alignment" Property setzen (aber nicht auf einen String sondern auf eine Zahl).

    Ich habe folgendes unter Microsoft Word im OleView gefunden:

    pdispinterface _ParagraphFormat
    

    darunter
    methods: Alignment :

    [id(0x00000065), proput , helpcontext(0x09530065)]
               void Alignment([in] WdParagraphAlignment rhs);
    
    typedef enum {
            wdAlignParagraphLeft = 0,
            wdAlignParagraphCenter = 1,
            wdAlignParagraphRight = 2,
            wdAlignParagraphJustify = 3,
            wdAlignParagraphDistribute = 4,
            wdAlignParagraphJustifyMed = 5,
            wdAlignParagraphJustifyHi = 7,
            wdAlignParagraphJustifyLow = 8,
            wdAlignParagraphThaiJustify = 9
        } WdParagraphAlignment;
    

    Wenn Du sagst IDispatch-inteface holen verstehe ich folgendes:

    LPDISPATCH pdispFormat; 
    
    		::CreateObject(OLESTR("_ParagraphFormat"), &pdispFormat);
    

    Dabei erstelle ich doch eine neues COM-SchnittstellenObjekt.
    Andererseits denke ich doch , dass du über WordBasic Word steuern möchtest

    weiter müsste ich dann mit invoke die Methode Alignment (DISPATCH_METHOD)aufrufen?
    und dann die Parameter setzen (DISPATCH_PROPERTYPUT) WdParagraphAlignment=0 (für left)

    Irgendwie denke ich z Zt völlig daneben und liege wahrscheinlich auch völlig falsch.

    PS Ich habe dazu in einem Buch ein Kapitel über Com und automatisierung gelesen. Danach war ich reichlich benebelt 😞



  • Mit meinem Satz habe ich gemeint:
    - via Invoke mit PROPERY_GET die Methode "ParagraphFormat" aufrufen; dann bekommst Du ein IDispatch-Interface zurück, welches Du bei dem *nächsten* Aufruf von Invoke verwendest (hier hast Du ja "pdispWord" verwendet)
    - Jetzt mit dem zurückgegebenen IDispatch-Interfave wieder via Invoke und PROPERTY_PUT mit dem Namen "Alignment" z.B. den Wert 2 (wdAlignParagraphRight) aufrufen.



  • Sei mir nicht böse aber ich sehe nicht wo ich ein IDispatch-Interface
    über Invoke zurückbekomme.

    /* 
     * Invoke 
     * 
     * Purpose: 
     *  Invokes a property accessor function or method of an automation object. Uses Unicode with OLE. 
     * 
     * Parameters: 
     *  pdisp         IDispatch* of automation object. 
     *  wFlags        Specfies if property is to be accessed or method to be invoked. 
     *                Can hold DISPATCH_PROPERTYGET, DISPATCH_PROPERTYPUT, DISPATCH_METHOD, 
     *                DISPATCH_PROPERTYPUTREF or DISPATCH_PROPERTYGET|DISPATCH_METHOD.    
     *  pvRet         NULL if caller excepts no result. Otherwise returns result. 
     *  pexcepinfo    Returns exception info if DISP_E_EXCEPTION is returned. Can be NULL if 
     *                caller is not interested in exception information.  
     *  pnArgErr      If return is DISP_E_TYPEMISMATCH, this returns the index (in reverse 
     *                order) of argument with incorrect type. Can be NULL if caller is not interested 
     *                in this information.  
     *  pszName       Name of property or method. 
     *  pszFmt        Format string that describes the variable list of parameters that  
     *                follows. The format string can contain the follwoing characters. 
     *                & = mark the following format character as VT_BYREF  
     *                b = VT_BOOL 
     *                i = VT_I2 
     *                I = VT_I4 
     *                r = VT_R2 
     *                R = VT_R4 
     *                c = VT_CY  
     *                s = VT_BSTR (far string pointer can be passed, BSTR will be allocated by this function). 
     *                e = VT_ERROR 
     *                d = VT_DATE 
     *                v = VT_VARIANT. Use this to pass data types that are not described in  
     *                                the format string. (For example SafeArrays). 
     *                D = VT_DISPATCH 
     *                U = VT_UNKNOWN 
     *     
     *  ...           Arguments of the property or method. Arguments are described by pszFmt.   
     *                ****FAR POINTERS MUST BE PASSED FOR POINTER ARGUMENTS in Win16.**** 
     * Return Value: 
     *  HRESULT indicating success or failure         
     *
    

    Rückgabewert von Invoke ist HRESULT
    und der einzige Parameter der einen Wert zurückgibt ist pvRet
    der ist jedoch vom Typ VARIANT .

    Tut mir ja leid aber ich sehe das einfach nicht .
    (im Voraus: Danke für Deine Geduld 😉 )



  • Na, vermutlich in

    *  pvRet         NULL if caller excepts no result. Otherwise returns result.
    

    Simples Beispiel:

    LPDISPATCH pdispParagraphFormat;
      HRESULT hrRes;
      VARIANT vRet;
      VariantInit(&vRet);
      hrRes = Invoke(pdispWord, DISPATCH_PROPERTYGET, &vRet, NULL, NULL, 
        OLESTR("ParagraphFormat"), NULL);
      if FAILED(hrRes)
        return hrRes;
      if (V_VT(&vRet) != VT_DISPATCH)
        return E_FAIL;
      *ppdispRoot = V_DISPATCH(&vRet);
      if ((*ppdispRoot) == NULL)
        return E_FAIL;
      pdispParagraphFormat->AddRef();  // keep a reference to the object
      VariantClear(&vRet);
    
      // Now use this object to do the Invoke for "Alignment"
    


  • Danke für den Source. Ich glaub langsam komme ich dahinter.

    Jedoch habe ich doch noch ein paar Fragen und Probleme

    VARIANT vRet;
    VariantInit(&vRet); 
    hrRes = Invoke(pdispWord, DISPATCH_PROPERTYGET, &vRet, NULL, NULL,OLESTR("ParagraphFormat"), NULL);
    

    Wenn ich es so ausführe bekomme ich nichts zurück
    vRet={VT_EMPTY}
    Wahrscheinlich ist "ParagraphFormat" bzw "_ParagraphFormat" nicht korrekt.
    Habe beides ausprobiert.

    Wenn ich das richtig verstehe muss ich doch

    LPDISPATCH *ppdispRoot;
    

    deklarieren?

    Nachhilfe in c++ 😉
    Wie mmuss ich

    *ppdispRoot = V_DISPATCH(&vRet);
      if ((*ppdispRoot) == NULL)
        return E_FAIL;
      pdispParagraphFormat->AddRef();  // keep a reference to the object
      VariantClear(&vRet)
    

    verstehen?



  • Hab den Source von einem bestehenden Projekt zusammenkopiert... musst Dur *ppdispRoot durch pdispParagraphFormat ersetzen:

    pdispParagraphFormat = V_DISPATCH(&vRet);
      if (pdispParagraphFormat == NULL)
        return E_FAIL;
      pdispParagraphFormat->AddRef();  // keep a reference to the object
      VariantClear(&vRet)
    

    Hab es nicht wirklich mit Word getestet...



  • Danke für Deine Hilfe
    Ich denke ich blicke jetz ein wenig mehr durch.

    Nur habe ich zZt keinen Schimmer warum Invoke kein entsprechendes Ergebnis liefert.
    ICh kann mir nur vorstellen, dass ich die falschen Argumente übergebe.

    Aber es ist doch richtig , dass ich die Bezeichnungen der Interfaces übergeben
    muss. Ich habe jetzt verschiedene Nezeichnungen für entsprechende Interfaces
    übergeben , jedoch immmer mit dem gleichen Ergebnis.

    Zum Verständnis:
    Ich suche unter type libraries nach

    ->Microsoft Word 11.0 Object library <8.3>
    

    darunter finde ich diverse Interfaces

    ->_Application
             _ParagraphFormat
             _Fonts
             Range
             Character
    etc
    

    und ich denke für diese muß ich doch ein IDspatch erhalten um dann
    auf die entsprechendem Methoden zugreifen zu können

    Oder nennen sich diese Schnittstellen bzgl VBA ganz anders ?



  • Du musst Methoden oder Properties aufrufen. Wie die Klasse heisst die Du da zurückbekommst oder verwendest spielt dabei *keine* Rolle!
    Und Werte doch einfach den HRESULT-Rückgabewert aus, dann kommst Du am schnellsten drauf was schief geht...



  • das ist es ja
    hrRes = 0x80020006 unbekannter Name.
    vRet = {VT_EMPTY}

    jedesmal (!seufz)

    Was ist mit pexcepinfo oder pnArgErr bei Invoke
    liefern diese Parameter mirt vielleich Infos?



  • Heureka , ich hab's 😃

    vergiss es mit IDispatch holen etc.

    Ich hatte die ganze Zeit Visual Basic und Wordbasic gleichgesetzt.

    es reicht einfach dei Wordbasic Methode aufzurufen : 💡 (auf Englisch)

    Invoke(pdispWord, DISPATCH_METHOD, NULL, NULL, NULL,   
    			OLESTR("RightPara"), NULL);
    

    eine Auflistung der Wordbasic-Methoden und entsprechenden VBA-Methoden
    habe ich hier gefunden:

    http://msdn.microsoft.com/library/en-us/vbawd11/html/wohowWordBasicEquivalentsA_HV05214104.asp?frame=true

    Trotzdem vielen Dank für die Hilfe . Es hat mir doch einige tiefere
    Einblicke in dieses Thema ermöglicht.

    🙂


Anmelden zum Antworten