COM-Bibliothek: Word-Dokument öffnen (IDispatch-Interface)
-
Hallo,
ich möchte ein bestehendes Word-Dokument öffnen und reinschreiben.
Ein neues Dokument zu erstellen und dort reinzuschreiben, klappt auch soweit. Möchte ich jedoch ein vorhandenes Dokument öffnen, kann ich leider nicht reinschreiben. Mir sind die Funktionen, die dafür nötig sind, nicht ganz klar.
Mein Code zur Initialisierung der Word-Komponente.
//Instanz von Word gestartet, Pointer pAppInt zum IUnknown-Interface von Word (Zugriff auf Funktionen möglich) m_officeInstance = ::CoCreateInstance(clsid, NULL, CLSCTX_SERVER, IID_IUnknown, (void**) &m_punknownapp); //IUnknown-Pointer punknownapp wird auf Dispatch-Pointer pdispapp umgelegt m_officeInstance = m_punknownapp->QueryInterface(IID_IDispatch, (void**)&m_pdispapp); // --- Zugriff auf das Application Objekt herstellen --- //IDispatch* für Dokumenteneigenschaften m_szFunction = OLESTR("Documents"); //Mappen der Argumente des Application Objekts für Invoke m_officeInstance = m_pdispapp->GetIDsOfNames(IID_NULL, &m_szFunction, 1, LOCALE_USER_DEFAULT, &m_dispid_Docs); //Zugriff zu den Methoden herstellen m_officeInstance = m_pdispapp->Invoke(m_dispid_Docs, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dpNoArgs, &m_vResult, NULL, NULL); //Dokumenteneigenschaften von Invoke über vResult übernehmen m_pdispdocs = m_vResult.pdispVal;Nun versuche ich, auf ein bestehendes Dokument mit "Open" zuzugreifen und mit "TypeText" was reinzuschreiben. Sichern möchte ich es mit "SaveAs", was aber leider nicht klappt.
Hier der Code dazu:
//--- lokale Variablen --- QString eigeneDateien; QString fileNameLoad; VARIANT vFileName; //DISPPARAMS dpFileOpen; DISPPARAMS dpNoArgs = {NULL, NULL, 0, 0}; BSTR bstr_FileName; //testweise mal rausgenommen //BSTR bstr_PassWord; //nur für Schreibtest BSTR bstr_Eingabe; VARIANT vArgsTypeText[1]; DISPPARAMS dpTypeText; BSTR bstr_EmptyString; //TO DO: noch buggy, stürzt ab nach geöffnetem Dokument //eigene Dateien: Dateipfad des aktuellen Benutzers eigeneDateien = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); fileNameLoad = QFileDialog::getOpenFileName(0, tr("Dateiname wählen"), eigeneDateien, tr("Dokumente (*.doc)")); if (fileNameLoad.length() > 0) { bstr_FileName = RSQStringToBSTR(fileNameLoad); vFileName.vt = VT_BSTR; vFileName.bstrVal = ::SysAllocString(bstr_FileName); DISPPARAMS dpFileOpen = {&vFileName, NULL, 1, 0}; //dpFileOpen.rgvarg = vFileName; //dpFileOpen.cNamedArgs = 0; //--- Zugriff auf Document Objekt herstellen --- m_szFunction = OLESTR("Open"); //Mappen der Argumente des Dokumenten Objekts für Invoke m_officeInstance = m_pdispdocs->GetIDsOfNames(IID_NULL, &m_szFunction, 1, LOCALE_USER_DEFAULT, &m_dispid_DocsAdd); //Zugriff zu den Methoden herstellen m_officeInstance = m_pdispdocs->Invoke(m_dispid_DocsAdd, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dpFileOpen, &m_vResult, NULL, NULL); m_pdispsel = m_vResult.pdispVal; //Dokumenteneigenschaften m_szFunction = OLESTR("Item"); m_officeInstance = m_pdispdocs->GetIDsOfNames(IID_NULL, &m_szFunction, 1, LOCALE_USER_DEFAULT, &m_dispid_Sel); m_officeInstance = m_pdispdocs->Invoke(m_dispid_Sel, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dpFileOpen, &m_vResult, NULL, NULL); //m_pdispactivedoc = m_vResult.pdispVal; //--- Zugriff auf Selection Objekt herstellen --- m_szFunction = OLESTR("Selection"); //Mappen der Argumente des Selection Objekts für Invoke m_officeInstance = m_pdispapp->GetIDsOfNames(IID_NULL, &m_szFunction, 1, LOCALE_USER_DEFAULT, &m_dispid_Sel); //Zugriff zu den Methoden herstellen m_officeInstance = m_pdispapp->Invoke(m_dispid_Sel, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dpFileOpen, &m_vResult, NULL, NULL); //Argumente von Invoke über m_vResult übernehmen //m_pdispactivedoc = m_vResult.pdispVal; //Aktives Dokument ansteuern m_szFunction = OLESTR("ActiveDocument"); m_officeInstance = m_pdispapp->GetIDsOfNames(IID_NULL, &m_szFunction, 1, LOCALE_USER_DEFAULT, &m_dispid_ActiveDoc); m_officeInstance = m_pdispapp->Invoke(m_dispid_ActiveDoc, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dpFileOpen, &m_vResult, NULL, NULL); m_pdispactivedoc = m_vResult.pdispVal; //--- Test: Schreiben ins geöffnete Dokument --- //DISP_IDs on TypeText und TypeParagraph, m_szFunction = OLESTR("TypeText"); m_officeInstance = m_pdispsel->GetIDsOfNames(IID_NULL, &m_szFunction, 1, LOCALE_USER_DEFAULT, &m_dispid_TypeText); m_szFunction = OLESTR("TypeParagraph"); m_officeInstance = m_pdispsel->GetIDsOfNames(IID_NULL, &m_szFunction, 1, LOCALE_USER_DEFAULT, &m_dispid_TextPara); //TypeTextMethode hat ein Argument - mit VARIANT-Datentyp festlegen bstr_Eingabe = SysAllocString(OLESTR("Dokument geladen")); vArgsTypeText[0].vt = VT_BSTR; vArgsTypeText[0].bstrVal = bstr_Eingabe; dpTypeText.cArgs = 1; dpTypeText.rgvarg = vArgsTypeText; dpTypeText.cNamedArgs = 0; bstr_EmptyString = ::SysAllocString(OLESTR("")); //Texteingabe m_officeInstance = m_pdispsel->Invoke(m_dispid_TypeText, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &dpTypeText, NULL, NULL, NULL); //--- Test Ende --- //DISPPARAMS erstellen, damit Word-Dokument erstellt werden kann VARIANT vArgsSaveAs[11]; DISPPARAMS dpSaveAs; VARIANT vFalse; dpSaveAs.cArgs = 11; dpSaveAs.cNamedArgs = 0; dpSaveAs.rgvarg = vArgsSaveAs; vFalse.vt = VT_BOOL; vFalse.boolVal = FALSE; //Testdoc //String-Conversion bstr_Eingabe = RSQStringToBSTR(fileNameLoad); //Dateiname vArgsSaveAs[10].vt = VT_BSTR; vArgsSaveAs[10].bstrVal = bstr_Eingabe; //Dateiformat vArgsSaveAs[9].vt = VT_I4; vArgsSaveAs[9].lVal = 0; //keine Kommentare vArgsSaveAs[8] = vFalse; //evtl. Passwort vArgsSaveAs[7].vt = VT_BSTR; vArgsSaveAs[7].bstrVal = bstr_EmptyString; //zu "Recent Files dazufügen" vArgsSaveAs[6].vt = VT_BOOL; vArgsSaveAs[6].boolVal = TRUE; vArgsSaveAs[5].vt = VT_BSTR; //Passwort schreiben vArgsSaveAs[5].bstrVal = bstr_EmptyString; //ReadOnly vArgsSaveAs[4] = vFalse; //TrueTypeFormats embedding vArgsSaveAs[3] = vFalse; //Picture Format vArgsSaveAs[2] = vFalse; //Save FormsData vArgsSaveAs[1] = vFalse; //Save as OCE-Letter vArgsSaveAs[0] = vFalse; m_szFunction = OLESTR("SaveAs"); //Dokument sichern m_officeInstance = m_pdispactivedoc->GetIDsOfNames(IID_NULL, &m_szFunction, 1, LOCALE_USER_DEFAULT, &m_dispid_SaveAs); m_officeInstance = m_pdispactivedoc->Invoke(m_dispid_SaveAs, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYGET, &dpSaveAs, &m_vResult, NULL, NULL);Für Hilfe wäre ich sehr dankbar, da ich leider auch kaum Dokumentation zur Automatisierung von Word finde, habe mich auch schon durchs MSDN gewühlt.
Gruß,
Tobias
-
Der Code wird etwas unübersichtlich bei Dir... verwende doch den Wrapper von MS, dann kannst Du fast 1-zu-1 vorhandene VB-Beispiele umsetzen...
Siehe: http://blog.kalmbachnet.de/?postid=63
-
Hallo,
vielen Dank für die Wrapper-Klasse, das war sehr hilfreich. Allerdings bekomme ich irgendwie Word noch nicht dazu, ein Dokument zu öffnen und testweise was reinzuschreiben. Word öffnet die Datei gar nicht, welche OLE-Funktion müßte ich noch aufrufen?
Hier noch mein Code dazu:
QString eigeneDateien; QString fileNameLoad; eigeneDateien = QDesktopServices::storageLocation(QDesktopServices::DocumentsLocation); fileNameLoad = QFileDialog::getOpenFileName(0, tr("Dateiname wählen"), eigeneDateien, tr("Dokumente (*.doc)")); BSTR bstr_fileNameLoad = RSQStringToBSTR(fileNameLoad); Invoke(pdispWord, DISPATCH_METHOD, NULL, NULL, NULL, OLESTR("Open"), TEXT("s"), bstr_fileNameLoad); Invoke(pdispWord, DISPATCH_METHOD, NULL, NULL, NULL, OLESTR("Insert"), TEXT("s"), (LPOLESTR)OLESTR("angefuegt")); Invoke(pdispWord, DISPATCH_METHOD, NULL, NULL, NULL, OLESTR("FileSaveAs"), TEXT("s"), bstr_fileNameLoad);Vielen Dank schon mal.
Gruß,
Tobias
-
Hallo,
habe es gelöst, es darf nur die Funktion "FileOpen" sein, weder Item noch anderes darf darauf angewendet werden. Damit funktioniert es.
@Jochen: Danke für den Link mit den Wrapperklassen, das ist sehr hilfreich.
Viele Grüße,
Tobias