| | | Gut zu wissen: Hilfreiche Tipps und Tricks aus der Praxis prägnant, und auf den Punkt gebracht für Autodesk Produkte |
Autor
|
Thema: Pause bei Sendcommand (2278 mal gelesen)
|
Theo37 Mitglied Techniker
Beiträge: 423 Registriert: 08.10.2008
|
erstellt am: 29. Jul. 2010 16:33 <-- editieren / zitieren --> Unities abgeben:
Hallo an Alle, eine Frage an die VB-Spezialisten. Ich möchte folgende Zeilen von Lisp nach VP übersetzen: (defun c:nk1 () (command "einfüge" "X:\\ACAD-Symbole\\Lispsymbole\\Nk.dwg" Pause "1" "1" "0") (command "ursprung" "l") ) Es soll immer der gleiche Block, mit der gleichen Drehung und Skalierung eingefügt werden. Nur der Einfügepunkt soll vom Benutzer frei gewählt werden können. Dazu sollte der Block an der Maus hängen. Mit Sendcommand eigentlich kein Problem. Aber was mach ich mit dem Einfügepunkt? In List schreibe ich "Pause", dann hängt der Block an der Maus und ich kann einen Einfügepunkt anklicken und erst danach läuft der Command-Befehl weiter. Gibt es dazu in VB eine Alternative? Gruß, Theo Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 29. Jul. 2010 23:51 <-- editieren / zitieren -->
Hi, Wie das mit ' Zitat: Block hängt am Cursor
' gehen könnte: die sauberste Variante greift eher tief in's AutoCAD ein und lässt sich mit JIG-Methoden lösen (Beispiel ist meines Wissens im ObjectARX-Kit enthalten). Wenn Du nicht mit JIG arbeitest, dann hast Du auch nicht wirklich eine (saubere) Chance, den Block in der Voransicht der Maus folgen zu lassen, damit stehst Du bei SendCommand an, und damit brauchst Du nur die Optionsreihenfolge in Deinem LSP-Command ändern und es läuft. Guck mal, wenn Du im AutoCAD in der Befehlszeile folgendes startest: _-INSERT <deinBlockname> ==> und hier stehen die Optionen, die Du eingeben kannst, bevor Du den Basispunkt eingibst. Damit kannst Du die Eingabe fortsetzen mit: _scale 1 _rotate 0 Damit hast Du bewirkt, dass der Einfügepunkt als letzte Eingabe folgt, Du kannst damit über SendCommand dieses String schicken (command "_-INSERT" "DeinBlockname" "_SCALE" "1" "_ROTATE" "0") ...und damit ist das PAUSE aus dem LSP-Command entschwunden. Das nachfolgende Explode kannst Du eigentlich nur mit einem Event abfangen, dabei kannst Du vor Ende Deines ersten Codes mittles AddHandler ein Eventhandling CommandEnded oder ObjectCreated initialisieren, hat der Anwender dann den Block plaziert, dann wird Dein Event aktiv und Du kannst alles nachfolgende umsetzen.
Natürlich mußt Du vorbeugen: - dass der User den Einfügepunkt nicht zeigt, sondern vielleicht mit <ESC> abbricht - arbeitest Du mit ObjectCreated, dann wisse: sollte der Block Attribute haben, dann kommt für jedes Attribut ein ObjectCreated! - alfred - ------------------ www.hollaus.at |
Theo37 Mitglied Techniker
Beiträge: 423 Registriert: 08.10.2008
|
erstellt am: 30. Jul. 2010 11:37 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, Du schreibst: Das nachfolgende Explode kannst Du eigentlich nur mit einem Event abfangen, dabei kannst Du vor Ende Deines ersten Codes mittles AddHandler ein Eventhandling CommandEnded oder ObjectCreated initialisieren, hat der Anwender dann den Block plaziert, dann wird Dein Event aktiv und Du kannst alles nachfolgende umsetzen. Ich habe wirklich das Problem, daß nach dem Sendcommand-Befehl der nachfolgende Code früher ausgeführt wird, als der Auto-CAD befehl fertig ist. Was zu unvorhersehbaren Dingen führt. Wie kann ich sicherstellen, daß Sendcommand erst abgearbeitet wird und es danach erst im VB-Program weiter geht. Kannst Du mir dafür ein Code-Beispiel liefern? Gruß, Theo Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 30. Jul. 2010 11:58 <-- editieren / zitieren -->
Hi, >> Ich habe wirklich das Problem, daß nach dem Sendcommand-Befehl der nachfolgende Code früher ausgeführt wird, >> als der Auto-CAD befehl fertig ist Eigentlich steht in diesem Satz ja schon drin, wieso es (aus der Sicht von VBA) hier so nicht mehr geht. Mit anderen Worten und damit hoffentlich besser verständlich: Ein SendCommand-Befehl wird nicht ausgeführt während eines anderen AutoCAD-Befehls ==> Ist ja auch kein Wunder, denn in AutoCAD kann immer nur ein Befehl aktiv sein (Transparente Befehle jetzt mal ausgenommen). Und damit wird klar, erst wenn ein Befehl fertig ist, kann der andere gestartet werden. BeispielCode COM-basierend oder Managed?
- alfred - ------------------ www.hollaus.at |
Theo37 Mitglied Techniker
Beiträge: 423 Registriert: 08.10.2008
|
erstellt am: 30. Jul. 2010 12:37 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, das mit den AutCAD-Befehlen ist mir klar und das funktioniert auch. Nur mein Problem sind die nachfolgenden Zeilen im Program, diese werden von VB abgearbeitet bevor AutoCAD fertig ist. Eie kann ich das verhindern? BeispielCode bitte Managed. Danke, Theo Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 30. Jul. 2010 13:55 <-- editieren / zitieren -->
Hi, ein simples Beispiel dazu: Du startest meinen Befehl 'CADde_PLineClosed', dieser schickt an AutoCAD den Befehl _PLINE. Diese App setzt dann, wenn der Anwender mit der Polylinienerstellung fertig ist (entspricht/ersetzt eben PAUSE in LISP) wieder fort, überprüft, ob die Polylinie geschlossen ist und wenn nicht, wird diese Polylinie geschlossen. Das entspricht dann der Fortsetzung Deines Programms, ob Du dann jetzt Explode einer Blockreference machst oder sonstwas, das Handling ist gleich. Ich habe in diesem Beispiel keine Fehlerbehandlung durchgeführt, nur Standard-Checks, also diese bitte in Deinem Beispiel dann einbauen, hier ist es ohne diesen (hoffe ich) einfacher lesbar. Code: ''' <summary>CADde_PLineClosed startet via SendCommand den Befehlsaufruf für Polylinie ''' fängt dann das Ende der Polylinien-Erstellung ab und schliesst diese (wenn nicht durch Anwender schon geschehen) ''' </summary> ''' <remarks></remarks> <Autodesk.AutoCAD.Runtime.CommandMethod("CADde_PLineClosed")> _ Public Shared Sub CADde_PLineClosed() pAcadDoc = ApplicationServices.Application.DocumentManager.MdiActiveDocument pObjsAdded = New DatabaseServices.ObjectIdCollection 'wir machen AutoCAD jetzt mal darauf aufmerksam, dass es sich die erzeugten Elemente merken soll ' und am Ende des _PLINE-Befehls uns die Kontrolle wiedergibt AddHandler pAcadDoc.Database.ObjectAppended, AddressOf AcadDocEvHandler_ObjectAdded 'damit erstellte Objekte gesammelt werden können AddHandler pAcadDoc.CommandEnded, AddressOf AcadDocEvHandler_CommandEnded 'damit wir das Ende des Befehls erleben 'und jetzt das Polylinien-Command senden CType(pAcadDoc.AcadDocument, Interop.AcadDocument).SendCommand("_PLINE" & vbCr) 'hier hoert der eigene Befehl auf, damit kann der Befehl _PLINE aktiv werden 'fuer uns geht's erst weiter, wenn der EventHandler unten zuschnappt End Sub Private Shared pAcadDoc As ApplicationServices.Document = Nothing Private Shared pObjsAdded As DatabaseServices.ObjectIdCollection = Nothing Private Shared Sub AcadDocEvHandler_ObjectAdded(ByVal sender As Object, ByVal e As DatabaseServices.ObjectEventArgs) If (pObjsAdded IsNot Nothing) AndAlso (Not pObjsAdded.Contains(e.DBObject.ObjectId)) Then pObjsAdded.Add(e.DBObject.ObjectId) End If End Sub Private Shared Sub AcadDocEvHandler_CommandEnded(ByVal sender As Object, ByVal e As ApplicationServices.CommandEventArgs) If e.GlobalCommandName <> "CADDE_PLINECLOSED" Then 'ok die Kontrolle haben wir jetzt, die nächsten AutoCAD-Befehle brauchen wir daher nicht mehr ueberwachen ' die Ueberwachung nehmen wir damit jetzt zurueck RemoveHandler pAcadDoc.Database.ObjectAppended, AddressOf AcadDocEvHandler_ObjectAdded RemoveHandler pAcadDoc.CommandEnded, AddressOf AcadDocEvHandler_CommandEnded If (pObjsAdded IsNot Nothing) AndAlso (pObjsAdded.Count > 0) Then 'ok, es gibt neue Objekte, damit hat der Anwender nicht abgebrochen Dim tTrAct As DatabaseServices.Transaction = Nothing Dim tModifiedSomething As Boolean = False For Each tObjID As DatabaseServices.ObjectId In pObjsAdded If (tObjID.IsValid) AndAlso (Not tObjID.IsErased) AndAlso (tObjID.ObjectClass.DxfName Like "*POLYLINE*") Then 'es gibt in der Liste der Elemente auch die, die wir suchen/erwarten 'Element nehmen, pruefen, ob geschlossen und wenn nicht, dann jetzt schliessen If tTrAct Is Nothing Then tTrAct = pAcadDoc.TransactionManager.StartTransaction Dim tCurve As DatabaseServices.Curve = CType(tTrAct.GetObject(tObjID, DatabaseServices.OpenMode.ForWrite), DatabaseServices.Curve) If Not tCurve.Closed Then Select Case tCurve.GetType.FullName Case GetType(DatabaseServices.Polyline).FullName CType(tCurve, DatabaseServices.Polyline).Closed = True tModifiedSomething = True Case GetType(DatabaseServices.Polyline2d).FullName CType(tCurve, DatabaseServices.Polyline2d).Closed = True tModifiedSomething = True Case GetType(DatabaseServices.Polyline3d).FullName CType(tCurve, DatabaseServices.Polyline3d).Closed = True tModifiedSomething = True End Select End If End If Next If (tTrAct IsNot Nothing) Then If tModifiedSomething Then tTrAct.Commit() 'aenderungen ueber TransAction bestaetigen tTrAct.Dispose() tTrAct = Nothing End If End If 'und alles wieder sauber zuruecklassen If pObjsAdded IsNot Nothing Then pObjsAdded.Dispose() pObjsAdded = Nothing End If pAcadDoc = Nothing End If End Sub
- alfred -
------------------ www.hollaus.at |
Theo37 Mitglied Techniker
Beiträge: 423 Registriert: 08.10.2008
|
erstellt am: 30. Jul. 2010 14:17 <-- editieren / zitieren --> Unities abgeben:
|
Theo37 Mitglied Techniker
Beiträge: 423 Registriert: 08.10.2008 ACAD 2019 WIN 7 64bit Intel Xenon CPU E5-1620 3.60GHz 16GB RAM
|
erstellt am: 02. Aug. 2010 16:36 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, was muß ich vorher importieren? Wenn ich dein Beispiel laufen lassen will kommt bei vielen Dingen der Fehler : Der Typ "..." ist nicht defieniert. So z.B. bei atabaseServices.ObjectIdCollection, Interop.AcadDocument, ApplicationServices.Document... Ich denke es muß irgendwas am Anfang der Klasse stehen. Danke Theo Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 02. Aug. 2010 17:36 <-- editieren / zitieren -->
Hi, wenn Du den Objektbrowser startest, dann nach dem Typ suchst, der nicht gefunden wird, dann findest Du auch, wo dieser Typ definiert ist. Ich habe immer dieses (bezogen auf Autodesk/AutoCAD) impotiert: Imports Autodesk.AutoCAD HTH, - alfred - ------------------ www.hollaus.at |
Theo37 Mitglied Techniker
Beiträge: 423 Registriert: 08.10.2008
|
erstellt am: 03. Aug. 2010 13:32 <-- editieren / zitieren --> Unities abgeben:
Hi Alfred, ich krieg Dein Beispiel einfach nicht zum funktionieren. Ich weiß nicht was ich falsch mache. Mit dem Import von Autodesk.Autocad sind alle Fehlermedlungen weg. Und das Programm läuft einwandfrei durch. Nur es wartet nicht darauf, daß Autocad fertig wird. Ich habe mal zum Test ganz am Ende vom Programm nach "pAcadDoc = Nothing" eine MSGbox eingebaut, diese kommt ganz am Anfang. Erst danach kommt in der Acad-Befehlszeile die Pline. Auch wenn ich Zeile für Zeile debugge, wird die Zeile mit dem Sendcommand einfach übersprungen und es geht sofort in der CommandEnded Prozedur weiter. Kommt es auf irgendeine AutoCad Einstellung an? Gruß, Theo Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Theo37 Mitglied Techniker
Beiträge: 423 Registriert: 08.10.2008 ACAD 2019 WIN 7 64bit Intel Xenon CPU E5-1620 3.60GHz 16GB RAM
|
erstellt am: 03. Aug. 2010 16:13 <-- editieren / zitieren --> Unities abgeben:
Hallo Alfred, sorry, es geht doch. Hatte es nicht richtig probiert. Wenn ich es richtig verstanden habe, dann läuft die "AcadDocEvHandler_CommandEnded" einmal vor dem Sendcommand und einmal danach. Warum verstehe ich nicht ganz. Gruß, Theo Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Ex-Mitglied
|
erstellt am: 03. Aug. 2010 19:35 <-- editieren / zitieren -->
Hi, >> einmal vor dem Sendcommand und einmal danach. Warum verstehe ich nicht ganz.Beim ersten mal wird das Ende des Befehls 'CADde_PLineClosed' gefangen (der Befehl ist ja auch ein AutoCAD-Befehl) und dann wird der via SendCommand geschickte 'PLINE'-Befehl abgefangen. Deswegen auch das 'If ...' gleich am Anfang des Eventhandlers. HTH, - alfred - ------------------ www.hollaus.at |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|