What bone-head thing did I miss this time?
#1
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
Reply
#2
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 + ...
Reply
#3
@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
Reply
#4
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
Reply
#5
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
Reply
#6
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
Reply
#7
(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
Reply
#8
Thumbs Up 
(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 + ...
Reply
#9
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!
Reply
#10
Thumbs Up 
(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! Smile thanks!
b = b + ...
Reply




Users browsing this thread: 4 Guest(s)