Hot News:

Mit Unterstützung durch:

  Foren auf CAD.de (alle Foren)
  CATIA V5 Programmierung
  STL Import API Lösung

Antwort erstellen  Neues Thema erstellen
CAD.de Login | Logout | Profil | Profil bearbeiten | Registrieren | Voreinstellungen | Hilfe | Suchen

Anzeige:

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen nächster neuer Beitrag | nächster älterer Beitrag
Autor Thema:  STL Import API Lösung (1785 / mal gelesen)
Tanki
Mitglied
Entwicklungsingenieur


Sehen Sie sich das Profil von Tanki an!   Senden Sie eine Private Message an Tanki  Schreiben Sie einen Gästebucheintrag für Tanki

Beiträge: 14
Registriert: 11.05.2018

CATIA V5 R29 SP3
Windows 10

erstellt am: 25. Sep. 2020 17:00    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities


GUISTLImport.png

 
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


Sehen Sie sich das Profil von Tanki an!   Senden Sie eine Private Message an Tanki  Schreiben Sie einen Gästebucheintrag für Tanki

Beiträge: 14
Registriert: 11.05.2018

CATIA V5 R29 SP3
Windows 10

erstellt am: 21. Okt. 2020 13:41    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities


2020_10_21_13_39_04_Window.png

 
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


Sehen Sie sich das Profil von Tanki an!   Senden Sie eine Private Message an Tanki  Schreiben Sie einen Gästebucheintrag für Tanki

Beiträge: 14
Registriert: 11.05.2018

CATIA V5 R29 SP3
Windows 10

erstellt am: 26. Okt. 2020 14:51    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

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


Sehen Sie sich das Profil von bgrittmann an!   Senden Sie eine Private Message an bgrittmann  Schreiben Sie einen Gästebucheintrag für bgrittmann

Beiträge: 11780
Registriert: 30.11.2006

CATIA V5R19

erstellt am: 26. Okt. 2020 19:34    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Tanki 10 Unities + Antwort hilfreich

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


Sehen Sie sich das Profil von Tanki an!   Senden Sie eine Private Message an Tanki  Schreiben Sie einen Gästebucheintrag für Tanki

Beiträge: 14
Registriert: 11.05.2018

CATIA V5 R29 SP3
Windows 10

erstellt am: 27. Okt. 2020 14:30    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

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 entgegengenommen

Do
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


Sehen Sie sich das Profil von bgrittmann an!   Senden Sie eine Private Message an bgrittmann  Schreiben Sie einen Gästebucheintrag für bgrittmann

Beiträge: 11780
Registriert: 30.11.2006

CATIA V5R19

erstellt am: 27. Okt. 2020 18:06    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities Nur für Tanki 10 Unities + Antwort hilfreich

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


Sehen Sie sich das Profil von Tanki an!   Senden Sie eine Private Message an Tanki  Schreiben Sie einen Gästebucheintrag für Tanki

Beiträge: 14
Registriert: 11.05.2018

CATIA V5 R29 SP3
Windows 10

erstellt am: 28. Okt. 2020 14:04    Editieren oder löschen Sie diesen Beitrag!  <-- editieren / zitieren -->   Antwort mit Zitat in Fett Antwort mit kursivem Zitat    Unities abgeben: 1 Unity (wenig hilfreich, aber dennoch)2 Unities3 Unities4 Unities5 Unities6 Unities7 Unities8 Unities9 Unities10 Unities

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 >>)

Darstellung des Themas zum Ausdrucken. Bitte dann die Druckfunktion des Browsers verwenden. | Suche nach Beiträgen

nächster neuerer Beitrag | nächster älterer Beitrag
Antwort erstellen


Diesen Beitrag mit Lesezeichen versehen ... | Nach anderen Beiträgen suchen | CAD.de-Newsletter

Administrative Optionen: Beitrag schliessen | Archivieren/Bewegen | Beitrag melden!

Fragen und Anregungen: Kritik-Forum | Neues aus der Community: Community-Forum

(c)2023 CAD.de | Impressum | Datenschutz