Page 1 of 1
Improved IsScreenActive()
Posted: Sun Dec 27, 2009 1:02 pm
by blueznl
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?)
Re: Improved IsScreenActive()
Posted: Thu Jan 07, 2010 12:11 am
by IdeasVacuum
Indeed, IsScreenActive() does not appear to work properly if Engine3D is being used, always returns #True.
Re: Improved IsScreenActive()
Posted: Thu Jan 07, 2010 10:35 am
by djes
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().
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
;******************************************************************************************************
Here is another example showing how to make it work with engine3d
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
;******************************************************************************************************
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.
Re: Improved IsScreenActive()
Posted: Fri Jan 08, 2010 6:51 am
by IdeasVacuum
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).
Re: Improved IsScreenActive()
Posted: Sat Jan 09, 2010 12:16 pm
by blueznl
In spite of Djes' nice example I still think it's an improvement to the language...
Re: Improved IsScreenActive()
Posted: Sun Jan 10, 2010 12:41 am
by djes
I agree with you, the ALT-Tab should not be an issue.