Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
setting program to display always on top of other windows without having the focus?
#6
(05-17-2024, 11:27 PM)SMcNeill Wrote: https://qb64phoenix.com/qb64wiki/index.p...ost_Window
Fantastic!

Now once the program window is set to always be in the foreground, how would you change it back to a normal window? 

I tried modifying my programs so 
a window stays on top (HWND_TOPMOST) when the user presses the "a" key, 
and goes back to normal (HWND_NOTOPMOST) when they press "b", 
but it doesn't seem to be working...

Program #1 (blue):
Code: (Select All)
' McNeill - Super Moderator
' #2
' 05-17-2024, 07:27 PM (This post was last modified: 05-17-2024, 07:28 PM by SMcNeill.)
' https://qb64phoenix.com/qb64wiki/index.php/Windows_Libraries#Top_Most_Window

' public domain
Const cProgName = "Program #1": _Title cProgName
Const FALSE = 0: Const TRUE = Not FALSE

' TEXT MODE COLORS:
Const cBlack = 0: Const cBlue = 1: Const cGreen = 2: Const cLtBlue = 3
Const cRed = 4: Const cPurple = 5: Const cOrange = 6: Const cWhite = 7
Const cGray = 8: Const cPeriwinkle = 9: Const cLtGreen = 10: Const cCyan = 11
Const cLtRed = 12: Const cPink = 13: Const cYellow = 14: Const cLtGray = 15

Const SWP_NOSIZE = &H0001 'ignores cx and cy size parameters
Const SWP_NOMOVE = &H0002 'ignores x and y position parameters
Const SWP_NOZORDER = &H0004 'keeps z order and ignores hWndInsertAfter parameter
Const SWP_NOREDRAW = &H0008 'does not redraw window changes
Const SWP_NOACTIVATE = &H0010 'does not activate window
Const SWP_FRAMECHANGED = &H0020
Const SWP_SHOWWINDOW = &H0040
Const SWP_HIDEWINDOW = &H0080
Const SWP_NOCOPYBITS = &H0100
Const SWP_NOOWNERZORDER = &H0200
Const SWP_NOSENDCHANGING = &H0400
Const SWP_DRAWFRAME = SWP_FRAMECHANGED
Const SWP_NOREPOSITION = SWP_NOOWNERZORDER
Const SWP_DEFERERASE = &H2000
Const SWP_ASYNCWINDOWPOS = &H4000
Const HWND_TOP = 0 'window at top of z order no focus
Const HWND_BOTTOM = 1 'window at bottom of z order no focus
Const HWND_TOPMOST = -1 'window above all others no focus unless active
Const HWND_NOTOPMOST = -2 'window below active no focus

Declare Dynamic Library "user32"
    Function FindWindowA%& (ByVal lpClassName%&, Byval lpWindowName%&)
    Function SetWindowPos& (ByVal hWnd%&, Byval hWndInsertAfter%&, Byval X&, Byval Y&, Byval cx&, Byval cy&, Byval uFlags~&)
    Function GetForegroundWindow%&
End Declare

Declare Dynamic Library "kernel32"
    Function GetLastError~& ()
End Declare

Dim t As String
Dim hWnd As _Offset
Dim iLoop As Integer
Dim bOnTop As Integer: bOnTop = FALSE

Screen 12 ' SCREEN 12 can use 16 color attributes with a black background. 256K possible RGB color hues. Background colors can be used with QB64.
Cls , cBlue
Color cWhite, cBlue

Randomize Timer
t = Hex$(Rnd * &H1000000) ' random title for FindWindowA
_Title cProgName + t ' _Trim$(Str$(t))
t = t + Chr$(0)
hWnd = _WindowHandle ' FindWindowA(0, _OFFSET(t))
_Title cProgName + t + ": This Window will always be on Top" ' any title

_Delay 4 ' delay allows user to click focus on other windows

' set as topmost window and move without sizing or activation
If 0 = SetWindowPos(hWnd, HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) Then
    Print "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
