Fenster im Vordergrund

#1
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
 

BAGZZlash

Well-Known Member
#2
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
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
 

BAGZZlash

Well-Known Member
#4
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".
 

German

Well-Known Member
c-b Experte
#5
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
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.
 

German

Well-Known Member
c-b Experte
#7
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
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.
 

German

Well-Known Member
c-b Experte
#9
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
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.
 

German

Well-Known Member
c-b Experte
#11
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
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
 

German

Well-Known Member
c-b Experte
#15
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:
Oben