Page 1 of 1

alt-Enter and alt-tab Fullscreen toggle

Posted: Fri Aug 13, 2010 11:42 am
by Blue Steel
how can i get my game to toggle from a window to fullscreen or visa versa on alt-enter keypress
using dirextx 9 mode.

Re: alt-Enter Fullscreen toggle

Posted: Sat Aug 14, 2010 4:59 am
by idle

Re: alt-Enter Fullscreen toggle

Posted: Sat Aug 14, 2010 7:59 pm
by RASHAD
Hi
Snippet by Danilo
Modified by RASHAD

Code: Select all


Structure WinInfoT 
  ; Windowed 
  pi.l  ; PB Window Identifier 
  ph.l  ; PB Window Handle 
  wx.l  ; Window X offset 
  wy.l  ; Window Y offset 
  ww.l  ; Window 
  wh.l  ; Window 
  wt.s  ; Window 
  wf.l  ; Window 

  ; Screen 
  sm.l  ; Screen Mode (0: Windowed, 1: Fullscreen) 
  sx.l  ; Screen X offset (windowed mode) 
  sy.l  ; Screen Y offset (windowed mode) 
  sw.l  ; Screen Width (fullscreen) 
  sh.l  ; Screen Height (fullscreen) 
  sc.l  ; Screen Colour Bits (fullscreen) 
  sd.l  ; Screen Depth Bits (fullscreen) 

  ws.l  ; Window State (0:  Opening, 1: Active, 2: Closing) 
  
EndStructure 

Global wi.WinInfoT 
Global cBlack,cWhite,cRed,cSky 

cBlack  = RGB(0,0,0) 
cWhite  = RGB(255,255,255) 
cRed    = RGB(255,0,0) 
cSky    = RGB(192, 192, 255) 
  
;============================================================================ 

Procedure.l WinResize(w.l, h.l) 
  wi\ww = w: wi\wh = h 
  CloseScreen() 
  OpenWindowedScreen(wi\ph, wi\sx, wi\sy, wi\sw, wi\sh, 1, 0, 0) 
EndProcedure 

Procedure SwitchScreen() 
  wi\sm = wi\sm ! 1 

  If wi\ws 
    CloseScreen() 
  Else 
    wi\ws=1 
  EndIf 
  
  If wi\sm = 0 ; Windowed 
    wi\ph = OpenWindow(wi\pi, wi\wx, wi\wy, wi\ww, wi\wh, wi\wt, wi\wf) 
    OpenWindowedScreen(wi\ph, wi\sx, wi\sy, wi\ww, wi\wh, 0, 0, 0) 
    SetFocus_(wi\ph) 
  Else 
    If wi\ph : CloseWindow(wi\pi) : wi\ph=0 : EndIf 
    OpenScreen(wi\sw,wi\sh,wi\sc,wi\wt) 
  EndIf 

EndProcedure 

;============================================================================ 

