Microsoft Excel

Herbers Excel/VBA-Archiv

Userform nur beim Start in den Vordergrund


Betrifft: Userform nur beim Start in den Vordergrund
von: Sandro L
Geschrieben am: 30.11.2018 00:13:42

Hallo liebe Experten!

Ich stehe vor folgendem Problem:

Ich habe eine VBA Arbeitsmappe erstellt, bei der beim öffnnen direkt die Userform erscheint und Excel im Hintergrund verschwindet. Ich möchte, dass es möglichst nach einem "echten Windowsprogramm" ausschaut, brauche aber excel zur Datenverarbeitung da ich mich in Visual Basic nicht mit Datenbankzugriffen etc auskenne.

Soweit funktioniert alles sehr gut und nach meinen Vorstellungen, der Endanwender sollte mit der originalen Exceltabelle nicht in berührung kommen.

Allerding ist mir aufgefallen, dass wenn ich "das Programm" geöffnet habe, es immer hinter allen momentan aktiven Fenstern verschwunden ist. Daraufhin habe ich mich auf die Suche gemacht nach einem Code der dies behebt und bin halbwegs fündig geworden.
Den Code den ich gefunden habe lässt meine Userform immer im Vordergrund erscheinen auch wenn ich z.b. den Windows Explorer öffne.
Könnte man den Code so anpassen dass er zwar beim start der "Anwendung" die Userform in den Vordergrund zwingt, aber danach hinter andere Fenster verschwindet wenn ich zum Beispiel den Windows Explorer öffne?

Hier der Code:

Option Explicit

Private Declare PtrSafe Function SetWindowPos Lib "user32.dll" ( _
ByVal hwnd As LongPtr, _
ByVal hWndInsertAfter As LongPtr, _
ByVal x As Long, _
ByVal y As Long, _
ByVal cx As Long, _
ByVal cy As Long, _
ByVal wFlags As Long) As Long
Private Declare PtrSafe Function FindWindowA Lib "user32.dll" ( _
ByVal lpClassName As String, _
ByVal lpWindowName As String) As LongPtr

Private Const HWND_TOPMOST As LongPtr = -1
Private Const SWP_NOSIZE As Long = &H1
Private Const SWP_NOMOVE As Long = &H2
Private Const GC_CLASSNAMEUSERFORM As String = "ThunderDFrame"

Private Sub UserForm_Activate()
    Dim lngptrHwnd As LongPtr
    lngptrHwnd = FindWindowA(GC_CLASSNAMEUSERFORM, Caption)
    Call SetWindowPos(lngptrHwnd, HWND_TOPMOST, _
        0&, 0&, 0&, 0&, SWP_NOMOVE Or SWP_NOSIZE)
End Sub
Da ich gerne was dazu lernen möchte, bitte ich euch die Änderung dann zu erläutern
damit ich den Code auch einigermaßen verstehe und ihn in Zukunft gegebenfalls selber anpassen kann je nach Bedürfnis.

Ich danke euch schon mal im vorraus!

  

Betrifft: AW: Userform nur beim Start in den Vordergrund
von: Karl-Heinz Voltmann
Geschrieben am: 30.11.2018 08:38:51

Hallo Sandro,

es gibt auch den Parameter Const HWND_NOTOPMOST = -2.

Ich denke mal, mit dem kannst Du das wieder ändern.
Call SetWindowPos(lngptrHwnd, HWND_NOTTOPMOST, _
0&, 0&, 0&, 0&, SWP_NOMOVE Or SWP_NOSIZE)

viele Grüße
Karl-Heinz


  

Betrifft: AW: Userform nur beim Start in den Vordergrund
von: Karl-Heinz Voltmann
Geschrieben am: 30.11.2018 08:53:55

Hallo Sandro,

evtl. kannst Du auch mal diese Funktion hier ausprobieren.

Declare PtrSafe Function BringWindowToTop Lib "user32" Alias "BringWindowToTop" (ByVal hwnd As LongPtr) As Long

BringWindowToTop lngptrHwnd

Habe ich zwar noch nicht benutzt, müsste aber Dein Fenster einmalig in den Vordergrund bringen.

Oder diese hier, die nehme ich immer um ein Fenster in den Vordergrund zu setzen:
Declare PtrSafe Function SetForegroundWindow Lib "user32" (ByVal hWnd As LongPtr) As Long

SetForegroundWindow lngptrHwnd

Probier's einfach mal aus.

viele Grüße
Karl-Heinz


  

Betrifft: AW: Userform nur beim Start in den Vordergrund
von: Sandro L
Geschrieben am: 30.11.2018 09:20:18

Vielen Dank für deine Mühen Karl-Heinz!

Dein erster Vorschlag hat mich auf den richtigen Weg gebracht :)

mit dem Parameter Const HWND_NOTOPMOST = -2. ist leider meine Userform beim starten im Hintergrund geblieben.
Deshalb habe ich mir gedacht einfach erst HWND_TOPMOST = -1 auszuführen damit das Fenster auf jeden Fall in den Vordergrund kommt beim Start und dann zeitverzögert die anweisung HWND_NOTOPMOST.
So funktioniert es wie es soll, beim Start erscheint das Fenster im Vordergrund und nach der von mir eingestellten Zeit ist es möglich andere fenster vor meinen in den Vordergrund zu stellen.

Hier noch mein Lösungscode:

Option Explicit


Private Const SWP_NOSIZE = &H1
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOACTIVATE = &H10
Private Const SWP_SHOWWINDOW = &H40
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2

#If Win64 Then
Private Declare PtrSafe Function SetWindowPos Lib "user32" ( _
ByVal hwnd As LongPtr, ByVal hWndInsertAfter As LongPtr, _
ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long
Private Declare PtrSafe Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
#Else
Private Declare Function SetWindowPos Lib "user32" ( _
ByVal hwnd As Long, ByVal hWndInsertAfter As Long, _
ByVal x As Long, ByVal y As Long, ByVal cx As Long, ByVal cy As Long, _
ByVal wFlags As Long) As Long
Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" ( _
ByVal lpClassName As String, ByVal lpWindowName As String) As Long
#End If

Private Sub UserForm_Activate()
   
   
   #If Win64 Then
  Dim hwnd As LongPtr
#Else
  Dim hwnd As Long
#End If
  hwnd = FindWindow("ThunderDFrame", Me.Caption)
  SetWindowPos hwnd, HWND_TOPMOST, 0, 0, 0, 0, _
    SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE
    
Application.Wait Now + TimeSerial(0, 0, 1) '1 sekunden Pause

  SetWindowPos hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, _
    SWP_NOACTIVATE Or SWP_SHOWWINDOW Or SWP_NOMOVE Or SWP_NOSIZE

End Sub

Danke nochmals für die Hilfe!


  

Betrifft: AW: Userform nur beim Start in den Vordergrund
von: Karl-Heinz Voltmann
Geschrieben am: 30.11.2018 11:01:14

Schön, dass es Dich weitergebracht hat und danke für die Rückmeldung.

VG KH