Form immer im Hintergrund

Hallo!
Wie kann ich einer Form ein „Attribut“ zuweisen, sodass sie immer im Hintergrund ist?
Konkret: Mein Programm, ein Terminplaner, soll direkt auf dem Desktop liegen und muss immer das unterste Programm sein; es soll nämlich so wirken, als wäre es in den Desktopbereich fest integriert.
Irgendwo hab ich einen entsprechenden Code gefunden, der Code macht aber gar nix; Fehler bei Compilieren gibt es nicht, aber er macht eben nix…

Schon mal vielen Dank falls mir da jemand weiterhelfen kann,
Nina


Option Explicit

Private Const HWND_TOP = 0
Private Const HWND_TOPMOST = -1
Private Const HWND_NOTOPMOST = -2
Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE

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 Sub Form_Load()
Call StayNotOnTop(Form1)
End Sub

Sub StayNotOnTop(the As Form)
Call SetWindowPos(the.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)
End Sub

Call SetWindowPos(the.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)

…so weit so gut … verwende statt HWND_NOTOPMOST

Private Const HWND\_BOTTOM = 1

dann verschwindet Dein Fensterl auch wirklich in den Hintergrund.

Das ganze ist aber eine einmalige Sache, denn wenn Du auf das Fenster klickst schiebt es sich wieder in den Vordergrund. Abhilfe würde da z.B. ein Timer schaffen, der alle 100ms die Funktion SetWindowPos() aufruft.

Wäre cool, wenn es dafür eine etwas elegantere Lösung gäbe!!!

greets from michL (vienna)

Hallo Michael!

Das ganze ist aber eine einmalige Sache, denn wenn Du auf das
Fenster klickst schiebt es sich wieder in den Vordergrund.
Abhilfe würde da z.B. ein Timer schaffen, der alle 100ms die
Funktion SetWindowPos() aufruft.

Bei einer „Form-in-den-Vordergrund-Methode“, die ich in einem anderen Projekt schonmal verwendet habe, ist es aber so, dass die Form wirklich IMMER im Vordergrund liegt, auch wenn sie nicht den Fokus hat. Andere Forms können ganz normal angeklickt werden und auf Eingaben reagieren, aber sie bleiben dennoch immer hinter der Form, die die „Form-in-den-Vordergrund-Methode“ drin hat.
Analog sollte es auch mit der „Form-in-den-HINTERGRUND“-Methode funktionieren…

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
Sub AlwaysOnTop(F As Form, OnTop As Boolean)
'Sub AlwaysOnTop(F As Form)
'OnTop = True: Fenster immer im Vordergrund
'OnTop = False: Fenster immer im Hintergrund
Dim Switch As Integer
If OnTop Then
Switch = -1 'im Vordergrund
Else
Switch = -2 'nicht im Vordergrund
End If
Call SetWindowPos(F.hwnd, Switch, 0, 0, 0, 0, &H53)
End Sub

Private Sub Form_Load()
Call AlwaysOnTop(Form1, True)
End Sub

Call SetWindowPos(the.hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, FLAGS)

…so weit so gut … verwende statt
HWND_NOTOPMOST

Private Const HWND_BOTTOM = 1

dann
verschwindet Dein Fensterl auch wirklich in den Hintergrund.

Ich hab jetzt den Code abgeändert auf (siehe unten), aber es macht wieder nixxx! :frowning:
Was ist das bloß?!

Gruß,
Nina


Option Explicit

Private Const HWND_TOP = 0
Private Const HWND_TOPMOST = -1
Private Const HWND_BOTTOM = 1

Private Const SWP_NOMOVE = &H2
Private Const SWP_NOSIZE = &H1
Private Const FLAGS = SWP_NOMOVE Or SWP_NOSIZE

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 Sub Form_Load()
Call StayNotOnTop(Form1)
End Sub

Sub StayNotOnTop(the As Form)
Call SetWindowPos(the.hWnd, HWND_BOTTOM, 0, 0, 0, 0, FLAGS)
End Sub

Mein Coding:

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 Const SWP\_NOMOVE = &H2
Private Const SWP\_NOSIZE = &H1
Private Const HWND\_BOTTOM = 1
'
Call SetWindowPos(Me.hwnd, HWND\_BOTTOM, 0, 0, 0, 0, SWP\_NOMOVE Or SWP\_NOSIZE)

Du hast recht, die Always-On-Top G’schichte bleibt immer „On-Top“, leider scheint es aber kein „Always-At-Bottom“ zu geben!!

greets from michL (vienna)

Private Sub Form_Load()
Call StayNotOnTop(Form1)
End Sub

übrigens … der Grund, warums bei Dir wahrscheinlich nicht geht ist, weil Du „es“ im Form_Load() machst und da ist das Form ja noch gar nicht sichtbar!!! —>

Private Sub Form\_Load()
Me.Show
Call StayNotOnTop(Form1)
End Sub

wird wahrscheinlich funktionieren!

greets from michL

1 Like

Thanks!

übrigens … der Grund, warums bei Dir wahrscheinlich nicht
geht ist, weil Du „es“ im Form_Load() machst und da ist das
Form ja noch gar nicht sichtbar!!! —>

Private Sub
Form_Load()
Me.Show
Call StayNotOnTop(Form1)
End Sub

wird wahrscheinlich funktionieren!

greets from michL

Yep, funktioniert! Danke!
Den Rest werd ich dann noch per Timer erledigen!
Dass es keine „Always-At-Bottom“ gibt, ist gut möglich - „Always-At-Top“ macht ja in diversen Fällen Sinn, aber das andere braucht man ja kaum mal (außer jetzt mal in meinem Fall :wink:)
Ohne die in-den-Hintergrund-stell-Funktion wär mein Programm ziemlich wertlos (soll nämlich eine Ergänzung zum Desktop sein, mit quasi in den Desktop eingebautem Terminplaner).

Gruß,
Nina