Die Community zu .NET und Classic VB.
Menü

VB 5/6-Tipp 0007: Fenster immer oben halten

 von 

Beschreibung 

Dieser Tipp hält ein frei wählbares Fenster immer über den anderen geöffneten
Fenstern.

Update von Bernhard Gertz ( ): Der Tipp
funktioniert jetzt mit allen Betriebsystemen und umgeht auch die Probleme die manchmal unter Windows XP auftraten (Das Fenster rutschte manchmal in den Hintergrund).

Schwierigkeitsgrad:

Schwierigkeitsgrad 1

Verwendete API-Aufrufe:

SetWindowPos

Download:

Download des Beispielprojektes [2,02 KB]

'Dieser Quellcode stammt von http://www.activevb.de
'und kann frei verwendet werden. Für eventuelle Schäden
'wird nicht gehaftet.

'Um Fehler oder Fragen zu klären, nutzen Sie bitte unser Forum.
'Ansonsten viel Spaß und Erfolg mit diesem Source!

'------------- Anfang Projektdatei Projekt1.vbp -------------
'--------- Anfang Formular "Form1" alias Form1.frm  ---------
' Steuerelement: Timersteuerelement "Timer1"
' Steuerelement: Kontrollkästchen-Steuerelement "Check1"

Option Explicit

'Deklaration: Globale Form API-Konstanten
Private Const SWP_NOMOVE As Long = &H2
Private Const SWP_NOSIZE As Long = &H1
Private Const HWND_TOPMOST As Long = -1&
Private Const HWND_NOTOPMOST As Long = -2&

'Deklaration: Globale Form API-Funktionen
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()
    'Control-Eigenschaften initialisieren
    Check1.Caption = "Fenster obenhalten"
    Check1.Value = vbChecked
    Timer1.Interval = 250
    Timer1.Enabled = True
End Sub

Private Sub Check1_Click()
    If Check1.Value = vbChecked Then
        'Fenster im Vordergrund halten
        SetWindowPos hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE
        Timer1.Enabled = True
    Else
        'Fenster kann von anderen Fensters überdeckt werden
        SetWindowPos hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE
        Timer1.Enabled = False
    End If
End Sub

Private Sub Timer1_Timer()
    'Wirkt einem Bug entgegen: Der Wert wird regelmäßig aktualisiert
    Call Check1_Click
End Sub
'---------- Ende Formular "Form1" alias Form1.frm  ----------
'-------------- Ende Projektdatei Projekt1.vbp --------------

Tipp-Kompatibilität:

Windows/VB-VersionWin32sWin95Win98WinMEWinNT4Win2000WinXP
VB4
VB5
VB6

Hat dieser Tipp auf Ihrem Betriebsystem und mit Ihrer VB-Version funktioniert?

Ja, funktioniert!

Nein, funktioniert nicht bei mir!

VB-Version:

Windows-Version:

Ihre Meinung  

Falls Sie Fragen zu diesem Artikel haben oder Ihre Erfahrung mit anderen Nutzern austauschen möchten, dann teilen Sie uns diese bitte in einem der unten vorhandenen Themen oder über einen neuen Beitrag mit. Hierzu können sie einfach einen Beitrag in einem zum Thema passenden Forum anlegen, welcher automatisch mit dieser Seite verknüpft wird.

Archivierte Nutzerkommentare 

Klicken Sie diesen Text an, wenn Sie die 26 archivierten Kommentare ansehen möchten.
Diese stammen noch von der Zeit, als es noch keine direkte Forenunterstützung für Fragen und Kommentare zu einzelnen Artikeln gab.
Aus Gründen der Vollständigkeit können Sie sich die ausgeblendeten Kommentare zu diesem Artikel aber gerne weiterhin ansehen.

Kommentar von Jonathan am 01.11.2007 um 22:44

Ich halte den Timer auch für sinnlos.

Natürlich mag es andere Forms geben, die auch gerne im Vordergrund sein sollen. Dann sollte man aber keine nTimer einsetzen.

Stellt euch mal vor, mehrere Programme mchen das so, dann flackerts immer schon zwischen beiden Programmen hin und her.

SetWindowPos hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + _
SWP_NOSIZE

und

SetWindowPos hwnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE + _
SWP_NOSIZE

reicht völlig als Tipp. das würde ich dann allerdings noch in separate Subs packen.

Kommentar von js am 02.07.2007 um 00:22

