DirectX + Alt + Tab
DirectX + Alt + Tab
After searching through these forums, and browsing the game section, and reading the FAQ, I still do not have a fail safe solution...
I want to be able to Alt+Tab from a full screen PureBasic application back to the desktop, and then back to my application, without the application crashing... How do I o that?
I want to be able to Alt+Tab from a full screen PureBasic application back to the desktop, and then back to my application, without the application crashing... How do I o that?
( 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... )
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
Re: DirectX + Alt + Tab
should work flawlessly... pse state an example that doesn't...
oh... and have a nice day.
Re: DirectX + Alt + Tab
I am not sitting behind my machine right now, but I will do so tonight, yesterday every attempt at Alt+Tab crashed the application. Perhaps I screwed up? (I do sometimes, you know, that's how I ended up married
)

( 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... )
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
Re: DirectX + Alt + Tab
I'm not sure if there was a problem with calling FlipBuffers or ScreenOutput when the screen is inactive, whether we have to if it out or not...
but when you put everything concerning the screen after an If IsScreenActive and only a Delay after the Else, it should become rocksolid.
but when you put everything concerning the screen after an If IsScreenActive and only a Delay after the Else, it should become rocksolid.
oh... and have a nice day.
Re: DirectX + Alt + Tab
Well, it's an answer, but somewhat, euh... vague 
Could you modify the code below to show me what you mean? I'm clueless...

