Seite 2 von 2

Verfasst: Mo, 28. Jul 2008 15:20
von Dirk Jucknies
Hi Stevie,

entweder

oWord := CreateObject("Word.Application")
oWord := oWord:dynamicCast( ActiveXObject() )
...

oder

oWord := ActiveXObject():create( "Word.Application" )
...

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Mi, 17. Sep 2008 14:08
von stevie
Wenn ich Quit() so wie du befülle in einem Activex-Object, dann passiert bei mir gar nichts.
oWord := CreateObject("Word.Application")
IF Empty( oWord )
MsgBox( "Microsoft Word ist nicht installiert" )
ENDIF
oWord:=oWord:dynamicCast( ActiveXObject() )

// Setzen des code blocks für die "Quit" Nachricht
oWord:quit := {|| msgbox("Finished!"),lok:=.T. }
Die Meldung kommt nicht und die public Variable lok wird auch nicht verändert.

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Mi, 17. Sep 2008 14:57
von brandelh
Hi,

sieh mal unter \source\samples\activex\msword\... nach.
Dort habe ich eben feed.prg compiliert und aufgerufen.

Word geht auf, ersetzt, speichert und wieder zu.

Vorher schließen sie noch das Dokument !

Code: Alles auswählen

oDoc:close()
oWord:Quit()
oWord:destroy() // das ist wohl wieder Xbase++
Eventuell muss man das Dokument schließen, sonst hängt quit() in einer unsichtbaren Abfrage (wirklich speichern ? aber da ist doch noch ...) :wink:

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Mi, 17. Sep 2008 15:01
von brandelh
Ach ja,

Quit() ist nur eine Methode, kein Callback-codeblock !

siehe hierzu die Datei "VBAWD10.CHM"

(muss eventuell nachinstalliert werden ... VBA Hilfedatei...wie steht hier auch irgendwo.)

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Mi, 17. Sep 2008 16:02
von Tom
Hallo, Hubert.
Quit() ist nur eine Methode, kein Callback-codeblock !
Jedes ActiveXObjekt erbt von XbpWindow den Slot "Quit", der auch zugewiesen werden kann. Wenn man ein Word-Objekt erzeugt und den Quit-Callback belegt, erhält das Objekt in der iVar :EventMap ein Array, das (u.a.) für "QUIT" einen Eintrag enthält, in dem der Codeblock dann vorzufinden ist (Position 3). Allerdings offenbar ohne Wirkung. Das Objekt selbst hat KEINE Methode namens Quit(). Das hier erzeugt also keinen Laufzeitfehler:

Code: Alles auswählen

oWord := CreateObject("Word.Application")
oWord := oWord:dynamicCast(ActiveXObject())
oWord:Visible := .T.
oWord:Quit := {||msgbox('Word wurde beendet'),oWord:Destroy()}
Aber es passiert eben auch nichts beim Schließen. :?:

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Mi, 17. Sep 2008 16:53
von Tom
Wer lesen kann, ist klar im Vorteil. Aus der Doku zu XbpWindow:

Auf Windows-Plattformen wird das xbeP_Quit Ereignis nur dann erzeugt, wenn das Betriebssystem heruntergefahren wird und der laufende Prozeß vom Betriebssystem, nicht vom Anwender, beendet wird. Wenn ein Programm über den Task-Manager abgebrochen wird, entsteht ein xbeP_Close Ereignis.

Das CLOSE-Event kennen aber nur XbpDialog und XbpCrt.

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Mi, 17. Sep 2008 18:48
von brandelh
Tom hat geschrieben:Hallo, Hubert.
Quit() ist nur eine Methode, kein Callback-codeblock !
...
Jedes ActiveXObjekt erbt von XbpWindow den Slot "Quit", der auch zugewiesen werden kann.
Das Objekt selbst hat KEINE Methode namens Quit(). Das hier erzeugt also keinen Laufzeitfehler:
...
Aber es passiert eben auch nichts beim Schließen. :?:
Hallo Tom,

OK, der Callback auf Xbase++ Ebene mag bestehen, aber wie du in dem von mir zitierten Beispiel
sehen kannst wird Word nach dem Aufruf beendet.

