An improvement of the IsScreenActive() command:
IsScreenActive() should return #True if the screen is active in all situations.
Currently, it only works after a FlipBuffers() attempt using DirectX7, and there is no easy way to use it under DirectX9.
(On a related side note: why does the user have to take care of [Alt]+[Tab] issues? Not that I really mind, but perhaps it's an idea to hide this under the hood?)
Improved IsScreenActive()
Improved IsScreenActive()
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
( The path to enlightenment and the PureBasic Survival Guide right here... )
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Improved IsScreenActive()
Indeed, IsScreenActive() does not appear to work properly if Engine3D is being used, always returns #True.
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Improved IsScreenActive()
This is an example showing how to make it work in 2D, DirectX9 or DirectX7, and 3D in the next code. Badly, with the debugger enabled, an error occurs on WaitWindowEvent().
Here is another example showing how to make it work with engine3d
Please note that I'm using sprite3d even if the manual is saying they're not supported :/ ; also note that Clearscreen() doesn't work. Also note that you can't close and recreate a screen without a crash.
Code: Select all
;******************************************************************************************************
;* check_lostfocus() ALT-TAB IsScreenActive() demo
;* By djes (djes@free.fr) 03/24/2009
;* PB 4.3
;* 12/21/09 : PB 4.40
;******************************************************************************************************
#STARS_NB = 50
#D3D_OK = 0
Structure pos
x.l
y.l
speed.l
EndStructure
Dim stars.pos(#STARS_NB)
;******************************************************************************************************
;- PROCEDURES
;******************************************************************************************************
Procedure create_sprites()
CreateSprite(0, 64, 64)
StartDrawing(SpriteOutput(0))
Circle(32, 32, 31, RGB($FF, $FF, $FF))
StopDrawing()
EndProcedure
;******************************************************************************************************
Procedure init_display()
OpenScreen(1024, 768, 32, "", #PB_Screen_SmartSynchronization)
ClearScreen(0)
EndProcedure
;******************************************************************************************************
;Check if the user has switched (and that we have lost focus) (ALT-TAB)
;Vérifie si l'utilisateur n'a pas changé d'appli (en nous faisant donc perdre le focus) (ALT-TAB)
Procedure check_lostfocus()
If IsScreenActive() = 0
ReleaseMouse(1)
;Wait til our window is coming back to foreground - Attend que notre fenêtre repasse au premier plan
Repeat
;now our events are to be processed with WaitWindowEvent, else IsScreenActive() will never say that our window has the focus again
;it should be written in the doc!
;maintenant les événements sont à gérer avec WaitWindowEvent, sinon IsScreenActive() ne dit jamais que notre fenêtre a à nouveau le focus
;il faudrait mettre ça dans la doc!!!!
WaitWindowEvent()
Until IsScreenActive() <> 0
ReleaseMouse(0)
;--- Optional
;Better recreate the screen - il vaut mieux recréer l'écran
CloseScreen()
init_display()
;and the sprites too (have to!) - et les sprites aussi (indispensable)
create_sprites()
;give to the system some time to rest - laisse un peu le temps au système de récupérer
Delay(2000)
;---
EndIf
EndProcedure
;******************************************************************************************************
;- INIT
;******************************************************************************************************
InitSprite()
InitKeyboard()
InitMouse()
init_display()
create_sprites()
For i=0 To #STARS_NB-1
stars(i)\x = Random(1023)
stars(i)\y = Random(767)
stars(i)\speed = Random(16) + 1
Next i
exit=#False
;******************************************************************************************************
;- MAIN LOOP
;******************************************************************************************************
Repeat
FlipBuffers()
check_lostfocus()
ExamineKeyboard()
ExamineMouse()
If KeyboardPushed(#PB_Key_Escape)
exit=#True
EndIf
ClearScreen(0)
;-TEST CODE
For i = 0 To #STARS_NB-1
stars(i)\x + stars(i)\speed
If stars(i)\x > 1023
stars(i)\x - 1024 - 64
EndIf
Next i
For i = 0 To #STARS_NB-1
DisplayTranslucentSprite(0, stars(i)\x, stars(i)\y, stars(i)\speed<<4)
Next i
;-END TEST CODE
Until exit
CloseScreen()
End
;******************************************************************************************************
Code: Select all
;******************************************************************************************************
;* check_lostfocus() ALT-TAB IsScreenActive() demo
;* By djes (djes@free.fr) 03/24/2009
;* PB 4.3
;* 12/21/09 : PB 4.40
;******************************************************************************************************
#STARS_NB = 50
#D3D_OK = 0
Structure pos
x.l
y.l
speed.l
EndStructure
Dim stars.pos(#STARS_NB)
;******************************************************************************************************
;- PROCEDURES
;******************************************************************************************************
Procedure create_sprites()
CreateSprite(0, 64, 64, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(0))
Circle(32, 32, 31, RGB($FF, $FF, $FF))
StopDrawing()
CreateSprite3D(0, 0)
EndProcedure
;******************************************************************************************************
Procedure init_display()
OpenScreen(1024, 768, 32, "", #PB_Screen_SmartSynchronization)
ClearScreen(0)
EndProcedure
;******************************************************************************************************
;Check if the user has switched (and that we have lost focus) (ALT-TAB)
;Vérifie si l'utilisateur n'a pas changé d'appli (en nous faisant donc perdre le focus) (ALT-TAB)
Procedure check_lostfocus()
If IsScreenActive() = 0
ReleaseMouse(1)
;Wait til our window is coming back to foreground - Attend que notre fenêtre repasse au premier plan
Repeat
;now our events are to be processed with WaitWindowEvent, else IsScreenActive() will never say that our window has the focus again
;it should be written in the doc!
;maintenant les événements sont à gérer avec WaitWindowEvent, sinon IsScreenActive() ne dit jamais que notre fenêtre a à nouveau le focus
;il faudrait mettre ça dans la doc!!!!
WaitWindowEvent()
Until IsScreenActive() <> 0
ReleaseMouse(0)
;--- Optional
;Better recreate the screen - il vaut mieux recréer l'écran
;CloseScreen()
;init_display()
;and the sprites too (have to!) - et les sprites aussi (indispensable)
;create_sprites()
;give to the system some time to rest - laisse un peu le temps au système de récupérer
Delay(2000)
;---
EndIf
EndProcedure
;******************************************************************************************************
;- INIT
;******************************************************************************************************
InitEngine3D()
InitSprite3D()
InitSprite()
InitKeyboard()
InitMouse()
init_display()
create_sprites()
For i=0 To #STARS_NB-1
stars(i)\x = Random(1023)
stars(i)\y = Random(767)
stars(i)\speed = Random(16) + 1
Next i
exit=#False
;******************************************************************************************************
;- MAIN LOOP
;******************************************************************************************************
Repeat
FlipBuffers()
ClearScreen(0)
;If engine3d is used
ev = WindowEvent()
check_lostfocus()
ExamineKeyboard()
ExamineMouse()
If KeyboardPushed(#PB_Key_Escape)
exit=#True
EndIf
RenderWorld()
;-TEST CODE
For i = 0 To #STARS_NB-1
stars(i)\x + stars(i)\speed
If stars(i)\x > 1023
stars(i)\x - 1024 - 64
EndIf
Next i
Start3D()
For i = 0 To #STARS_NB-1
DisplaySprite3D(0, stars(i)\x, stars(i)\y, stars(i)\speed<<4)
Next i
Stop3D()
;-END TEST CODE
Until exit
CloseScreen()
End
;******************************************************************************************************
-
- Always Here
- Posts: 6426
- Joined: Fri Oct 23, 2009 2:33 am
- Location: Wales, UK
- Contact:
Re: Improved IsScreenActive()
Hello djes
Very nice example thank you. I think however that OpenWindowedScreen is the one that may put the spanner in IsScreenActive's works
Concerning ClearScreen, someone on the forum (might have been you!) gave a good tip: Use CameraBackColor.
Concerning the screen crashing if you close and try to re-create, I have seen the same issue with OpenWindowedScreen, a real shame because you can't re-size it's Host Window and have the windowed screen re-size with it (if Engine3D is being used).
Very nice example thank you. I think however that OpenWindowedScreen is the one that may put the spanner in IsScreenActive's works

Concerning ClearScreen, someone on the forum (might have been you!) gave a good tip: Use CameraBackColor.
Concerning the screen crashing if you close and try to re-create, I have seen the same issue with OpenWindowedScreen, a real shame because you can't re-size it's Host Window and have the windowed screen re-size with it (if Engine3D is being used).
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
If it sounds simple, you have not grasped the complexity.
Re: Improved IsScreenActive()
In spite of Djes' nice example I still think it's an improvement to the language...
( PB6.00 LTS Win11 x64 Asrock AB350 Pro4 Ryzen 5 3600 32GB GTX1060 6GB)
( The path to enlightenment and the PureBasic Survival Guide right here... )
( The path to enlightenment and the PureBasic Survival Guide right here... )
Re: Improved IsScreenActive()
I agree with you, the ALT-Tab should not be an issue.