Improved IsScreenActive()

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Improved IsScreenActive()

Post 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?)
( 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... )
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Improved IsScreenActive()

Post by IdeasVacuum »

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.
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Improved IsScreenActive()

Post 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.
IdeasVacuum
Always Here
Always Here
Posts: 6426
Joined: Fri Oct 23, 2009 2:33 am
Location: Wales, UK
Contact:

Re: Improved IsScreenActive()

Post 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).
IdeasVacuum
If it sounds simple, you have not grasped the complexity.
User avatar
blueznl
PureBasic Expert
PureBasic Expert
Posts: 6166
Joined: Sat May 17, 2003 11:31 am
Contact:

Re: Improved IsScreenActive()

Post by blueznl »

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... )
User avatar
djes
Addict
Addict
Posts: 1806
Joined: Sat Feb 19, 2005 2:46 pm
Location: Pas-de-Calais, France

Re: Improved IsScreenActive()

Post by djes »

I agree with you, the ALT-Tab should not be an issue.
Post Reply