05-19-2024, 03:24 PM
(This post was last modified: 05-19-2024, 03:45 PM by madscijr.
Edit Reason: fixed sample code again
)
(05-17-2024, 11:27 PM)SMcNeill Wrote: https://qb64phoenix.com/qb64wiki/index.p...ost_WindowFantastic!
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