| | | KISTERS 3DViewStation: 3D-Heatmaps für aussagekräftige Machbarkeitsanalysen, eine Pressemitteilung
|
Autor
|
Thema: STL Import API Lösung (1921 / mal gelesen)
|
Tanki Mitglied Entwicklungsingenieur
Beiträge: 14 Registriert: 11.05.2018 CATIA V5 R29 SP3 Windows 10
|
erstellt am: 25. Sep. 2020 17:00 <-- editieren / zitieren --> Unities abgeben:
Hallo zusammen, da CATIA keine VBA Lösung für die Funktionen "STL Import" bereitstellt, möchte ich mich erstmalig mit einer API Anwendung in VBA beschäftigen. Im Anhang ist die GUI der Funktion zu sehen. Der Code soll folgende Schritte ausführen: 1. CATIA.StartCommand "STL Import" 2. In den Filebrowser wird der Dateipfad automatisch eingetragen 3. Apply 4. OK Ich habe dafür in Vorbereitung dessen über spy++ die handle der Einzelnen Fenster bzw. Schaltflächen ermittelt. Kann mir jemand mit einem Ansatz aushelfen, wie ich die einzelnen Schaltflächen in VBA nun anspreche? Zudem ist mir aufgefallen, dass im Speicherpfad des STL Imports bei Start des Befehls stets ein alter Pfad bereits angezogen ist. Kann ich diese Vorauswahl evtl auch über einen einfachen VBA Befehl schon treffen und muss nicht den umständlichen Weg über API gehen? Um euch noch ein bisschen Kontext zu geben: Das Ziel ist es, alle STL Files eine Verzeichnisses über eine Schleife in CATParts zu konvertieren, indem die STLs als Mesh importiert werden und im zweiten Schritt über Automatic Surface in Flächen überführt werden Danke euch vorab und viele Grüße Tanki
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Tanki Mitglied Entwicklungsingenieur
Beiträge: 14 Registriert: 11.05.2018 CATIA V5 R29 SP3 Windows 10
|
erstellt am: 21. Okt. 2020 13:41 <-- editieren / zitieren --> Unities abgeben:
Hallo, ich bin etwas vorangekommen in dem Thema. Ich kann die einzelnen Buttons des Dialogfenster über die jeweiligen Handles ansprechen. Hier war der Schlüssel, dass die Handles ein recht komplexe Parent-Children Beziehung haben und man erst die verschiedenen Ebenen ansprechen muss. Nun habe ich folgendes Problem: Beim Öffnen der Windows Exploreroberfläche (in der die zu importierende Datei ausgewählt werden soll) aus dem STL Import Dialog heraus, wird die Ausführung des Codes angehalten. Erst, wenn ich die Explorer-DialogBox manuell "wegklicke" kann der Code weiterlaufen. Ich möchte hier natürlich automatisiert den Dateinamen eintragen. Wie bewirke ich, dass der Code an der unten fett markierten Stelle weiterläuft?
Code:
Private Declare PtrSafe Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare PtrSafe Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWndParent As LongPtr, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long Private Declare PtrSafe Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As LongPtr, ByVal wParam As LongPtr, lParam As LongPtr) As Long Private Declare PtrSafe Function SetForgroundWindow Lib "user32.dll" Alias "SetForgroundWindowA" (ByVal hwnd As LongPtr) As LongPtr Private Declare PtrSafe Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As LongPtr) As LongPtr Private Const WS_DISABLED = &H8000000 Private Const BM_CLICK = &HF5 Dim hstlimport, hfileselect, hautomaticsurface As LongPtr Dim childwindow1, childwindow2, childwindow3, hOeffnenButton, hOKButton, hOKButtonSurface, hApplyButton, hexplorerButton, heditfilelink As LongPtr Sub CATMain() Dim selection As selection 'Pfad mit den STL Daten auswählen 'For Each STL in Dateipfad
CATIA.StartCommand "STL Import" While hstlimport = 0 hstlimport = FindWindow("#32770", "Import") CATIA.RefreshDisplay = True Wend 'childwindows Ebene 1 ermitteln childwindow1 = 0 While childwindow1 = 0 childwindow1 = FindWindowEx(CLng(hstlimport), 0, vbNullString, "GlobalFrame") Wend 'childwindows Ebene 2 ermitteln childwindow2 = 0 While childwindow2 = 0 childwindow2 = FindWindowEx(CLng(childwindow1), 0, vbNullString, "Selected File") Wend 'childwindows Ebene 3 ermitteln childwindow3 = 0 While childwindow3 = 0 childwindow3 = FindWindowEx(CLng(childwindow2), 0, vbNullString, "FrameFile") Wend 'Filebrowser öffnen While hexplorerButton = 0 hexplorerButton = FindWindowEx(childwindow3, 0, "Button", "...") Wend SendMessage hexplorerButton, BM_CLICK, 0, 0 '######## An dieser Stelle hält der Code an ######### 'File Select Fenster finden While hfileselect = 0 hfileselect = FindWindow("#32770", "File Selection") Wend 'Dateinamen eintragen 'to be done 'Datei öffnen drücken While hOeffnenButton = 0 hOeffnenButton = FindWindowEx(hstlimport, 0, "Button", "Ö&ffnen") Wend SendMessage hOeffnenButton, BM_CLICK, 0, 0 'Apply Button finden und drücken While hApplyButton = 0 hApplyButton = FindWindowEx(hstlimport, 0, "Button", "Apply") Wend SendMessage hApplyButton, BM_CLICK, 0, 0 'Ok drücken und dann Fenster schließen hOKButton = FindWindowEx(hstlimport, 0, "Button", "OK") SendMessage hOKButton, BM_CLICK, 0, 0 'STL auswählen Dim partDocument1 As PartDocument Set partDocument1 = CATIA.ActiveDocument 'selection.Clear selection.Search ("Name=stl*,all") 'Automatic Surface Befehl ausführen CATIA.StartCommand "Automatic Surface" hautomaticsurface = FindWindow("#32770", "Automatic Surface") hOKButtonSurface = FindWindowEx(hautomaticsurface, 0, "Button", "OK") SendMessage hOKButtonSurface, BM_CLICK, 0, 0 'Fläche isolieren selection.Clear selection.Search ("Name=Automatic*,all") CATIA.StartCommand "Isolate" 'Stl löschen selection.Clear selection.Search ("Name=stl*,all") 'evtl *_* als Suchnamen selection.Delete 'Datei speichern unter '... 'Fläche löschen '... 'Next STL End Sub
Danke vorab und viele Grüße Tanki
[Diese Nachricht wurde von Tanki am 26. Okt. 2020 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Tanki Mitglied Entwicklungsingenieur
Beiträge: 14 Registriert: 11.05.2018 CATIA V5 R29 SP3 Windows 10
|
erstellt am: 26. Okt. 2020 14:51 <-- editieren / zitieren --> Unities abgeben:
Ergänzung: Aus meiner Internetrecherche hätte ich den Ansatz entwickelt, ein VBS Script im Hintergrund laufen zu lassen, welches überprüft, ob das FileBrowser-Fenster aufgeht. Wenn es aufgeht, müsste dieses Script den jeweiligen Dateinamen eintragen und auf Öffnen drücken. Damit würde sich das Fenster schließen und der Rest des Makros würde weiterlaufen. Da es das Ziel ist, alle STLs eines Ordners zu durchschleifen müsste ich zu Beginn jedes Schleifendurchgangs den Code des VBS-Scriptes anpassen, damit der korrekte Dateiname eingetragen wird. Hat jemand einen besseren Ansatz, der ausschließlich in VBA umzusetzen ist? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
bgrittmann Moderator Konstrukteur
Beiträge: 12005 Registriert: 30.11.2006 CATIA V5R19
|
erstellt am: 26. Okt. 2020 19:34 <-- editieren / zitieren --> Unities abgeben: Nur für Tanki
Servus Ich hab drei Ideen (ohne selbst mal mit der WinAPI gearbeitet zu haben): - in VBA auf das FileBrowser-Fenster per FindWindow zugreifen (eventuell musst du darauf warten (DoEvents, Sleep, ...)
- falls du es mit einem externen Script arbeiten willst: den Pfad als Parameter übergeben
- das ganze Makro auslagern (VB.net, VB6, ...) (auf Catia per GetObject zugreifen)
Gruß Bernd ------------------ Warum einfach, wenn es auch kompliziert geht. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Tanki Mitglied Entwicklungsingenieur
Beiträge: 14 Registriert: 11.05.2018 CATIA V5 R29 SP3 Windows 10
|
erstellt am: 27. Okt. 2020 14:30 <-- editieren / zitieren --> Unities abgeben:
Servus Bernd, zu deinen Ideen: 1. Funktioniert leider nicht, da der Code schlichtweg nicht weiter läuft, sodass ich einen neuen FindWindow Befehl starten könnte. 2. Das VBS Script scheint für mich die Lösung zu sein. Kannst du mir einen Hinweis geben, wie ich beim shell Befehl einen Parameter als Argument an das VBS Script übergeben kann? Das scheint alles in einem Pfadparameter übergeben zu werden... Mein Ansatz schaut so aus:
Code: 'Code zum Ausführen des Scripts stlfile = "...\test.stl" Shell "wscript.exe C:\Desktop\FileDialogSTL.vbs" 'Wie gebe ich hier die Variable stlfile als Argument an?
Code:
'VBS Code Set wshShell = CreateObject("WScript.Shell") Set arrPara = WScript.Arguments 'Hier wird das Argument entgegengenommenDo ret = wshShell.AppActivate("File Selection") Loop Until ret = True WScript.Sleep 500 ret = wshShell.AppActivate("File Selection") If ret = True Then ret = wshShell.AppActivate("File Selection") WScript.Sleep 1000 wshShell.SendKeys "{TAB}" WScript.Sleep 1000 wshShell.SendKeys "{TAB}" WScript.Sleep 1000 wshShell.SendKeys arrPara(0) WScript.Sleep 1000 wshShell.SendKeys "{enter}" End If
3. Hab ich mir jetzt noch nicht angeschaut. Aber hier sehe ich auf Anhieb auch keinen Vorteil. Danke und viele Grüße Tanki
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
bgrittmann Moderator Konstrukteur
Beiträge: 12005 Registriert: 30.11.2006 CATIA V5R19
|
erstellt am: 27. Okt. 2020 18:06 <-- editieren / zitieren --> Unities abgeben: Nur für Tanki
Servus Tanki Schon mal Code: Shell "wscript.exe C:\Desktop\FileDialogSTL.vbs " & stlfile
probiert (gemäß hier) Die Lösung 3 ist wohl am elegantesten: Code an einer Stelle, fertiges Makro als exe-Datei kompilieren Gruß Bernd ------------------ Warum einfach, wenn es auch kompliziert geht. Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Tanki Mitglied Entwicklungsingenieur
Beiträge: 14 Registriert: 11.05.2018 CATIA V5 R29 SP3 Windows 10
|
erstellt am: 28. Okt. 2020 14:04 <-- editieren / zitieren --> Unities abgeben:
Hi, ich hab den Aufruf des Scripts etwas angepasst, sodass das Argument korrekt übergeben wird. Wenn ich den Code im Debug schrittweise ausführe funktioniert alles wunderbar. Beim Run des Makros komme ich nun an dem Problem an, dass der VBA Code gewissermaßen das VBS Script überholt (in dem Moment, in dem das File Browser Fenster geöffnet werden soll). Der Einbau künstlicher Wartezeit führt an dieser Stelle leider nur dazu, dass die Ausführung des VBA Codes verzögert wird. Das File Browser Fenster öffnet sich nicht während der Wartezeit, sondern erst zu einem späteren Zeitpunkt, wenn im Code aufgrund mangelnden Inputs keine die nächste Anweisung nicht ausgeführt werden kann. Der aktuelle Code sieht so aus: Code:
Private Declare PtrSafe Function FindWindow Lib "user32.dll" Alias "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Private Declare PtrSafe Function FindWindowEx Lib "user32.dll" Alias "FindWindowExA" (ByVal hWndParent As LongPtr, ByVal hwndChildAfter As Long, ByVal lpszClass As String, ByVal lpszWindow As String) As Long Private Declare PtrSafe Function SendMessage Lib "user32.dll" Alias "SendMessageA" (ByVal hwnd As LongPtr, ByVal wMsg As LongPtr, ByVal wParam As LongPtr, lParam As LongPtr) As Long Private Declare PtrSafe Function SetForgroundWindow Lib "user32.dll" Alias "SetForgroundWindowA" (ByVal hwnd As LongPtr) As LongPtr Private Declare PtrSafe Function GetWindowLong Lib "user32.dll" Alias "GetWindowLongA" (ByVal hwnd As LongPtr, ByVal nIndex As LongPtr) As LongPtr Private Declare PtrSafe Sub Sleep Lib "kernel32.dll" (ByVal dwMilliseconds As Long) Private Const WS_DISABLED = &H8000000 Private Const BM_CLICK = &HF5 Dim sfile, stlfile As String Dim hstlimport, hfileselect, hautomaticsurface As LongPtr Dim childwindow1, childwindow2, childwindow3, hOeffnenButton, hOKButton, hOKButtonSurface, hApplyButton, hexplorerButton, heditfilelink As LongPtr Dim WSHShell As Object Sub CATMain()
Dim selection Set WSHShell = CreateObject("WScript.Shell") Dim cDir As String Dim sPath, catpartDateiname As String Dim partDocument1 As PartDocument '---------------------------------------------------------------------------------------------------------------------------------------------- 'Pfad auswählen über Pop-Up Dialog Set Application = CreateObject("Shell.Application") sPath = Application.BrowseForFolder(0, strTitle, 0).Self.Path & "\" cDir = Dir(sPath & "*.stl") Dim arrayOfVariantOfBSTR1(0) '---------------------------------------------------------------------------------------------------------------------------------------------- Do While cDir <> "" 'Dateinamen vergeben catpartDateiname = sPath & Left(cDir, Len(cDir) - 4) & ".CATPart" CATIA.StartCommand "STL Import" While hstlimport = 0 hstlimport = FindWindow("#32770", "Import") CATIA.RefreshDisplay = True Wend 'childwindows Ebene 1 ermitteln childwindow1 = 0 While childwindow1 = 0 childwindow1 = FindWindowEx(CLng(hstlimport), 0, vbNullString, "GlobalFrame") Wend 'childwindows Ebene 2 ermitteln childwindow2 = 0 While childwindow2 = 0 childwindow2 = FindWindowEx(CLng(childwindow1), 0, vbNullString, "Selected File") Wend 'childwindows Ebene 3 ermitteln childwindow3 = 0 While childwindow3 = 0 childwindow3 = FindWindowEx(CLng(childwindow2), 0, vbNullString, "FrameFile") Wend 'VBS Script schreiben und im Hintergrund starten stlfile = " " & sPath & cDir 'wichtig Leerzeichen. Als zweites Argument sollte sPath übergeben werden, um das verzeichnis im Browserfenster zu wechseln WSHShell.Run "C:\Desktop\FileDialogSTL.vbs" & stlfile Sleep 1000 'Filebrowser öffnen While hexplorerButton = 0 hexplorerButton = FindWindowEx(childwindow3, 0, "Button", "...") Wend SendMessage hexplorerButton, BM_CLICK, 0, 0 'do while schleife um zu verzögern bis das Explorerfenster geöffnet ist, damit der ApplyButton erst gedrückt wird, wenn das File Browser Fenster befüllt und wieder geschlossen wurde Dim time1, time2 time1 = Now time2 = Now + TimeValue("0:00:05") Do Until time1 >= time2 DoEvents time1 = Now() Loop 'Apply Button in STL IMport Fenster finden und drücken While hApplyButton = 0 hApplyButton = FindWindowEx(hstlimport, 0, "Button", "Apply") Wend SendMessage hApplyButton, BM_CLICK, 0, 0 'Ok drücken und Fenster schließen hOKButton = FindWindowEx(hstlimport, 0, "Button", "OK") SendMessage hOKButton, BM_CLICK, 0, 0 'STL auswählen Set partDocument1 = CATIA.ActiveDocument Set selection = CATIA.ActiveDocument.selection 'selection.Clear selection.Search ("Name=*.1,all") 'Automatic Surface Befehl ausführen CATIA.StartCommand "Automatic Surface" hautomaticsurface = FindWindow("#32770", "Automatic Surface") hOKButtonSurface = FindWindowEx(hautomaticsurface, 0, "Button", "OK") SendMessage hOKButtonSurface, BM_CLICK, 0, 0 'Fläche isolieren selection.Clear selection.Search ("Name=Automatic*,all") CATIA.StartCommand "Isolate" 'Stl löschen selection.Clear selection.Search ("Name=*.1,all") selection.Delete 'Datei speichern unter 'tbd 'Fläche löschen 'tbd 'Nächste Datei cDir = Dir Loop End Sub
Nach etwas Recherche denke ich, dass ich an Lösungspfad 3 nicht vorbeikomme. Wenn ich das Makro auslagere und auf CATIA als Object zugreife, müsste eine Sleep Anweisung ja bewirken, dass nur das ausgelagerte Makro verzögert wird und nicht CATIA selbst. Wenn noch jemand einen Ansatz hat, wie ich das Fenster dazu bewegen kann, aufzugehen, bevor die nächste Aktion (Apply Button) ausgeführt wird, dann immer raus damit :-) Beste Grüße Tanki Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
| Anzeige.:
Anzeige: (Infos zum Werbeplatz >>)
|