If InitSprite()=0 Or InitKeyboard()=0 
  MessageRequester("ERROR","Cant init DirectX !",#MB_ICONERROR):End 
EndIf 

  w=800: h=600: c=32: d=32: 
  wi\wx = 0: wi\wy = 0 
  wi\ww = 800 
  wi\wh = 600 
  wi\sc = 32 
  wi\wf = #PB_Window_SizeGadget|#PB_Window_ScreenCentered|#PB_Window_SystemMenu                    ;#PB_Window_SystemMenu
  wi\wt = "Flip Test" 

  wi\sm = 1 
  wi\sx = 0 
  wi\sy = 0 
  wi\sw = 800 
  wi\sh = 600 

SwitchScreen() 

SetFrameRate(50) 

Repeat 
    FlipBuffers() 
    ExamineKeyboard()
    Input_AltEnter = ((KeyboardPushed(#PB_Key_LeftAlt) Or 0) Or (KeyboardPushed(#PB_Key_RightAlt) Or 0)) And ((KeyboardPushed(#PB_Key_Return) Or 0) Or (KeyboardPushed(#PB_Key_PadEnter) Or 0))

    If IsScreenActive() 
      ClearScreen(RGB(192,192,255)) 

      StartDrawing(ScreenOutput()) 
        DrawingMode(4) 
        Box(0, 0, wi\sw, wi\sh , cRed) 
        LineXY(0, 0, wi\sw, wi\sh , cRed) 
        LineXY(0, wi\sh, wi\sw, 0 , cRed) 
        Circle((wi\sw-1)/2, (wi\sh-1)/2, (wi\sh-1)/2, cRed) 

        DrawingMode(1) 
        FrontColor(RGB(255,255,255)) 
        DrawText(10,10,Str(wi\ww)+","+Str(wi\wh)) 
        DrawText(10,25,Str(wi\sw)+","+Str(wi\sh)) 
      StopDrawing() 

    EndIf 

    If wi\sm = 0 
      Select WindowEvent() 
        Case #WM_SIZE 
          WinResize(WindowWidth(wi\pi),WindowHeight(wi\pi)) 
        Case #PB_Event_CloseWindow
          quit=1
      EndSelect 
    EndIf 

    If Input_AltEnter
      SwitchScreen() 
    EndIf 

    Delay(1) 
    If KeyboardPushed(#PB_Key_Escape) 
      quit=1
    EndIf
Until quit=1

CloseWindow(wi\pi) 


Re: alt-Enter Fullscreen toggle

Posted: Sun Aug 15, 2010 11:35 am
by Blue Steel
thanks much appreciated..

and thanks for the other link too.. very interesting.. i can use something like that for another project ;)

Re: alt-Enter Fullscreen toggle

Posted: Sun Aug 15, 2010 3:20 pm
by Blue Steel
interesting...

examining the code I've found that SetFocus_(xxx) ISN'T in the PureBasic help file :(

another problem i'm having is when i minimise the Screen (not window) eg: through pressing alt-tab and try to re-open it by selecting it. it selects it and makes it active but it doesn't show it until i press alt-enter to swap it to a window again. after that I can press alt-Enter and get it back into fullscreen mode.

can someone tell me how to get the full screen to redisplay when regaining focus through alt-tab

also if i comment out the clearscreen and the i'm in fullscreen mode (a Transparent screen .. very cool) its flickering how do i stop the flickering

I commented out the Procedure WinResize as windows does it automagically (doesn't linux ??)
I also added another procedure it initialise
here is my slightly optomised code (hoping to make the top procedures into an include file ;) for easy re-use)

edit.. code removed.. has changfed heaps .. see my later reply for newest code

Re: alt-Enter Fullscreen toggle

Posted: Sun Aug 15, 2010 7:35 pm
by RASHAD
I just modified the example in the manual
I also modified Danilo snippet
But the next looks much better
Have a look

Code: Select all

Screen_Width  = 320 
Screen_Height = 240 
Screen_Depth  = 16

dm.DEVMODE
EnumDisplaySettings_ (0, #ENUM_CURRENT_SETTINGS, @dm)
FullScreen_Width = dm\dmPelsWidth
FullScreen_Height = dm\dmPelsHeight
FullScreen_Depth = dm\dmBitsPerPel

; Variables 
Scan_Input_AltEnter.b = 0 
Scan_Event_WindowEvent.w = 0 

Screen_Fullscreen.b = 0 


  InitSprite()
  InitKeyboard()
  
    OpenWindow(0, 0, 0,Screen_Width,Screen_Height, "A screen in a window...", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    ;ButtonGadget(0, 170, 135, 45, 20, "Quit")

    OpenWindowedScreen(WindowID(0), 0, 0,Screen_Width,Screen_Height, 0, 0, 0)
    CreateSprite(0, 20, 20)
    direction = 2
    
  Repeat
  ExamineKeyboard() 
  AltEnter = ((KeyboardPushed(#PB_Key_LeftAlt) Or 0) Or (KeyboardPushed(#PB_Key_RightAlt) Or 0)) And ((KeyboardPushed(#PB_Key_Return) Or 0) Or (KeyboardPushed(#PB_Key_PadEnter) Or 0))
   
  ; Switch Screen Modes 
  If AltEnter = #True 
    If Screen_Fullscreen = #True 
       Screen_Fullscreen = #False 
       CloseScreen()
       OpenWindow(0, 0, 0, Screen_Width, Screen_Height, "Hit Alt + Enter to Switch Screen Modes", #PB_Window_ScreenCentered) 
       OpenWindowedScreen(WindowID(0), 0, 0, Screen_Width, Screen_Height,1, 0, 0)
       CreateSprite(0, 20, 20)
     ElseIf Screen_Fullscreen = #False 
      Screen_Fullscreen = #True 
      CloseWindow(0) 
      CloseScreen()
      OpenScreen(FullScreen_Width,FullScreen_Height,FullScreen_Depth, "Hit Alt + Enter to Switch Screen Modes")
      CreateSprite(0, 20, 20)
    EndIf 
  EndIf 
  ; It's very important to process all the events remaining in the queue at each frame
  
  If StartDrawing(SpriteOutput(0))
    Box(0, 0, 20, 20, RGB(255, 0, 155))
    Box(5, 5, 10, 10, RGB(155, 0, 255))
    StopDrawing()
  EndIf
  
    FlipBuffers() 
    ClearScreen(RGB(0, 0, 0))
    DisplaySprite(0, x, x)
    x + direction
  If Screen_Fullscreen = #False
    If x > Screen_Height - 30 : x = Screen_Height - 30: direction = -2 : EndIf
    If x < 0   : direction =  2 : EndIf
  Else
    If x > FullScreen_Height - 30 : direction = -2 : EndIf
    If x < 0   : direction =  2 : EndIf
  EndIf  
    Delay(1)
  Until KeyboardPushed(#PB_Key_Escape)


Re: alt-Enter Fullscreen toggle

Posted: Mon Aug 16, 2010 1:04 am
by J. Baker
Blue Steel wrote:interesting...

examining the code I've found that SetFocus_(xxx) ISN'T in the PureBasic help file :(
Windows API ;)

Re: alt-Enter and alt-tab Fullscreen toggle

Posted: Fri Aug 27, 2010 11:03 am
by Blue Steel
Hi i've been busy working on several procedures to help me as a skeleton for writting a game (games).

so far this is it.

* fullscreen toggle on alt-enter
* handles alt-tab loosing / regaining focus in both window and fullscreen modes
* reduced flicker in window resizing mode
* handles transparent or solid window/screen backgrounds

fixed

* alt-tab

added:

* Press T to Toggle Transparent mode

* Check for closing of fullscreen is minimised, if you close it via taskbar

more comming ..

let me know what you think

Code: Select all

;{  Set up Variables
Global AltTab = 0
Global ScrMode = 1
Global WinState = 0
Global WinH = 0
Global WinId = 0
Global Quit = 0
Global WinX = 0
Global WinY = 0
Global WinWidth = 800
Global WinHeight = 600
Global Transparent = RGBA(255,0,255,0)
Global Background =  Transparent; #Black ; #Blue RGB(r,g,b) RGBA(r,g,b,a)
Global WinFlags = #PB_Window_ScreenCentered|#PB_Window_SizeGadget|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget|#PB_Window_MaximizeGadget
Global Title.s = "test"
Global ScrMode = 0
Global ScrX = 0
Global ScrY = 0
Global ScrWidth = 640
Global ScrHeight = 480
Global ScrDepth = 32
Global cBlack,cWhite,cRed,cSky
cBlack = RGB(0,0,0)
cWhite = RGB(255,255,255)
cRed = RGB(255,0,0)
cSky = RGB(192, 192, 255)
;}

Procedure SwitchScreen()
  ScrMode = ScrMode ! 1
  If WinState
    CloseScreen()
  Else
    WinState=1
  EndIf
  If ScrMode = 0 ; Windowed
    WinH = OpenWindow(WinId, WinX, WinY, WinWidth, WinHeight, Title.s, WinFlags)
    If AltTab
    SetWindowState(WinId,#PB_Window_Minimize) 
    Else     
      SetWindowLong_(WinH,#GWL_EXSTYLE,GetWindowLong_(WinH,#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_COMPOSITED)
      If Background=Transparent
        SetWindowLong_(WinH,#GWL_EXSTYLE,GetWindowLong_(WinH,#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_COMPOSITED)
        SetLayeredWindowAttributes_(WinH, Transparent, 0, #LWA_COLORKEY)
      EndIf 
    EndIf
    OpenWindowedScreen(WinH, ScrX,ScrY, ScrWidth, ScrHeight, 1, 0, 0)
    SetFocus_(WinH)
  Else
    If WinH : CloseWindow(WinId) : WinHeight : EndIf
      If Background=Transparent
      WinH = OpenWindow(WinId, 0, 0, DesktopWidth(0),DesktopHeight(0), Title.s, #PB_Window_BorderLess)
      SetWindowLong_(WinH,#GWL_EXSTYLE,GetWindowLong_(WinH,#GWL_EXSTYLE)|#WS_EX_LAYERED|#WS_EX_COMPOSITED)
      SetLayeredWindowAttributes_(WinH, Transparent, 0, #LWA_COLORKEY)
      OpenWindowedScreen(WinH, ScrX,ScrY, ScrWidth, ScrHeight, 1, 0, 0)
   Else
      OpenScreen(ScrWidth, ScrHeight, ScrDepth, Title.s)
   EndIf
  EndIf
EndProcedure

Procedure RenderScreen()     
  ClearScreen(Background)
    StartDrawing(ScreenOutput())
      DrawingMode(4)
      Box(0, 0, ScrWidth, ScrHeight , cRed)
      LineXY(0, 0, ScrWidth, ScrHeight , cRed)
      LineXY(0, ScrHeight, ScrWidth, 0 , cRed)
      Circle((ScrWidth-1)/2, (ScrHeight-1)/2, (ScrHeight-1)/2, cRed)
      DrawingMode(1)
      FrontColor(RGB(255,255,255))
      If ScrMode=0
        DrawText(10,14,"Screen Size : "+Str(ScrWidth)+","+Str(ScrHeight))
        DrawText(10,28,"Window Size : "+Str(WinWidth)+","+Str(WinHeight))
      Else
        DrawText(10,10,"Screen Size : "+Str(ScrWidth)+","+Str(ScrHeight))
      EndIf
      DrawText(10,42,"Press T to Toggle Transparent mode")
      StopDrawing()
    FlipBuffers()   
EndProcedure
 
Procedure HandleEvents()
  ExamineKeyboard() 
  ;  Toggle_Screen_Mode
  If ((KeyboardPushed(#PB_Key_LeftAlt) Or 0) Or (KeyboardPushed(#PB_Key_RightAlt) Or 0)) And ((KeyboardPushed(#PB_Key_Return) Or 0) Or (KeyboardPushed(#PB_Key_PadEnter) Or 0))
    SwitchScreen()
  EndIf
  
  If ((KeyboardReleased(#PB_Key_T) Or 0)) 
    If Background=Transparent
      Background=#Black
    Else
      Background=Transparent
    EndIf
  ScrMode = ScrMode ! 1
    SwitchScreen()
  EndIf
  If KeyboardPushed(#PB_Key_Escape)
    Quit=1
  EndIf
  
  ; Handle if fullscreen looses focus eg: alt-Tab
  If IsScreenActive() <> 1
    If ScrMode=1 And Background <> Transparent
      AltTab=1
      SwitchScreen()
      Repeat
        Select WindowEvent()
          Case #PB_Event_CloseWindow
            Quit=1
          Default
            ;do nothing
        EndSelect  
        Delay(1)  
      Until IsScreenActive() <>0 Or Quit =1
      SwitchScreen()
      AltTab=0     
    EndIf
  EndIf
  
  If ScrMode=0 Or Background=Transparent
    Select WindowEvent()
      Case #WM_SIZE
        WinWidth = WindowWidth(WinId)
        WinHeight = WindowHeight(WinId)
      Case #PB_Event_CloseWindow
        Quit=1
      Default
        ; do nothing .. just here to clear the queue   
    EndSelect
  EndIf
EndProcedure

If InitSprite()=0 Or InitKeyboard()=0 Or InitMouse()=0 Or ExamineDesktops()=0
  MessageRequester("ERROR","Can't initialize!",#MB_ICONERROR):End
EndIf
; sneaky way of opening window or screen
SwitchScreen()

Repeat
  RenderScreen()
  HandleEvents()
  Delay(1)
Until Quit=1

CloseScreen()
CloseWindow(WinId)


Re: alt-Enter and alt-tab Fullscreen toggle

Posted: Sat Aug 28, 2010 2:48 am
by Blue Steel
ok .. now that I have that working as much as it is.

what i'm looking at trying to do next is
any help would be greatly appreciated