End If

x%& = GetForegroundWindow%& ' find currently focused process handle

Print "Program handle:"; hWnd; "Focus handle:"; x%&

If hWnd <> x%& Then
    _ScreenClick 240, 240 ' add 40 to x and y to focus on positioned window
End If

Locate 5, 20 ' y,x where 1,1 = top left
Print cProgName
Locate 10, 20
Print "Press A to stay on top, B for background"
Locate 25, 20 ' y,x where 1,1 = top left
Print "Hold down ESC to exit."
For iLoop = 10000 To 0 Step -1
    Locate 15, 20
    Print IIFSTR$(bOnTop, "STAY ON TOP", "BACKGROUND ")
    Locate 20, 20 ' y,x where 1,1 = top left
    Print _Trim$(Str$(iLoop)) + "     "

    While _DeviceInput(1): Wend ' clear and update the keyboard buffer
    If _KeyDown(Asc("a")) Or _KeyDown(Asc("A")) Then
        bOnTop = TRUE
        '(ENABLE ALWAYS STAY ON TOP)
       
        ' set as topmost window and move without sizing or activation
        If 0 = SetWindowPos(hWnd, HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) Then
            Locate 1, 1
            Print "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
        End If
       
    ElseIf _KeyDown(Asc("b")) Or _KeyDown(Asc("B")) Then
        bOnTop = FALSE
        '(DISABLE ALWAYS STAY ON TOP)
       
        ' set as topmost window and move without sizing or activation
        If 0 = SetWindowPos(hWnd, HWND_NOTOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) Then
            Locate 1, 1
            Print "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
        End If
       
    End If
    If _KeyDown(27) Then Exit For ' leave loop when ESC key pressed
    _Limit 4 ' keep loop at 4 frames per second
Next iLoop
End

Function IIF (Condition, IfTrue, IfFalse)
    If Condition Then IIF = IfTrue Else IIF = IfFalse
End Function
Function IIFSTR$ (Condition, IfTrue$, IfFalse$)
    If Condition Then IIFSTR$ = IfTrue$ Else IIFSTR$ = IfFalse$
End Function

Program #2 (red):
Code: (Select All)
' McNeill - Super Moderator
' #2
' 05-17-2024, 07:27 PM (This post was last modified: 05-17-2024, 07:28 PM by SMcNeill.)
' https://qb64phoenix.com/qb64wiki/index.php/Windows_Libraries#Top_Most_Window

' public domain
Const cProgName = "Program #2": _Title cProgName
Const FALSE = 0: Const TRUE = Not FALSE

' TEXT MODE COLORS:
Const cBlack = 0: Const cBlue = 1: Const cGreen = 2: Const cLtBlue = 3
Const cRed = 4: Const cPurple = 5: Const cOrange = 6: Const cWhite = 7
Const cGray = 8: Const cPeriwinkle = 9: Const cLtGreen = 10: Const cCyan = 11
Const cLtRed = 12: Const cPink = 13: Const cYellow = 14: Const cLtGray = 15

Const SWP_NOSIZE = &H0001 'ignores cx and cy size parameters
Const SWP_NOMOVE = &H0002 'ignores x and y position parameters
Const SWP_NOZORDER = &H0004 'keeps z order and ignores hWndInsertAfter parameter
Const SWP_NOREDRAW = &H0008 'does not redraw window changes
Const SWP_NOACTIVATE = &H0010 'does not activate window
Const SWP_FRAMECHANGED = &H0020
Const SWP_SHOWWINDOW = &H0040
Const SWP_HIDEWINDOW = &H0080
Const SWP_NOCOPYBITS = &H0100
Const SWP_NOOWNERZORDER = &H0200
Const SWP_NOSENDCHANGING = &H0400
Const SWP_DRAWFRAME = SWP_FRAMECHANGED
Const SWP_NOREPOSITION = SWP_NOOWNERZORDER
Const SWP_DEFERERASE = &H2000
Const SWP_ASYNCWINDOWPOS = &H4000
Const HWND_TOP = 0 'window at top of z order no focus
Const HWND_BOTTOM = 1 'window at bottom of z order no focus
Const HWND_TOPMOST = -1 'window above all others no focus unless active
Const HWND_NOTOPMOST = -2 'window below active no focus