Ich habe in der Worddokumentation nachgesehen, und dort gibt es die Methode .quit(xx) die Word beendet.
Es könnte natürlich auch sein, dass das oDlg:destroy() Word rausgeschossen hat, aber das glaube ich eher nicht,
da das Entfernen einer Referenz auf Word dieses selbst kaum abschießen dürfte.

Und die Frage war doch, wie man Word nach dem Ausdruck beenden könnte.
Dafür muß man die Methode quit aufrufen ...
//////////////////////////////////////////////////////////////////////
// FEED.PRG
//
// Copyright:
// Alaska Software, (c) 2002-2006. Alle Rechte vorbehalten.
//
...
// Erzeugen einer ActiveX-Komponente
oWord := CreateObject("Word.Application")
IF Empty( oWord )
MsgBox( "Microsoft Word ist nicht installiert" )
ENDIF
oWord:visible := .T.
...
// Schliessen des Dokuments und zerstoeren das
// ActiveX-Objektes.
oDoc:close()
oWord:Quit()
oWord:destroy()

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Do, 18. Sep 2008 9:59
von stevie
Irgendwann habe ich es erst geschafft, dass der Codeblock ausgeführt wurde, konnte es aber nicht mehr reproduzieren.
Egal, ob ich mit Taskmanager beendet, es mit quit() vom Programm beendet oder von Hand beendet habe.
Deswegen versuche ich nun das Ganze in einem Activexcontrol in die Anwendung einzubetten.
Weiß vielleicht jemand, was daran falsch sein könnte?

Code: Alles auswählen

oApp:=xbpdialog():new(SetAppWindow():drawingArea,,{0,0},getApp():drawingArea:currentsize())
oApp:title:="Word"
oApp:create()
oWord:=xbpActivexControl():new(oApp:drawingArea,,{10,10},{oApp:drawingArea:currentsize()[1]-40,oApp:drawingArea:currentsize()[2]-40})
oWord:visible:=.T.
oWord:CLSID:="{000209FF-0000-0000-C000-000000000046}"
oWord:create()
oApp:Show()
oWord:visible:=.T.
oWord:show()
Vielleicht ist die CLSID für Word ja ne andere?
Word.Application funzt auch nich.
Oder was anderes falsch?
Jedenfalls kann man nur das Fenster sehen und er meldet xbpactivexcontrol = couldn't create.

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Do, 18. Sep 2008 10:10
von Jan
Stevie,

ich misch mich da mal eben ein. Mich irritiert die Fehlermeldung bzw. die Aussage, daß Word.Application nicht funktioniert.

Zuerst würde ich das natürlich darauf schieben, daß Word garnicht installiert ist. Was ich jetzt aber mal nicht unterstelle.

Der nächste Punkt wäre: Welches Betriebssystem benutzt Du? Zumindest unter Vista habe ich das massive Problem gehabt, daß da die CLSID nicht ausreicht. Viele ActiveX-Elemente wollen auch noch eine :License haben. Ohne die gibt es ebenfalls die Fehlermeldung bei :create(). Ich weiß jetzt nicht, wie die von Word lautet, weil ich da nicht mit arbeite. Aber Du kannst die über den Formdesigner rausbekommen. Was aber nach meinen Erfahrungen unter Vista nicht funktioniert, da muß dann ein anderer Rechner z. B. mit XP her.

Auf jeden Fall solltest Du aber in der endgültigen Programmversion den Fehler abfangen. Denn nicht jeder hat Word installiert, und ein Laufzeitfehler macht sich dann nicht so gut.

Jan

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Do, 18. Sep 2008 10:17
von stevie
Windows 2000 und Office 2000 Pro.
Die CLSID hab ich in der Registrierung entdeckt.
Das ich den Fehler abfangen muss, dass der User kein Word hat hat, ist logisch.

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Fr, 17. Okt 2008 10:57
von stevie
Hab jetzt Quit abfangen können, musste eine Eventschleife hinzufügen, dann klappte das.
Nur eins ist komisch. Word hat das Ereignis Quit, Excel aber nicht.
Hat Excel etwas anderes, sonst kann ich per visible in der Eventschleife das Programm
bis Excel beendet ist, anhalten?

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Fr, 17. Okt 2008 11:08
von Koverhage
Stevie,

