Posts: 1,616
Threads: 157
Joined: Apr 2022
Reputation:
77
Windows API for set window active should register a number in this little test routine, but it doesn't. I threw in a couple of other API functions that register just fine. Anyone know what I missed here?
Code: (Select All) DECLARE DYNAMIC LIBRARY "user32"
FUNCTION SetActiveWindow& (BYVAL hwnd AS LONG)
FUNCTION GetWindow& (BYVAL hwnd AS LONG, BYVAL nCmdShow AS LONG)
FUNCTION FindWindowA& (BYVAL ClassName AS LONG, WindowName$) 'handle by title
END DECLARE
title$ = "Set Window Active Test"
_TITLE (title$)
_DELAY .1
DO
hwnd& = FindWindowA(0, title$)
LOOP UNTIL hwnd&
DO
_LIMIT 10
c& = GetWindow(hwnd&, 1) ' Just put this in to show it does register.
a& = SetActiveWindow(hwnd&) ' This one should registere, but doesn't. <==============
PRINT "This should be non-zero:"; a&; " These are fine:"; c&, hwnd&
SLEEP 4
IF LEN(INKEY$) THEN END
LOOP
Pete
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
10-28-2022, 05:55 PM
(This post was last modified: 10-28-2022, 06:02 PM by bplus.)
Would a program that sets the active window have to be active itself to work?
Looks sorta like this program can only call itself and that only if it is saved under title$ name (with an .exe) and I recall you have to add an end of string character for Windows calls.
A couple of things to try until Spriggsy weighs in...
b = b + ...
Posts: 1,510
Threads: 53
Joined: Jul 2022
Reputation:
47
10-28-2022, 09:08 PM
(This post was last modified: 10-28-2022, 09:10 PM by mnrvovrfc.)
@Pete you should put an "INKEY" test or something like that to get away from the first loop which has the potential to be a CPU-locking endless loop. Or it might just quit after one iteration so it's worthless...
IDK:
https://qb64phoenix.com/qb64wiki/index.php/WINDOWHANDLE
https://qb64phoenix.com/qb64wiki/index.p...OWHASFOCUS
Posts: 1,616
Threads: 157
Joined: Apr 2022
Reputation:
77
10-28-2022, 09:52 PM
(This post was last modified: 10-28-2022, 10:17 PM by Pete.)
I've used _WINDOWHANDLE before. It's basically the same as the old-school method I applied using: FindWindowA
The INKEY$ is just a =there so anyone who tests it and sees the SetActiveWindow just won't register can easily quit using the keyboard.
At this stage I don't expect the SetActiveWindow to be the complete answer, but if I coded it wrong, I can't even test out its behavior.
Oh, I've seen that add CHR$(0) to the title, but I've never had a need to do so. This one gets the handle just fine, with or without it.
Ultimately what I'm looking for is a better way than the hack I created to activate alternate opened messenger windows, here: https://staging.qb64phoenix.com/showthre...71#pid8671
Pete
Posts: 439
Threads: 17
Joined: Apr 2022
Reputation:
21
10-29-2022, 01:28 AM
(This post was last modified: 10-29-2022, 01:30 AM by SpriggsySpriggs.)
This is a very dirty way of doing this but here, @Pete :
Code: (Select All) Declare Dynamic Library "user32"
Sub ShowWindow (ByVal hWnd As _Offset, Byval nCmdShow As Long)
End Declare
title$ = "Set Window Active Test"
_Title title$
_Delay .1
Do
hwnd%& = _WindowHandle
Loop Until hwnd%&
Do
_Limit 10
If _WindowHasFocus = 0 Then
_ScreenIcon
ShowWindow hwnd%&, 1
End If
Print hwnd%&
Sleep 4
If Len(InKey$) Then End
Loop
Basically, I'm checking if the window has focus. If it doesn't, I'm forcing the focus back to the window by minimizing it with ScreenIcon and then maximizing it with ShowWindow. The stuff like SetActiveWindow, SetForegroundWindow, etc are all buggy as hell and don't work half the time and no one ever has a good explanation why. Hope this helps you at least a little, Pete.
Ask me about Windows API and maybe some Linux stuff
Posts: 1,616
Threads: 157
Joined: Apr 2022
Reputation:
77
10-29-2022, 01:41 AM
(This post was last modified: 10-29-2022, 01:43 AM by Pete.)
Hi Spriggsy,
Wow, when you and I both have to develop a hack to get a desired Windows API result, I'd say we reached the end of the trail. After all, you are the API King and I swear to God Steve, if I log in tomorrow and find API Queen in my profile, we are gonna have words!
I'll have a look at the icon one, new to me, but my hack was to also to min and restore each window, as that does force focus. https://staging.qb64phoenix.com/showthre...71#pid8671
In other news, Paul Pelosi apparently still didn't learn his lesson from his last drunk driving incident, as I hear he's still getting hammered!
Pete
Posts: 439
Threads: 17
Joined: Apr 2022
Reputation:
21
(10-29-2022, 01:41 AM)Pete Wrote: Hi Spriggsy,
Wow, when you and I both have to develop a hack to get a desired Windows API result, I'd say we reached the end of the trail. After all, you are the API King and I swear to God Steve, if I log in tomorrow and find API Queen in my profile, we are gonna have words!
I'll have a look at the icon one, new to me, but my hack was to also to min and restore each window, as that does force focus. https://staging.qb64phoenix.com/showthre...71#pid8671
In other news, Paul Pelosi apparently still didn't learn his lesson from his last drunk driving incident, as I hear he's still getting hammered!
Pete
Ha! I didn't even really read the other post so I had no idea that you were doing a minimize/maximize thing! Great minds think alike, eh?
Ask me about Windows API and maybe some Linux stuff
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
10-29-2022, 01:56 AM
(10-29-2022, 01:28 AM)Spriggsy Wrote: This is a very dirty way of doing this but here, @Pete :
Code: (Select All) Declare Dynamic Library "user32"
Sub ShowWindow (ByVal hWnd As _Offset, Byval nCmdShow As Long)
End Declare
title$ = "Set Window Active Test"
_Title title$
_Delay .1
Do
hwnd%& = _WindowHandle
Loop Until hwnd%&
Do
_Limit 10
If _WindowHasFocus = 0 Then
_ScreenIcon
ShowWindow hwnd%&, 1
End If
Print hwnd%&
Sleep 4
If Len(InKey$) Then End
Loop
Basically, I'm checking if the window has focus. If it doesn't, I'm forcing the focus back to the window by minimizing it with ScreenIcon and then maximizing it with ShowWindow. The stuff like SetActiveWindow, SetForegroundWindow, etc are all buggy as hell and don't work half the time and no one ever has a good explanation why. Hope this helps you at least a little, Pete.
This is pretty cool. I remember somewhere, sometime we discussed how to keep a Window on top but danged if I could find the code.
This works, is it the same thing?
b = b + ...
Posts: 1,616
Threads: 157
Joined: Apr 2022
Reputation:
77
I've made three different ways to handle that. One of the simplest...
Code: (Select All) CONST HWND_TOPMOST%& = -1
CONST SWP_NOSIZE%& = &H1
CONST SWP_NOMOVE%& = &H2
CONST SWP_SHOWWINDOW%& = &H40
DECLARE DYNAMIC LIBRARY "user32"
FUNCTION SetWindowPos& (BYVAL hWnd AS LONG, BYVAL hWndInsertAfter AS _OFFSET, BYVAL X AS INTEGER, BYVAL Y AS INTEGER, BYVAL cx AS INTEGER, BYVAL cy AS INTEGER, BYVAL uFlags AS _OFFSET)
FUNCTION GetForegroundWindow& 'find currently focused process handle
END DECLARE
' Needed for acquiring the hWnd of the window
DIM hWnd AS LONG ' Get hWnd value
DO ' Title window and get handle.
_LIMIT 30
_TITLE "Persistency Window Demo"
hWnd = _WINDOWHANDLE
i = i + 1: IF i > 100000 THEN PRINT "Cannt get window handle.": END
LOOP UNTIL hWnd
wdth = 300: hght = 400
' Set screen
s& = _NEWIMAGE(wdth, hght, 32)
SCREEN s&
_DEST 0
_SCREENMOVE 800, 50
' Main loop
Level = 175
_DELAY .1
DO
_LIMIT 30
FGwin& = GetForegroundWindow&
IF hWnd <> FGwin& THEN ' QB64 no longer in focus.
WHILE _MOUSEINPUT: WEND
y& = SetWindowPos&(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE + SWP_SHOWWINDOW)
PRINT y&, hWnd, HWND_TOPMOST%&, SWP_NOSIZE%& + SWP_NOMOVE%& + SWP_SHOWWINDOW%&
DO: _LIMIT 30: LOOP UNTIL hWnd = GetForegroundWindow&
END IF
IF INKEY$ = CHR$(27) THEN SYSTEM
LOOP
Pete
API Queen... Dammit Steve!
Posts: 2,700
Threads: 124
Joined: Apr 2022
Reputation:
134
10-29-2022, 02:29 AM
(10-29-2022, 02:06 AM)Pete Wrote: I've made three different ways to handle that. One of the simplest...
Code: (Select All) CONST HWND_TOPMOST%& = -1
CONST SWP_NOSIZE%& = &H1
CONST SWP_NOMOVE%& = &H2
CONST SWP_SHOWWINDOW%& = &H40
DECLARE DYNAMIC LIBRARY "user32"
FUNCTION SetWindowPos& (BYVAL hWnd AS LONG, BYVAL hWndInsertAfter AS _OFFSET, BYVAL X AS INTEGER, BYVAL Y AS INTEGER, BYVAL cx AS INTEGER, BYVAL cy AS INTEGER, BYVAL uFlags AS _OFFSET)
FUNCTION GetForegroundWindow& 'find currently focused process handle
END DECLARE
' Needed for acquiring the hWnd of the window
DIM hWnd AS LONG ' Get hWnd value
DO ' Title window and get handle.
_LIMIT 30
_TITLE "Persistency Window Demo"
hWnd = _WINDOWHANDLE
i = i + 1: IF i > 100000 THEN PRINT "Cannt get window handle.": END
LOOP UNTIL hWnd
wdth = 300: hght = 400
' Set screen
s& = _NEWIMAGE(wdth, hght, 32)
SCREEN s&
_DEST 0
_SCREENMOVE 800, 50
' Main loop
Level = 175
_DELAY .1
DO
_LIMIT 30
FGwin& = GetForegroundWindow&
IF hWnd <> FGwin& THEN ' QB64 no longer in focus.
WHILE _MOUSEINPUT: WEND
y& = SetWindowPos&(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE + SWP_NOSIZE + SWP_SHOWWINDOW)
PRINT y&, hWnd, HWND_TOPMOST%&, SWP_NOSIZE%& + SWP_NOMOVE%& + SWP_SHOWWINDOW%&
DO: _LIMIT 30: LOOP UNTIL hWnd = GetForegroundWindow&
END IF
IF INKEY$ = CHR$(27) THEN SYSTEM
LOOP
Pete
API Queen... Dammit Steve!
OK now I've got two of 'em to lose! thanks!
b = b + ...
|