Declare Dynamic Library "user32"
    Function FindWindowA%& (ByVal lpClassName%&, Byval lpWindowName%&)
    Function SetWindowPos& (ByVal hWnd%&, Byval hWndInsertAfter%&, Byval X&, Byval Y&, Byval cx&, Byval cy&, Byval uFlags~&)
    Function GetForegroundWindow%&
End Declare

Declare Dynamic Library "kernel32"
    Function GetLastError~& ()
End Declare

Dim t As String
Dim hWnd As _Offset
Dim iLoop As Integer
Dim bOnTop As Integer: bOnTop = FALSE

Screen 12 ' SCREEN 12 can use 16 color attributes with a black background. 256K possible RGB color hues. Background colors can be used with QB64.
Cls , cRed
Color cWhite, cRed

Randomize Timer
t = Hex$(Rnd * &H1000000) ' random title for FindWindowA
_Title cProgName + t ' _Trim$(Str$(t))
t = t + Chr$(0)
hWnd = _WindowHandle ' FindWindowA(0, _OFFSET(t))
_Title cProgName + t + ": This Window will always be on Top" ' any title

_Delay 4 ' delay allows user to click focus on other windows

' set as topmost window and move without sizing or activation
If 0 = SetWindowPos(hWnd, HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) Then
    Print "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
End If

x%& = GetForegroundWindow%& ' find currently focused process handle

Print "Program handle:"; hWnd; "Focus handle:"; x%&

If hWnd <> x%& Then
    _ScreenClick 240, 240 ' add 40 to x and y to focus on positioned window
End If

Locate 5, 20 ' y,x where 1,1 = top left
Print cProgName
Locate 10, 20
Print "Press A to stay on top, B for background"
Locate 25, 20 ' y,x where 1,1 = top left
Print "Hold down ESC to exit."
For iLoop = 10000 To 0 Step -1
    Locate 15, 20
    Print IIFSTR$(bOnTop, "STAY ON TOP", "BACKGROUND ")
    Locate 20, 20 ' y,x where 1,1 = top left
    Print _Trim$(Str$(iLoop)) + "     "

    While _DeviceInput(1): Wend ' clear and update the keyboard buffer
    If _KeyDown(Asc("a")) Or _KeyDown(Asc("A")) Then
        bOnTop = TRUE
        '(ENABLE ALWAYS STAY ON TOP)
       
        ' set as topmost window and move without sizing or activation
        If 0 = SetWindowPos(hWnd, HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) Then
            Locate 1, 1
            Print "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
        End If
       
    ElseIf _KeyDown(Asc("b")) Or _KeyDown(Asc("B")) Then
        bOnTop = FALSE
        '(DISABLE ALWAYS STAY ON TOP)
       
        ' set as topmost window and move without sizing or activation
        If 0 = SetWindowPos(hWnd, HWND_NOTOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) Then
            Locate 1, 1
            Print "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
        End If
       
    End If
    If _KeyDown(27) Then Exit For ' leave loop when ESC key pressed
    _Limit 4 ' keep loop at 4 frames per second
Next iLoop
End

Function IIF (Condition, IfTrue, IfFalse)
    If Condition Then IIF = IfTrue Else IIF = IfFalse
End Function
Function IIFSTR$ (Condition, IfTrue$, IfFalse$)
    If Condition Then IIFSTR$ = IfTrue$ Else IIFSTR$ = IfFalse$
End Function
Reply


Messages In This Thread
RE: setting program to display always on top of other windows without having the focus? - by madscijr - 05-19-2024, 03:24 PM



Users browsing this thread: 2 Guest(s)