Dass der Timer tatsächlich nur dafür sorgt, dass sich das Form vor alle Fenster "drängt" ist schlecht weil die anderen Fenster möglicherweise einen Grund haben, warum sie im Vordergrund sein wollen wie z.B. der Taskmanager etc...

Kommentar von Dirk am 28.05.2007 um 13:30

Mir ist gerade aufgefallen, dass dieser Code das Lost_Focus-Event der Form außer Gefecht setzt. (Zumindest unter VB6).
Sollte man evtl. beachten, wenn man die Form so wieder loswerden wollte...

Kommentar von Jochen Wierum am 18.02.2007 um 17:11

Hallo mike, Hallo JMR,

man kann mit Findwindow, GetWindowund SetParent schon einiges machen. Zumindest auf den Desktop und vor die Icons bekommst du damit normale Controls gesetzt:

dhwnd = GetWindow(FindWindow("Progman", "Program Manager"), GW_CHILD)
SetParent(Picturebox1.hWnd, dhwnd)


Ansonsten kannst du natürlich auch das Hintergrundbild manipulieren, dann aber ohne Controls. Also prinzipiell ist zumindest die Richtung machbar...

Mit freundlichen Grüßen
Jochen

Kommentar von JMR am 18.02.2007 um 13:00

ähhh bitte? zwischen Desktop und Desktopicons?? nein, gar keine chance. du könntest dich da höchstens, vielleicht, möglicherweise als ActiveDesktop Applikation zwischen schummeln. aber an sich ises unmöglich sich zwischen die Icons auf dem Desktop und dem Desktophintergrund zu setzen. schlicht und einfach, weil die Icons Teil des Desktops sin....

Kommentar von mikeb69 am 16.02.2007 um 18:53

hallo,

kann ein fenster auch IMMER UNTEN gehalten werden ?
am besten zwischen dem wallpaper und den programm icons ?

danke

mikeb69

Kommentar von Carsten Jahner am 07.07.2005 um 12:22

Ups. Da hat sich ein kleiner Fehler eingeschlichen.
Es muss natürlich heißen:

Private Const GWL_HWNDPARENT As Long = (-8)

Public Sub SetParent(Parent As Long, Child As Long)
SetWindowLong Parent, GWL_HWNDPARENT, Child
End Sub

Kommentar von Carsten Jahner am 07.07.2005 um 09:12

Eine meiner Meinung nach elegantere Lösung ein Fenster immer oben zu halten, also auch wenn es mal gerade nicht den Focus hat zeigt folgender Code:

Das wird in einem Modul benötigt:

Private Const GWL_HWNDPARENT As Long = (-8)

Public Sub SetParent(Parent As Form, Child As Form)
SetWindowLong Parent.hWnd, GWL_HWNDPARENT, Child.hWnd
End Sub


Das aufzurufende Fenster kann dann z.B. über folgende Methode angezeigt werden.

Public Sub ShowForm(ParentHwnd As Long)
SetParent ParentHwnd, me.Hwnd
me.Show vbModeless
End Sub


Als Ergebnis hat man dann ein Fenster welches innerhalb der Applikation dauerhaft im Vordergrund steht.

Kommentar von Richie198 am 31.05.2005 um 15:05

