1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Fenster im Vordergrund

Dieses Thema im Forum "Visual Basic, Visual Basic for Applications (VBA) " wurde erstellt von Edwin1966, 20. Februar 2018.

  1. Edwin1966

    Edwin1966 New Member

    Hallo

    Ich rufe in einem VBScript eine HTA auf, um eine Visualisierung zu erhalten. Das klapp soweit auch ganz gut, leider habe ich noch ein Problem damit, die Fenster in den Vordergrund zu holen. AppActivate gibt es in meinem VBS leider nicht, da dies eine etwas abgeänderte Version zur IBN von Werkzeugmaschinen ist.

    Ich habe auch schon versucht, in der HTA nochmal ein Script mit AppActivate zu setzen, leider ebenfalls ohne erfolgt. Hier ein Teil des Quellcodes, ich hoffe, ihr könnt mir helfen, ich komme einfach nicht weiter.

    Code:
    Set oIE = CreateObject("InternetExplorer.Application")
    With oIE
        .Left = 500                                    ' Window left position in pixels
        .Top = 200                                     ' Window top position in pixels
        .Height = CLng(390.0 * rGuiScaling)           ' Window heigth in pixels
        .Width = CLng(550.0 * rGuiScaling)            ' Window width in pixels, alt: 400
        .AddressBar = False                           ' Show addressbar
        .Menubar = False                              ' Show menubar
        .Toolbar = False                              ' Show toolbar
        .Statusbar = False                            ' Show statusbar
        .Resizable = False                            ' Window is resizable
        .Navigate("about:blank")                      ' Url
        .Visible = True                               ' Display window
        Set oDoc = .Document                          ' Get object of displayed html document
    End With ' oIE
    
    With oDoc
        ' Open the (empty) document and write the formular code in it.
        .Open
        .Writeln("<html><head><title>")
        ' HTA Erstellung
        .Close
    End With ' oDoc
     
    ' For inner loop check, if IE object still exists
    On Error Resume Next
    ' Wait until button is pushed
    While (Not(boClose))
        ' Suspend and release CPU utilization
        APP.Time(1)
        ' Check, if IE object still exists
        iDummy = oIE.ReadyState
       
        If (Err.Number <> 0) Then
            ' Some kind of IE access error => exit loop and quit application
            boClose = True
            boExit = True
        End If ' Err.Number <> 0
    Wend ' Not(boClose)
    On Error GoTo 0
  2. BAGZZlash

    BAGZZlash Active Member

    Was ist denn eine "HTA"? Was ist "IBN"?

    Mal ge-google-t? Finde da z.B. das hier. Hilft das?

    Code:
    Set oIE = CreateObject("InternetExplorer.Application")
    
    With oIE
       .Left = 500  ' Window left position in pixels
       .Top = 200  ' Window top position in pixels
       .Height = CLng(390.0 * rGuiScaling)  ' Window heigth in pixels
       .Width = CLng(550.0 * rGuiScaling)  ' Window width in pixels, alt: 400
       .AddressBar = False  ' Show addressbar
       .Menubar = False  ' Show menubar
       .Toolbar = False  ' Show toolbar
       .Statusbar = False  ' Show statusbar
       .Resizable = False  ' Window is resizable
       .Navigate("about:blank")  ' Url
       .Visible = True  ' Display window
       Set oDoc = .Document  ' Get object of displayed html document
    End With ' oIE
    
    With oDoc
       ' Open the (empty) document and write the formular code in it.
       .Open
       .Writeln("<html><head><title>")
       ShowWindow "iexplore", "."
      ' HTA Erstellung
      .Close
    End With ' oDoc
    
    On Error Resume Next
    ' Wait until button is pushed
    While (Not(boClose))
      ' Suspend and release CPU utilization
      APP.Time(1)
      ' Check, if IE object still exists
      iDummy = oIE.ReadyState
      
      If (Err.Number <> 0) Then
      ' Some kind of IE access error => exit loop and quit application
         boClose = True
         boExit = True
      End If ' Err.Number <> 0
    Wend ' Not(boClose)
    
    On Error GoTo 0
    
    sub ShowWindow(appName, titlePattern)
    '@description: Bring a window to the front and activate it.
    '@author: Jeremy England (SimplyCoded)
      with createobject("wscript.shell")
      .run "powershell -Command ""$type = Add-Type -MemberDefinition '[DllImport(\""user32.dll\"")] " & _
      "public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);[DllImport(\""user32.dll\"")] " & _
      "public static extern int SetForegroundWindow(IntPtr hwnd);' -Name WindowAPI -PassThru;$hwnd = (Get-Process " & _
      appName & " | where MainWindowTitle -match '" & titlePattern & "').MainWindowHandle;" & _
      "&null = $type::ShowWindowAsync($hwnd, 4);$null = $type::SetForegroundWindow($hwnd)""", 0, true
      end with
    end sub
  3. Edwin1966

    Edwin1966 New Member

    Hy

    Danke für die Antwort, hab es gerade getestet, jedoch wieder ohne Erfolg.
    Ja, ich habe schon stunden mit google verbracht und vieles getestet, da ich aber keine Lösung gefunden habe, hoffe ich, dass mir hier im Forum geholfen werden kann.
    HTA: HTML Application um für ein VBScript eine GUI zu erzeugen
    IBN: Inbetriebnahme

    Danke, mfg
  4. BAGZZlash

    BAGZZlash Active Member

    Ja, dass SetForegroundWindow() nicht so ohne Weiteres funktioniert, dafür hat Microsoft gute Gründe, siehe auch hier. Man muss das In-den-Vordergrund-Holen zuerst autorisieren. Wie das prinzipiell geht, habe ich hier beschrieben. Das ist allerdings für VB6. Wie das auf VBS anzupassen ist, weiß ich nicht, dafür kenne ich mich mit VBS nicht gut genug aus. Ohne direkten Zugang zum API wird's aber schwer. Grundsätzlich so, wie im geposteten Code auch, und zwar per API-Wrapper mittels "wscript.shell".
  5. German

    German Well-Known Member c-b Experte

    Ich schau mir das heute Abend mal an. So richtig komme ich aber noch nicht klar, was du eigentlich vorhast.

    Eine HTA ist eine HTML Datei mit einem zusätzlichen <HTA:APPLICATION> Tag und der Dateiendung .hta, die mit mshta.exe in einem von einem Browser unabhängigen Fenster ausgeführt wird. So weit so gut. Bloß sehe ich nichts dergleichen in deinem Code. Du erzeugst eine Interntexplorer Instanz und schreibst dort offensichtlich HTML Markup in die DOM Struktur. Und dann?
  6. Edwin1966

    Edwin1966 New Member

    Es ist eine HTML Application in einem VBScript, habe in folgendem Link gelesen, dass man das HTA nennt:
    http://www.sternenhimmelstuermer.eu/pctipps/hta.html
    Mein VBScript hat nur Massagebox und Inputbox zur Verfügung, das ist für die Eingabe von mehreren Werten sehr mühsam. Daher die Idee zur HTA, aber es ist halt sehr nervig, dass jedesmal der Fokus verloren geht und man Programm sowie zb. Ordnerauswahl erst wieder suchen muss.
  7. German

    German Well-Known Member c-b Experte

    Ich habe eine ganz gute Vorstellung von dem was eine HTA ist, weil ich schon einige geschrieben habe. Ich verstehe immer noch nicht was dein obiger Code damit zu tun hat. Vielleicht klärst du mal darüber auf. Du kannst VBScript in eine HTA einbinden, bei dir sieht das irgendwie nach dem umgekehrten Fall aus :confused: Wie gesagt, ich werde nicht schlau daraus.
  8. Edwin1966

    Edwin1966 New Member

    Ja, genauso ist es. Ich habe in einem Inbetriebnahmeprogramm für einen Antriebsregler (Roboterinbetriebnahme) die Möglichkeit ein Script einzufügen, aber keine HTA.
    Es gibt aber die Möglichkeit, eine HTA vom Script heraus auszuführen, dies wird durch die Befehle CreateObject("InternetExplorer.Application") und anschließend .writeln("HTML Code") ermöglicht.
    Ich kann nur *.vbs Files einfügen, keine direkten HTA-Files.
  9. German

    German Well-Known Member c-b Experte

    Das wird Mist. Lege deine HTA außerhalb des Scripts an und verwende im Script nur ein
    CreateObject("WScript.Shell").Run "Beispiel.hta"
    Die Logik die deine HTA braucht, schreibst du dann in integrierte JavaScript oder VBScript Routinen in die HTA.
  10. Edwin1966

    Edwin1966 New Member

    So einfach geht das leider nicht, ich habe ja in der HTA Eingaben, diese muss ich weiterleiten ans VBScript. Wenn ich aus dem VBScript eine HTA starte, wie kann ich dann Variablen an das Script senden? Die Daten müssen ins Inbetriebnahmetool, also in das VBScript, mit dem ich die HTA starte.
  11. German

    German Well-Known Member c-b Experte

    Dann erweitere deinen Code mal soweit, dass was daraus wird was man ausführen kann und den Fehler reproduziert. Keine Ahnung, ein Eingabefeld oder so ...
  12. Edwin1966

    Edwin1966 New Member

    Hy

    Habe einen Button Offline hinzugefügt, beim Drücken wird eine Msgbox aufgerufen.
    Code:
    Set oIE = CreateObject("InternetExplorer.Application")
    With oIE
        .Left = 500                                    ' Window left position in pixels
        .Top = 200                                     ' Window top position in pixels
        .Height = CLng(390.0 * rGuiScaling)           ' Window heigth in pixels
        .Width = CLng(550.0 * rGuiScaling)            ' Window width in pixels, alt: 400
        .AddressBar = False                           ' Show addressbar
        .Menubar = False                              ' Show menubar
        .Toolbar = False                              ' Show toolbar
        .Statusbar = False                            ' Show statusbar
        .Resizable = False                            ' Window is resizable
        .Navigate("about:blank")                      ' Url
        .Visible = True                               ' Display window
        Set oDoc = .Document                          ' Get object of displayed html document
    End With ' oIE
    
    With oDoc
        ' Open the (empty) document and write the formular code in it.
        .Open
        .Writeln("<html><head><title>" & "IBN-Script" & "</title>" &_
             "<style ....>"</style></head>")
    
        .Writeln("<div><span style='position:absolute; left: 50px;'>" & _
            "<input Type=button id='htaOffline' Value='Offline'></span></div>")
        ' ......
        .Close
    End With ' oDoc
     
      .GetElementById("htaOffline").OnClick = GetRef("OnClick_Offline")
      .GetElementById("htaOffline").Disabled = False
       
    ' For inner loop check, if IE object still exists
    On Error Resume Next
    ' Wait until button is pushed
    While (Not(boClose))
        ' Suspend and release CPU utilization
        APP.Time(1)
        ' Check, if IE object still exists
        iDummy = oIE.ReadyState
       
        If (Err.Number <> 0) Then
            ' Some kind of IE access error => exit loop and quit application
            boClose = True
            boExit = True
        End If ' Err.Number <> 0
    Wend ' Not(boClose)
    On Error GoTo 0
       
    Private Sub OnClick_Offline()
        MsgBox("Button Offline gedrückt")
        boClose = True
    End Sub ' OnClick_Offline    
  13. German

    German Well-Known Member c-b Experte

    ... wäre schön gewesen.
    Woher kommt rGuiScaling?
    "<style ....>"</style></head>" unbalanced quotes
    Woher kommt das Objekt für .GetElementById("htaOffline")...?
  14. Edwin1966

    Edwin1966 New Member

    Oh, sorry, werds nochmal überarbeiten und testen und erst dann posten. Der Originalcode ist mittlerweile schon sehr umfangreich und nicht sehr leserlich.
  15. German

    German Well-Known Member c-b Experte

    Naja, ich kann das auch gerade ziehen. Hatte nur nicht endlos Zeit. Aber es ist ja Wochenende ...
    Code:
    Option Explicit
    Const MB_TOPMOST = &h00040000&, _
          Title = "IBN-Script"
    Dim oIE, oDoc, iDummy, boClose
    
    Set oIE = CreateObject("InternetExplorer.Application")
    With oIE
      .Left = 500                                   ' Window left position in pixels
      .Top = 200                                    ' Window top position in pixels
      .Height = 390                                 ' Window heigth in pixels
      .Width = 550                                  ' Window width in pixels, alt: 400
      .AddressBar = 0                               ' Show addressbar
      .Menubar = 0                                  ' Show menubar
      .Toolbar = 0                                  ' Show toolbar
      .Statusbar = 0                                ' Show statusbar
      .Resizable = 0                                ' Window is resizable
      .Navigate "about:blank"                       ' Url
      .Visible = 0                                  ' Hide window
      Set oDoc = .Document                          ' Get object of displayed html document
    End With ' oIE
    
    With oDoc
      ' Open the (empty) document and write the formular code in it.
      .Open
      .Writeln "<html><head><title>" & Title & "</title></head><body><div><span style='position:absolute; left:50px;'><input Type=button id='htaOffline' Value='Offline'></span></div></body></html>"
      .GetElementById("htaOffline").OnClick = GetRef("OnClick_Offline")
      .GetElementById("htaOffline").Disabled = False
      .Close
    End With ' oDoc
    
    ' Bring the window to the foreground and give it the keyboard focus
    boClose = False
    oIE.Visible = 1
    ShowWindow "iexplore", "^" & Title
    
    ' Wait until button is pushed
    While (Not boClose)
      Wscript.Sleep 50
      ' Check, if IE object still exists
      On Error Resume Next
      iDummy = oIE.ReadyState
      ' Some kind of IE access error => exit loop and quit application
      If (Err.Number <> 0) Then
        oIE.Quit
        WScript.Quit
      End If
      On Error GoTo 0
    Wend ' Not(boClose)
    
    oIE.Quit
    
    Private Sub OnClick_Offline()
      CreateObject("WScript.Shell").Popup "Button Offline gedrückt", 0, "Test", vbSystemModal Or MB_TOPMOST
      boClose = True
    End Sub ' OnClick_Offline
    
    Private Sub ShowWindow(appName, titlePattern)
    '@description: Bring a window to the front and activate it.
    '@author: Jeremy England (SimplyCoded), modified: Steffen Illhardt
      CreateObject("WScript.Shell").Run "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command ""$type = Add-Type -MemberDefinition '" & _
        "[DllImport(\""user32.dll\"")] public static extern bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);" & _
        "[DllImport(\""user32.dll\"")] public static extern int SetForegroundWindow(IntPtr hwnd);' -Name WindowAPI -PassThru;" & _
        "$hwnd = (Get-Process " & appName & " | where MainWindowTitle -match '" & titlePattern & "').MainWindowHandle;" & _
        "&null = $type::ShowWindowAsync($hwnd, 4);$null = $type::SetForegroundWindow($hwnd)""", 0, True
    End Sub
    
    ... soll heißen, der Code von @BAGZZlash funktioniert fast eins zu eins, zumindest in einem Stand Alone Script. Wie sich das in deiner Umgebung widerspiegelt, weiß ich nicht. Und natürlich bekommst du eine kleine Verzögerung rein, da die Run Methode einen Powershell Prozess startet, der vom Betriebssystem auch erst mal geplant und geladen werden muss ...
    Zuletzt bearbeitet: 24. Februar 2018