Could you modify the code below to show me what you mean? I'm clueless...
Code: Select all
InitKeyboard()
InitSprite()
InitSprite3D()
;
OpenScreen(1024,768,32,"Test",#PB_Screen_SmartSynchronization)
;
CreateImage(1,100,100,32)
StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,100,100,0)
DrawingMode(#PB_2DDrawing_AlphaBlend)
BackColor(RGBA(0,0,0,0))
FrontColor(RGBA(255,255,255,255))
LineXY(4,95,49,5)
LineXY(5,95,50,5)
LineXY(50,5,95,95)
LineXY(51,5,96,95)
LineXY(95,95,50,85)
LineXY(95,96,50,86)
LineXY(50,85,5,95)
LineXY(50,86,5,96)
FillArea(45,20,-1,RGBA(255,0,0,96))
LineXY(50,6,50,84,RGBA(128,128,128,96))
FillArea(55,20,-1,RGBA(128,128,128,255))
StopDrawing()
;
CreateSprite(1,100,100,#PB_Sprite_Texture)
StartDrawing(SpriteOutput(1))
DrawImage(ImageID(1),0,0)
StopDrawing()
CreateSprite3D(1,1)
;
s = 5
a = 0
Repeat
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
event = #PB_Event_CloseWindow
EndIf
If event = 0
ClearScreen(0)
For y = 0 To 1
For xx = 0 To 1
For x = 0 To 7
RotateSprite3D(1,angle,#PB_Absolute)
Start3D()
Sprite3DBlendingMode(s,xx*8+x)
DisplaySprite3D(1+a,30+x*125,10+xx*170+y*410)
DisplaySprite3D(1+a,50+x*125,30+xx*170+y*410)
Stop3D()
StartDrawing(ScreenOutput())
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(60+x*125,150+xx*170+y*410,Str(s)+" , "+Str(xx*8+x),RGB(255,255,255)*(1-y))
StopDrawing()
Next x
Next xx
Next y
angle = (angle+1) % 360
FlipBuffers()
EndIf
Until event = #PB_Event_CloseWindow
;
CloseScreen()
( 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: DirectX + Alt + Tab
same problem as here:
http://www.purebasic.fr/english/viewtop ... =4&t=35669
http://www.purebasic.fr/english/viewtop ... =4&t=35669
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and more ― Typeface - Sprite-based font include/module
Lizard - Script language for symbolic calculations and more ― Typeface - Sprite-based font include/module
- Kaeru Gaman
- Addict
- Posts: 4826
- Joined: Sun Mar 19, 2006 1:57 pm
- Location: Germany
Re: DirectX + Alt + Tab
I'll read that code tomorrow, watching The Closer atm and Black Cristmas afterwards.
gnight
gnight
oh... and have a nice day.
Re: DirectX + Alt + Tab
I noticed all the same symptoms that were posted in that thread when applying the needed corrections to blueznl's code sample above. The needed corrections were prevented from functioning.STARGÅTE wrote:same problem as here:
http://www.purebasic.fr/english/viewtop ... =4&t=35669

The most notable problem was that Flipbuffers() can't be called if the screen isn't active and that IsScreenActive() won't indicate the screen is active again without calling Flipbuffers() to update the status of the screen.

This observation may apply to the bug-thread dealing with threaded apps also.
@Edit: I incorrectly combined separate symptoms, from each of the solutions I was trying, into the observation I stated above. The problem didn't relate directly to FlipBuffers(). FlipBuffers() appeared to work fine (no faults). The problem was that the screen does not become active again when the program is selected again. When this happens IsScreenActive() always returns '0' and none of the screen functions appear to work. I think this is something the developers will have to remedy.
Last edited by Demivec on Sat Dec 19, 2009 11:14 pm, edited 1 time in total.
Re: DirectX + Alt + Tab
I found some code in a (french) tutorial from 'B-games'. That code works with DirectX7 but NOT with DirectX9.
Makes me wonder if DirectX9 in PureBasic is yet mature enoug to be used as default...
There's also good news: DirectX7 synchronisation has become much better since previous versions...
Makes me wonder if DirectX9 in PureBasic is yet mature enoug to be used as default...
There's also good news: DirectX7 synchronisation has become much better since previous versions...
( 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: DirectX + Alt + Tab
This is a code I've done some months ago showing (among other things) how to do. See and adapt check_lostfocus() procedure.
Code: Select all
;******************************************************************************************************
;* Rasterline and VBL Sync
;* By djes (djes@free.fr) 03/24/2009
;* Thanx to Stefan Moebius for VBL sync examples
;* Note : I do not check functions return codes : I know it's bad!
;* PB 4.3
;* 12/21/09 : PB 4.40
;******************************************************************************************************
#STARS_NB = 50
#D3D_OK = 0
;******************************************************************************************************
Structure D3DRASTER_STATUS
InVBlank.l
ScanLine.l
EndStructure
Structure pos
x.l
y.l
speed.l
EndStructure
;******************************************************************************************************
Define.D3DRASTER_STATUS raster
Define.IDirect3DDevice9 D3Ddevice_interface
Dim stars.pos(#STARS_NB)
;******************************************************************************************************
;- PROCEDURES
;******************************************************************************************************
;wait for the vblank to start
;attend le début de la synchro vbl
Procedure vblank_wait()
Shared D3Ddevice_interface, raster, exit
Repeat
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
exit=#True
EndIf
D3Ddevice_interface\GetRasterStatus(0, @raster)
Until raster\InVBlank=#True Or exit
EndProcedure
;******************************************************************************************************
;wait for the vblank to finish
;attend la fin de la synchro vbl
Procedure vblank_end_wait()
Shared D3Ddevice_interface, raster, exit
Repeat
ExamineKeyboard()
If KeyboardPushed(#PB_Key_Escape)
exit=#True
EndIf
D3Ddevice_interface\GetRasterStatus(0, @raster)
Until raster\InVBlank=#False Or exit
EndProcedure
;******************************************************************************************************
;récupère la position du raster et y affiche une ligne de la couleur indiquée
Procedure rasterline(color.l)
Shared raster, D3Ddevice_interface
StartDrawing(ScreenOutput())
D3Ddevice_interface\GetRasterStatus(0, @raster)
LineXY(0, raster\ScanLine, 1023, raster\ScanLine, color)
StopDrawing()
EndProcedure
;******************************************************************************************************
Procedure create_sprites()
CreateSprite(0, 64, 64)
StartDrawing(SpriteOutput(0))
Circle(32, 32, 31, RGB($FF, $FF, $FF))
StopDrawing()
EndProcedure
;******************************************************************************************************
;Open screen and get the device - Ouvre l'écran et récupère le device
Procedure init_display()
Shared *SwapChain_interface, D3Ddevice_interface
OpenScreen(1024, 768, 32, "", #PB_Screen_NoSynchronization)
!extrn _PB_Screen_Direct3DDevice
!MOV dword EAX, [_PB_Screen_Direct3DDevice]
!MOV dword [v_D3Ddevice_interface],EAX
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)
;we're lowering our priority - on baisse notre priorité
SetPriorityClass_( GetCurrentProcess_(), #NORMAL_PRIORITY_CLASS)
SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_NORMAL)
;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)
;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)
;We're waiting for the synchro a new time - On réattend la synchro
vblank_wait()
SetPriorityClass_( GetCurrentProcess_(), #HIGH_PRIORITY_CLASS)
SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_ABOVE_NORMAL) ;warning : keyboard lock
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
;we're giving priority boost to our process - on donne une priorité maximale à notre processus
SetPriorityClass_( GetCurrentProcess_(), #REALTIME_PRIORITY_CLASS)
SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_TIME_CRITICAL) ;warning : keyboard lock
;******************************************************************************************************
;- MAIN LOOP
;******************************************************************************************************
Repeat
;wait for the sync - attends la synchro
vblank_wait()
;flip the buffers without the PB's sync - flippe le buffer sans utiliser la synchro PB
FlipBuffers()
;during VBL, lower a bit our priority to give time to OS (especially to handle the keyboard)
;pendant la VBL, baisse un peu notre priorité pour donner un peu de temps au système (pour gérer le clavier surtout)
SetPriorityClass_( GetCurrentProcess_(), #HIGH_PRIORITY_CLASS)
SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_NORMAL)
ExamineKeyboard()
ExamineMouse()
If KeyboardPushed(#PB_Key_Escape)
exit=#True
EndIf
check_lostfocus()
ClearScreen(0)
;we're waiting for the VBL end (could be better!!!)
;on attend la fin de la VBL (à améliorer) pour être sûr de ne pas sauter une frame
vblank_end_wait()
;we're giving priority boost to our process - on donne une priorité maximale à notre processus
SetPriorityClass_( GetCurrentProcess_(), #REALTIME_PRIORITY_CLASS)
SetThreadPriority_( GetCurrentThread_() , #THREAD_PRIORITY_TIME_CRITICAL) ;warning : keyboard lock
rasterline($FF0000)
;-TEST CODE
;compute our effect
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
;draw it
For i = 0 To #STARS_NB-1
DisplayTranslucentSprite(0, stars(i)\x, stars(i)\y, stars(i)\speed<<4)
Next i
;-END TEST CODE
;draw a rasterline to see (visually) how much time our fx is taking
;affiche une rasterline pour visualiser combien de temps prend notre effet
rasterline($FF00)
Until exit
CloseScreen()
End
;******************************************************************************************************
Re: DirectX + Alt + Tab
Thx... but this can't be for real, I mean, the idea behind basic is that it's a basic language hiding some complexity from the user... I hope the PBDevs can cook up something that makes this kind of thing easy on the mind of the (beginning) programmer...
( 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: DirectX + Alt + Tab
Forget most of the code, just use this : It's not that hard...
Code: Select all
;******************************************************************************************************
;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