Hi guys,
I'm looking for a solution to add shortcut key to switch between window and fullscreen mode.
I tried to recreate the window like it's recommended for C++, but there is a problem with event handling.
Example:
private RenderWindow _window
; private bool _isFullScreen
; public void Run
() { Init
(); _window
= new RenderWindow
( _isFullScreen
? VideoMode
.DesktopMode : new VideoMode
(800,
800),
"MyApp",
_isFullScreen
? Styles
.Fullscreen : Styles
.Default,
new ContextSettings
() { AntialiasingLevel
= 16 }); _window
.KeyPressed += Window_OnKeyPressed
; _window
.Closed += (s, e
) => _window
.Close(); _window
.SetVisible(true); _window
.SetActive(true); while (_window
.IsOpen) { _window
.DispatchEvents(); // <== Exception appears here Update
(); Render
(); } } private void Window_OnKeyPressed
(object sender, KeyEventArgs e
) { if (e
.Code == Keyboard
.Key.F11) { // close exist window _window
.KeyPressed -= Window_OnKeyPressed
; _window
.MouseButtonPressed -= Window_OnMouseButtonPressed
; _window
.MouseButtonReleased -= Window_OnMouseButtonReleased
; _window
.MouseWheelMoved -= Window_OnMouseWheelMoved
; _window
.Close(); _window
.Dispose(); // create new one _window
= new RenderWindow
( _isFullScreen
? VideoMode
.DesktopMode : new VideoMode
(800,
800),
"MyApp",
_isFullScreen
? Styles
.Fullscreen : Styles
.Default,
new ContextSettings
() { AntialiasingLevel
= 16 }); _window
.KeyPressed += Window_OnKeyPressed
; _window
.Closed += (s, e
) => _window
.Close(); _window
.SetVisible(true); _window
.SetActive(true); } }
This code will produce Access violation exception inside DispatchEvents method:
System.AccessViolationException occurred
HResult=-2147467261
Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Source=sfmlnet-graphics-2
StackTrace:
at SFML.Graphics.RenderWindow.sfRenderWindow_pollEvent(IntPtr CPointer, Event& Evt)
at SFML.Graphics.RenderWindow.PollEvent(Event& eventToFill)
at SFML.Window.Window.DispatchEvents()
Any idea on how to handle keyboard event with no call to DispatchEvent?
Thanks
UPDATED: I found the reason, it's because I call the method Window.Dispose. I commented it and now it works :)
But there is still question - how to dispose window in such case?
here is an example on how I'm using fullscreen toggle.
It's much faster and solves issues such as restore window position/size/state and possible memory leaks.
private readonly Dictionary
<bool, RenderWindow
> _windowCache
= new Dictionary
<bool, RenderWindow
>(); private RenderWindow _window
; private bool _isFullScreen
; public void Dispose
() { DetachWindow
(); foreach (var key
in _windowCache
.Keys.ToArray()) { _windowCache
[key
].Close(); _windowCache
[key
].Dispose(); _windowCache
.Remove(key
); } } public void Run
(string[] args
) { Init
(); AttachWindow
(); while (_window
.IsOpen) { _window
.DispatchEvents(); Update
(); Render
(); } } private void AttachWindow
() { DetachWindow
(); if (!_windowCache
.ContainsKey(_isFullScreen
)) { var window
= new RenderWindow
( _isFullScreen
? VideoMode
.DesktopMode : new VideoMode
(800,
800),
"MyApp",
_isFullScreen
? Styles
.Fullscreen : Styles
.Default,
new ContextSettings
() { AntialiasingLevel
= 16 }); window
.Closed += (s, e
) => _window
.Close(); using (var image
= new Image
("Resources\\AppIcon.png")) { window
.SetIcon(image
.Size.X, image
.Size.Y, image
.Pixels); } _windowCache
[_isFullScreen
] = window
; } _window
= _windowCache
[_isFullScreen
]; _window
.KeyPressed += Window_OnKeyPressed
; _window
.TextEntered += Window_OnTextEntered
; _window
.MouseButtonPressed += Window_OnMouseButtonPressed
; _window
.MouseButtonReleased += Window_OnMouseButtonReleased
; _window
.MouseWheelMoved += Window_OnMouseWheelMoved
; _window
.SetVerticalSyncEnabled(GameSettings
.VSync); _window
.SetVisible(true); _window
.SetActive(true); _window
.RequestFocus(); } private void DetachWindow
() { if (_window
== null) { return; } _window
.KeyPressed -= Window_OnKeyPressed
; _window
.TextEntered -= Window_OnTextEntered
; _window
.MouseButtonPressed -= Window_OnMouseButtonPressed
; _window
.MouseButtonReleased -= Window_OnMouseButtonReleased
; _window
.MouseWheelMoved -= Window_OnMouseWheelMoved
; _window
.SetVisible(false); _window
= null; } private void Window_OnKeyPressed
(object sender, KeyEventArgs e
) { if (e
.Code == Keyboard
.Key.F11 || (e
.Code == Keyboard
.Key.Return && e
.Alt)) { _isFullScreen
= !_isFullScreen
; AttachWindow
(); return; } }