Und wie kann ich das ganze in Access 97 einbauen? mit 2000 funktioniert das ja einwandfrei, doch das bringt mir nicht viel :(

Kommentar von Johannes Roth am 29.03.2005 um 16:17

Warum ein Timer? Na vielleicht weil auch andere Programme auf die wunderbare Idee kommen und sich in den Vordergrund drängen wollen!?
Deswegen!

Kommentar von Timon am 29.03.2005 um 10:40

warum ein timer? geht auch einfach mit
SetWindowPos Me.hwnd, -1, 0, 0, 0, 0, 1 Or 2
in Form_Load() (wie Jens schon gesagt hat!)

..die form ist dann natürlich nicht aktiv und hintert auch nicht beim arbeiten in outlook usw.

Kommentar von Michael G am 28.01.2005 um 17:20

Hallo zusammen,

ich suche eine Lösung, um eine MsgBox von Excel in den Vordergrund ausgeben zu lassen, auch wenn ich in einer anderen Anwendung, z.B. in Word, arbeite. Mir wurde das obige Listing empfohlen, ich bin mir aber nicht sicher, ob es paßt, weil meine Kenntnisse noch nicht so weit reichen.

Ich arbeite mit Win XP und Excel 2002, bzw. VBA. Kann ich das Listing dafür überhaupt verwenden?

Danke & Ciao,

Michael

Kommentar von Zechi am 25.08.2004 um 10:00

Hallo!

Funkt bei mir wunderbar! Ich habe einen Timer der immer die aktuelle Zeit einträgt. Hab auch kein Problem mit anderen Programmen AUSSER mit OUTLOOK. Das verliert immer den Focus und das macht das arbeiten natürlich ein bissl schwierig. Gibts da eine Lösung??????

Kommentar von Eizvber am 24.07.2004 um 12:43

Dass das Fenster nicht immer im Vordergrund ist, ist kein Bug, denn wenn ein anderes Fenster auch diese Art von Fenster oben Benutzt, hebt sich das gegenseitig auf, da beide die gleiche Ebene haben. Oder ist das ein anderer Bug der gemeint ist?

Kommentar von Jens am 11.06.2004 um 22:45

Hm, ich halte die Fenster einfach mit diesem Aufruf oben

SetWindowPos Me.hwnd, -1, 0, 0, 0, 0, 1 Or 2

Wieso verwendet Ihr einen Timer ???

Kommentar von Jens am 11.06.2004 um 22:45

Hm, ich halte die Fenster einfach mit diesem Aufruf oben

SetWindowPos Me.hwnd, -1, 0, 0, 0, 0, 1 Or 2

Wieso verwendet Ihr einen Timer ???

Kommentar von Johannes Roth am 10.01.2004 um 18:28

Also um hier mal was klar zu stellen:
dieser Tipp zeigt wie man ein Fenster windowsweit in den Vordergrund setzt!
Der von Christian Eckler gezeigte Code setzt nur Projektweit eine Form in den Vordergrund.
Man kann aber nicht sagen das einer "besser" oder "schlechter" ist, das kommt immer auf die Anwendung an. Es ist ja auch gut denkbar das man ein Fenster windowsweit in den Vordergrund rücken will!!

Kommentar von Bernhard am 06.08.2003 um 15:44

Hi,

ich habe die Funktion modifiziert und an ActiveVB geschickt. Leider wurde bis jetzt der Tipp nicht aktualisiert.

Grüße

Bernhard

Kommentar von ShinnocK am 18.12.2002 um 14:53

Täusch' ich mich oder funzt das Setzen von TOPMOST im Form_Load nicht !?

Erst wenn die Option 1x ab- und wieder angehakt ist, bleibt das Fenster wirklich oben...

System: Win2000 Pro
VB: 6 Enterprise

Kommentar von Klaus am 18.10.2002 um 08:05

Hallo
Win2000, VB6
Die Form bleibt oben, ist aber nicht aktiv, wie mache ich das?

Kommentar von Alex am 14.10.2002 um 12:06

@ Climax: Die frmSub wird eben NICHT mit frmSub.show 1, frmMain oben gehalten, da vbModeless 0 ist und nicht 1... Und modal ist es nur, wenn es mit show 1 angezeigt wird... Right! Shit happens... ;-)

Kommentar von Alex am 14.06.2002 um 20:42

@ Christian Eckler: Wo muss ich das denn einfügen??

Kommentar von Thomas Kehne am 26.12.2001 um 02:29

Ich hätte ja gerne oben durch anklicken bestätigt, dass der Tip auch unter Windows XP funktioniert. Leider gibt es dafür noch keine Checkbox. Den Hinweis von Mirko sollte man allerdings ernst nehmen. Der Durchschnitt-User kommt wahrscheinlich nicht auf die Idee hinter das im Vordergrund liegende Fenster zu schauen, wenn es Probleme gibt.

Kommentar von Mirko am 24.11.2001 um 13:06

Der Tip von Christian Eckler ist echt besser für Programminterne Fenster. Wenn man o. genannten Code verwendet, steht das Fenster wirklich immer im Vordergrund, und das nicht nur Programmintern sondern Winwos-übergreifend. Wenn jetzt eine Fehlermeldung erscheint (Msgbox) sieht man diese nicht mehr. Also sollte man vorher wissen wofür man diesen Code verwendet.
Mirko

Kommentar von Climax am 03.05.2001 um 11:28

@ Christian Eckler
Ein Fenster mit frmSub.Show 1, frmMain oben zu halten ist wohl nicht der Sinn der Sache, da Du es ja dann modal anzeigst.
Shit happens... ;o)

Kommentar von Christian Eckler am 01.04.2001 um 09:03

Ein Fenster immer oben halten geht unter VB6 auch wesentlich billiger.
FrmMain.Show
FrmSub.Show vbModeless,FrmMain
Fertig....