VB6: Kompilierte .exe immer im Vordergrund starten

  • VB6

Es gibt 15 Antworten in diesem Thema. Der letzte Beitrag () ist von wernho.

    VB6: Kompilierte .exe immer im Vordergrund starten

    Ich habe mir zwei Programme geschrieben, das eine ist eine Art von Lesezeichenverwaltung für die Internet-Browser, das andere eine Art Explorer-Aufrufer mit den Laufwerken und Ordnern, die ich am meisten brauche.
    Nun ist es aber so, dass wenn ich mehrere Fenster offen habe und eines der beiden aufrufe, dass diese nicht in den Vordergrund kommen, sondern ich mit Alt-Tab (1x) dorthin wechseln muss. Aufgerufen wird das mit einem Shortcut in meinem G900 Keyboard.

    Wie bitte kann ich es im Code bewerkstelligen, dass beim Aufruf der .exe dieses Programm immer im Vordergrund ist.

    Danke im Voraus.
    Puh, bei VB6 weiß ich es nicht genau, aber das ist eine Einstellung beim Fenster.
    Bei WinForms gibt's dafür die Eigenschaft ​TopMost.

    So unterschiedlich wird es dann nicht sein.
    Andererseits muss man dann auch wissen, dass das Fenster wirklich überall oben ist und nicht mehr in den Hintergrund gerückt werden kann.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)
    @wernho Aus meinem Archiv geholt. Dennoch ist das keine Garantie, das das Fenster immer TopMost bleibt.

    Visual Basic-Quellcode

    1. Option Explicit
    2. Private Declare Function SetWindowPos Lib "user32.dll" ( _
    3. ByVal hwnd As Long, _
    4. ByVal hWndInsertAfter As Long, _
    5. ByVal x As Long, _
    6. ByVal y As Long, _
    7. ByVal cx As Long, _
    8. ByVal cy As Long, _
    9. ByVal wFlags As Long) As Long
    10. Const SWP_NOMOVE = 2
    11. Const SWP_NOSIZE = 1
    12. Const SWP_WNDFLAGS = SWP_NOMOVE Or SWP_NOSIZE
    13. Const HWND_TOPMOST = -1
    14. Const HWND_NOTOPMOST = -2
    15. Private Sub Form_Load()
    16. SetWindowPos Me.hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_WNDFLAGS
    17. End Sub
    Mfg -Franky-
    Danke schön für Eure Tipps.
    Leider ist genau dieser Code bereits enthalten, greift aber leider nicht. Das Fenster liegt des öfteren beim Aufruf an zweiter Stelle und muss mit 1x Alt-TAB geholt werden.
    Wenn es nicht gleich im Vordergrund ist, dann ist es immer an 2. Stelle (glaube ich zumindest).
    @wernho Dann hätte ich da nur noch was per Subclassing. Das hatte ich mal für ein OSK (OnScreenKeyboard) geschrieben das ja auch immer OnTop sein muss. Dazu brauchts ein Modul mit "Sub Main". In den Projekteigenschaften stellst halt anstelle der Form -> Sub Main ein.
    Spoiler anzeigen

    Visual Basic-Quellcode

    1. Option Explicit
    2. Private Const WS_EX_TOPMOST As Long = &H8
    3. Private Const WS_EX_NOACTIVATE As Long = &H8000000
    4. Private Const GWL_EXSTYLE As Long = -20
    5. Private Const GWL_WNDPROC As Long = -4
    6. Private Const HWND_TOPMOST As Long = -1
    7. Private Const SWP_NOSIZE As Long = &H1
    8. Private Const SWP_NOMOVE As Long = &H2
    9. Private Const SWP_NOACTIVATE As Long = &H10
    10. Private Const SW_SHOWNOACTIVATE As Long = 4
    11. Private Const WM_MOVING As Long = &H216
    12. Private Const WM_ACTIVATE As Long = &H6
    13. Private Const WM_ACTIVATEAPP As Long = &H1C
    14. Private Type RECT
    15. Left As Long
    16. Top As Long
    17. Right As Long
    18. Bottom As Long
    19. End Type
    20. Private Declare Function CallWindowProc Lib "user32" _
    21. Alias "CallWindowProcA" ( _
    22. ByVal lpPrevWndFunc As Long, _
    23. ByVal hwnd As Long, _
    24. ByVal Msg As Long, _
    25. ByVal wParam As Long, _
    26. ByVal lParam As Long) As Long
    27. Private Declare Function SetWindowLong Lib "user32" _
    28. Alias "SetWindowLongA" ( _
    29. ByVal hwnd As Long, _
    30. ByVal nIndex As Long, _
    31. ByVal dwNewLong As Long) As Long
    32. Private Declare Function GetWindowLong Lib "user32" _
    33. Alias "GetWindowLongA" ( _
    34. ByVal hwnd As Long, _
    35. ByVal nIndex As Long) As Long
    36. Private Declare Sub SetWindowPos Lib "user32" ( _
    37. ByVal hwnd As Long, _
    38. ByVal hWndInsertAfter As Long, _
    39. ByVal x As Long, _
    40. ByVal y As Long, _
    41. ByVal cx As Long, _
    42. ByVal cy As Long, _
    43. ByVal wFlags As Long)
    44. Private Declare Function ShowWindow Lib "user32" ( _
    45. ByVal hwnd As Long, _
    46. ByVal nCmdShow As Long) As Long
    47. Private Declare Sub CopyMemory Lib "kernel32" _
    48. Alias "RtlMoveMemory" ( _
    49. ByRef Destination As Any, _
    50. ByRef Source As Any, _
    51. ByVal Length As Long)
    52. Private tRect As RECT
    53. Private lngStyle As Long
    54. Private hFrmHwnd As Long
    55. Private lngOldWndProc As Long
    56. Sub Main()
    57. Load frmOSK '<- hier Deine Form
    58. hFrmHwnd = frmOSK.hwnd '<- hWnd von Deiner Form
    59. Call ShowWindow(hFrmHwnd, SW_SHOWNOACTIVATE)
    60. lngStyle = GetWindowLong(hFrmHwnd, GWL_EXSTYLE)
    61. lngStyle = lngStyle Or WS_EX_NOACTIVATE Or WS_EX_TOPMOST
    62. Call SetWindowLong(hFrmHwnd, GWL_EXSTYLE, lngStyle)
    63. Call SetWindowPos(hFrmHwnd, HWND_TOPMOST, 0&, 0&, 0&, 0&, SWP_NOSIZE Or _
    64. SWP_NOMOVE Or SWP_NOACTIVATE)
    65. lngOldWndProc = SetWindowLong(hFrmHwnd, GWL_WNDPROC, AddressOf WindowProc)
    66. End Sub
    67. Public Sub Unhook()
    68. Call SetWindowLong(hFrmHwnd, GWL_WNDPROC, lngOldWndProc)
    69. End Sub
    70. Private Function WindowProc(ByVal hwnd As Long, ByVal uMsg As Long, ByVal wParam As _
    71. Long, ByVal lParam As Long) As Long
    72. If uMsg = WM_MOVING Then
    73. Call CopyMemory(tRect, ByVal lParam, LenB(tRect))
    74. Call SetWindowPos(hFrmHwnd, -1, tRect.Left, tRect.Top, tRect.Right - _
    75. tRect.Left, tRect.Bottom - tRect.Top, 0&)
    76. WindowProc = True
    77. Exit Function
    78. End If
    79. If uMsg = WM_ACTIVATE Or uMsg = WM_ACTIVATEAPP Then
    80. Call SetWindowPos(hFrmHwnd, HWND_TOPMOST, 0&, 0&, 0&, 0&, SWP_NOSIZE Or _
    81. SWP_NOMOVE Or SWP_NOACTIVATE)
    82. End If
    83. WindowProc = CallWindowProc(lngOldWndProc, hwnd, uMsg, wParam, lParam)
    84. End Function


    Die "Sub Unhook()" rufst dann in Deinem Form_Unload auf. Ich muss aber dazu sagen das ich auf der Form keine Controls hatte und alle Button auf der Form gezeichnet wurden.
    Mfg -Franky-

    wernho schrieb:

    Aufgerufen wird das mit einem Shortcut in meinem G900 Keyboard

    Mich würde es nicht wundern, wenn in so einem Fall Windows selbst entscheidet, dass die Anwendung sich nicht einfach nach vorne morgeln darf. Ist das auch so, wenn du die Anwendung mit eigens ausgeführtem Klick startest?
    Besucht auch mein anderes Forum:
    Das Amateurfilm-Forum
    @-Franky-:
    Ich habe es mal neu kompiliert und werde nun den Befehl am Keyboard austauschen. Mal sehen, was passiert.
    edit:
    Also das Fenster bleibt immer im Vordergrund, da kann ich auch andere Fenster ansteuern, die kommen dann nicht. Aber das passt, denn wenn ich das aufrufe, dann wird dort sofort etwas getan. War noch nie anders. Somit ist das eine gute Lösung. Danke schön.

    @Marcus Gräfe:
    Muss ich erst mal schauen, denn es ist nicht immer so. Wenn ich beim nächsten Mal wieder mit dem Fenster hinten bin, werde ich es schließen und danach mittel Verknüpfung aufrufen.
    Die Verknüpfung ist im Startmenü und vom Keyboard wird es mittels Befehl aufgerufen. Heißt: Auf der Taste G4 am Keyboard (die Tastatur hat einige Zusatztasten) ist der Befehl zum Aufrufen hinterlegt: "E:/Dateien/VisualBasic/ExplorerAufrufen/ExplorerAufrufen.exe"
    edit:
    Hat sich somit erledigt, da die Lösung von @-Franky- funktioniert. Danke schön.

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „wernho“ ()

    @-Franky-:
    Ich muss zugeben, dass ich es nicht ganz verstehe.
    Ich habe zwar die Positionen gesehen (0, 0, 0, 0) und auch SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE.
    Aber ich habe das Fenster normalerweise in der Mitte.
    Wie bitte kann ich das bewerkstelligen?

    edit:
    Großes Problem: ich habe Dropdowns in meiner Form, diese können nicht mehr benutzt werden, klappen nicht auf. :/

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „wernho“ ()

    wernho schrieb:

    Aber ich habe das Fenster normalerweise in der Mitte.

    Dazu kannst Du in der "Sub Main" einfach folgendes ändern.

    Visual Basic-Quellcode

    1. 'Call SetWindowPos(hFrmHwnd, HWND_TOPMOST, 0&, 0&, 0&, 0&, SWP_NOSIZE Or SWP_NOMOVE Or SWP_NOACTIVATE)
    2. Call SetWindowPos(hFrmHwnd, HWND_TOPMOST, 300&, 300&, 0&, 0&, SWP_NOSIZE Or SWP_NOACTIVATE)

    Die 300& ist hier nur als Beispiel für die Top/Left-Position der Form auf dem Screen.

    wernho schrieb:

    Großes Problem: ich habe Dropdowns in meiner Form, diese können nicht mehr benutzt werden, klappen nicht auf

    Das kann ich nicht nachvollziehen.
    Bilder
    • Test.png

      4,74 kB, 313×165, 10 mal angesehen
    Mfg -Franky-
    Danke, hat funktioniert.
    Und das mit den Dropdowns bin ich auch schon draufgekommen:
    sie klappen zwar auf, sind aber hinter der Form. Bin auch nur deswegen draufgekommen, weil ich eines der unteren angeklickt habe.
    Screenshot:
    @wernho Du kannst auch hier Bilder/Anhänge hochladen. Das geht über "Erweiterte Antwort". Hmm, wenn ich mir Dein Bild so anschau, sind das die Standard-Comboboxen von VB6, machst Du ein Ownerdraw auf die Comboboxen oder sind das Drittanbieter-Controls? Weil der Button zum aufklappen der Combobox ist schmaler und hat eine andere Farbe.
    Mfg -Franky-
    Danke, ich habe es nicht gefunden, wo ich Bilder einfügen kann. Normalerweise bin ich nicht so unbedarft ;)

    Ja, es ist ein Drittanbieter, ich habe mir vor längerer Zeit schon die sev-Development Tools gekauft.
    Und ich habe eine normale Combobox testweise eingebaut, und diese funktioniert.
    Ok, muss ich mit etwas einfallen lasse: entweder ich baue das ganze um auf normale Comboboxen oder ich muss eine Lösung für meine Comboboxen finden.

    Und vielen lieben Dank für Deine Bemühungen und die Zeit, die Du mir geopfert hast.
    Hi @wernho
    ich kenne das Problam aus meinen VB6 Zeiten und habe vor 25 Jahren eine Lösung dafür gebaut.
    Habe ewig daran gefummelt.
    Ich schaue haute Abend mal nach dem alten Code und poste dir dann die Lösung, wenn ich den Code noch finde.
    Es war iegendwie was, mit manuellem Legen des Fensters ganz oben auf den Stapel der offenen Fenstern, wenn ich mich recht erinnere...

    EDIT: Ah, meine Anwot hat sich erledigt - Franky hat ja schon den Weg gewiesen... ;)
    So, jetzt ist es erledigt.
    Genau das, was @-Franky-/Ihr mir beschrieben habt, habe ich nun auch auf der Seite von vb@rchive, wo ich die Zusatzkomponenten gekauft habe, gefunden.
    Dort wird das ganze mit einer Function aufgerufen: FormOnTop. Das Ganze mit dem Parameter True or False.
    Zwar bleibt mir, wenn ich auf True gehe, auch meine eigenen Comboboxen im Hintergrund, ABER: wenn ich sofort danach das Ganze auf False setze, sind die Comboboxen wieder zur Gänze sichtbar.
    Also rufe ich das Ganze mit True auf, bringe somit das Fenster in den Vordergrund und gleich danach auf False, Fenster bleibt im Vordergrund und meine Comboboxen sind sichtbar.

    Ich danke Euch recht herzlich, denn Ihr habt mich auf den richtigen Weg gebracht, jetzt funktioniert es.