(05-19-2024, 04:35 PM)Steffan-68 Wrote: But your programs are fine.
If you press key B the window is no longer in the foreground and with A it is in the front again.
All you have to do is click on it with the mouse to give the program focus again, and then press the corresponding keys.
And the second program should not be in the same place as the first.
The function brings the window to the foreground, but does not hold the focus.
(05-19-2024, 04:36 PM)SMcNeill Wrote: @madscijr It works as expected on my PC.Thank you both for your replies.
I think the problem is you're clicking "b" while the program doesn't have focus, so it's not going to read that input and change modes on you.
...
At least, that's how it's working for me on Win 11.
I see what was happening - both were initializing as "top" so whichever one got the focus went to top.
I fixed that and now it's working, just one problem now, which is that when you press "a" or "b" and the program changes the "always on top" state, the window moves.
I see that lines 81 and 87 are calling SetWindowPos with X& and Y& hardcoded to 200:
Code: (Select All)
Function SetWindowPos& (ByVal hWnd%&, Byval hWndInsertAfter%&, Byval X&, Byval Y&, Byval cx&, Byval cy&, Byval uFlags~&)
...
If SetWindowPos(hWndThis, HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) = 0 Then
Thanks again!
Program #1
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
Const cProgName = "Program #1"
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 hWndThis As _Offset ' hWndThis%&
Dim hWndTop As _Offset ' x%&
Dim iLoop As Integer
Dim bOnTop As Integer: bOnTop = FALSE
Dim sError As String: sError = ""
_Title cProgName
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: Locate 5, 20: Print cProgName
For iLoop = 10000 To 0 Step -1
' GET WINDOW HANDLES
hWndThis = _WindowHandle ' FindWindowA(0, _OFFSET(t))
hWndTop = GetForegroundWindow%& ' find currently focused process handle
'If hWndThis <> hWndTop Then
' _ScreenClick 240, 240 ' add 40 to x and y to focus on positioned window
'End If
' UPDATE SCREEN y,x where 1,1 = top left
Locate 10, 20: Print "Program handle: " + _Trim$(Str$(hWndThis))
Locate 12, 20: Print "Focus handle: " + _Trim$(Str$(hWndTop))
Locate 14, 20: Print _Trim$(Str$(iLoop)) + " "
Locate 16, 20: Print "Press A to stay on top, B for background"
Locate 18, 20: If bOnTop = TRUE Then Print "STAY ON TOP" Else Print "NORMAL"
Locate 20, 20: If Len(sError) > 0 Then Print sError Else Print " "
Locate 25, 20: Print "Hold down ESC to exit."
' -----------------------------------------------------------------------------
' GET KEYBOARD INPUT
While _DeviceInput(1): Wend ' clear and update the keyboard buffer
If _KeyDown(Asc("a")) Or _KeyDown(Asc("A")) Then
' SET AS TOPMOST WINDOW AND MOVE WITHOUT SIZING OR ACTIVATION
If SetWindowPos(hWndThis, HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) = 0 Then
sError = "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
End If
bOnTop = TRUE ' FLAG ALWAYS STAY ON TOP
ElseIf _KeyDown(Asc("b")) Or _KeyDown(Asc("B")) Then
' SET AS TOPMOST WINDOW AND MOVE WITHOUT SIZING OR ACTIVATION
If SetWindowPos(hWndThis, HWND_NOTOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) = 0 Then
sError = "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
End If
bOnTop = FALSE ' UN-FLAG ALWAYS STAY ON TOP
ElseIf _KeyDown(27) Then
Exit For ' leave loop when ESC key pressed
End If
_Limit 4 ' keep loop at 4 frames per second
Next iLoop
End
Program #2
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
Const cProgName = "Program #2"
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 hWndThis As _Offset ' hWndThis%&
Dim hWndTop As _Offset ' x%&
Dim iLoop As Integer
Dim bOnTop As Integer: bOnTop = FALSE
Dim sError As String: sError = ""
_Title cProgName
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: Locate 5, 20: Print cProgName
For iLoop = 10000 To 0 Step -1
' GET WINDOW HANDLES
hWndThis = _WindowHandle ' FindWindowA(0, _OFFSET(t))
hWndTop = GetForegroundWindow%& ' find currently focused process handle
'If hWndThis <> hWndTop Then
' _ScreenClick 240, 240 ' add 40 to x and y to focus on positioned window
'End If
' UPDATE SCREEN y,x where 1,1 = top left
Locate 10, 20: Print "Program handle: " + _Trim$(Str$(hWndThis))
Locate 12, 20: Print "Focus handle: " + _Trim$(Str$(hWndTop))
Locate 14, 20: Print _Trim$(Str$(iLoop)) + " "
Locate 16, 20: Print "Press A to stay on top, B for background"
Locate 18, 20: If bOnTop = TRUE Then Print "STAY ON TOP" Else Print "NORMAL"
Locate 20, 20: If Len(sError) > 0 Then Print sError Else Print " "
Locate 25, 20: Print "Hold down ESC to exit."
' -----------------------------------------------------------------------------
' GET KEYBOARD INPUT
While _DeviceInput(1): Wend ' clear and update the keyboard buffer
If _KeyDown(Asc("a")) Or _KeyDown(Asc("A")) Then
' SET AS TOPMOST WINDOW AND MOVE WITHOUT SIZING OR ACTIVATION
If SetWindowPos(hWndThis, HWND_TOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) = 0 Then
sError = "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
End If
bOnTop = TRUE ' FLAG ALWAYS STAY ON TOP
ElseIf _KeyDown(Asc("b")) Or _KeyDown(Asc("B")) Then
' SET AS TOPMOST WINDOW AND MOVE WITHOUT SIZING OR ACTIVATION
If SetWindowPos(hWndThis, HWND_NOTOPMOST, 200, 200, 0, 0, SWP_NOSIZE Or SWP_NOACTIVATE) = 0 Then
sError = "SetWindowPos failed. 0x" + LCase$(Hex$(GetLastError))
End If
bOnTop = FALSE ' UN-FLAG ALWAYS STAY ON TOP
ElseIf _KeyDown(27) Then
Exit For ' leave loop when ESC key pressed
End If
_Limit 4 ' keep loop at 4 frames per second
Next iLoop
End