hatte auch das Problem, wurde durch die Hilfe von Alaska in Berlin gelöst.

oBook := oExcel:workbooks:open( cFile,,.t. )

oBook := oBook:dynamicCast(ActiveXObject())
oBook:BeforeClose := {||lExcelFinished := .T.}
lExcelFinished := .F.

Do WHILE !lExcelFinished
// Just wait
nEvent := AppEvent( @mp1, @mp2, , 1)
EndDo

// Quit Excel
oExcel:Quit()
oExcel:Destroy()

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Fr, 17. Okt 2008 11:19
von AUGE_OHR
hi,
stevie hat geschrieben: Nur eins ist komisch. Word hat das Ereignis Quit, Excel aber nicht.
schieb doch mal ein SLEEP(1000) vor dein oExcel:Quit() ... dann hat er es auf einmal ...

solange Excel noch am "arbeiten" ist z.b. Workbook "schliessen" kannst du die Methodes
nicht aufrufen was bei vielen activeX passiert ... die sind einfach "zu langsam" und deshab
SLEEP() oder eleganter die Eventloop.

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Fr, 17. Okt 2008 12:54
von stevie
naja nee, jetz ist das anders geworden.
Dokument neu erstellen.
Excel wird gestartet mit Vorlage und speichert das Dokument.
Jetzt bleibt Excel offen für den Fall, dass der Anwender noch etwas eintippen will.
Sobald Excel geschlossen wurde, wird das gespeicherte Dokument aus dem Arbeitsverzeichnis in das Zielverzeichnis kopiert und zwar automatisch.
Daher habe ich das bei Word so gelöst:

Code: Alles auswählen

oWord:Quit:={|| lCloseW:=.T.}
Eventschleife bis lCloseW halt, war ist.
Da Excel Quit anscheinend nicht besitzt, jedenfalls sagt er das beim Quit-Codeblock zuweisen,
ist halt die Frage, ob es noch ein anderes Event für "Excel wurde durch Anwender beendet" gibt.
Ansonsten muss ich den gleichen Aufbau halt mit oExcel:visible machen.
Egal in welchem Zustand Excel steht, es ist immer .T. bis Excel geschlossen wurde.

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Fr, 17. Okt 2008 13:26
von Koverhage
Stevie,

wenn Du das benutzt was ich geschrieben habe, sollte es funktionieren

Re: Exit-Methode beim (oder sagt man in) ActiveX-Object

Verfasst: Mo, 20. Okt 2008 8:46
von stevie
Koverhage hat geschrieben:Stevie,

wenn Du das benutzt was ich geschrieben habe, sollte es funktionieren
BeforeClose wird aufgerufen, wenn das Dokument geschlossen wird,
nicht aber wenn das Programm geschlossen wird, deswegen geht das so nicht.

Code: Alles auswählen

                  // Erzeugen eines "Excel.Application"-Objektes
                  oExcel := CreateObject("Excel.Application")
                  IF Empty( oExcel )
                     MsgBox( "Excel ist nicht installiert" )
                     RETURN
                  ENDIF

                  oExcel:= oExcel:dynamicCast(ActiveXObject())
                  // Vermeiden von Nachrichten wie "Die Datei
                  // existiert bereits". Sicherstellen, dass
                  // die Excel-Anwendung sichtbar ist.
                  oExcel:DisplayAlerts := .F.
                  oExcel:visible       := .T.
                  oBook  := oExcel:workbooks:Add(cVorl) // neue Datei mit Vorlage erstellen
                  oSheet := oBook:ActiveSheet
                  oSheet:PageSetup:Orientation := xlLandscape
                  //oSheet:Cells(1,1):Value:="Test"
                   // Speichern des Ergebnisses
                  IF ValType(cDatei)=="C"
                     oSheet:SaveAs(cDatei)
                  ENDIF
                  Do While oExcel:visible
                     nEvent := AppEvent( @mp1, @mp2, @oXbp )
                  Enddo
Das ganze mal mit visible, so kann man noch x-andere Dokumente öffnen und schließen,
bevor es im Programm weitergeht.
Und jetzt bitte keine Ansagen, wie "den Fehler musst du noch abfangen",
da guck ich sowieso nochmal genau hin.
Aber trotzdem Vielen Dank für eure Mühen.