mirror of
https://github.com/SFML/SFML.git
synced 2024-11-28 22:31:09 +08:00
Implementation for the window states API on Windows.
This commit is contained in:
parent
c793b81235
commit
0317f83b70
@ -123,6 +123,28 @@ namespace
|
||||
FreeLibrary(user32Dll);
|
||||
}
|
||||
}
|
||||
|
||||
DWORD translateStyle(sf::Uint32 style)
|
||||
{
|
||||
// Choose the window style according to the Style parameter
|
||||
DWORD win32Style = WS_VISIBLE;
|
||||
if (style == sf::Style::None)
|
||||
{
|
||||
win32Style |= WS_POPUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (style & sf::Style::Titlebar) win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
|
||||
if (style & sf::Style::Resize) win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
|
||||
if (style & sf::Style::Close) win32Style |= WS_SYSMENU;
|
||||
}
|
||||
if (!(style & sf::Style::Hidden))
|
||||
{
|
||||
win32Style |= WS_VISIBLE;
|
||||
}
|
||||
|
||||
return win32Style;
|
||||
}
|
||||
}
|
||||
|
||||
namespace sf
|
||||
@ -141,8 +163,9 @@ m_lastSize (0, 0),
|
||||
m_resizing (false),
|
||||
m_surrogate (0),
|
||||
m_mouseInside (false),
|
||||
m_fullscreen (false),
|
||||
m_cursorGrabbed (false)
|
||||
m_cursorGrabbed (false),
|
||||
m_win32Style (translateStyle(Style::None)),
|
||||
m_mode (VideoMode::getDesktopMode())
|
||||
{
|
||||
// Set that this process is DPI aware and can handle DPI scaling
|
||||
setProcessDpiAware();
|
||||
@ -174,8 +197,9 @@ m_lastSize (mode.width, mode.height),
|
||||
m_resizing (false),
|
||||
m_surrogate (0),
|
||||
m_mouseInside (false),
|
||||
m_fullscreen ((style & Style::Fullscreen) != 0),
|
||||
m_cursorGrabbed (m_fullscreen)
|
||||
m_cursorGrabbed ((style & Style::Fullscreen) != 0),
|
||||
m_win32Style (translateStyle(style)),
|
||||
m_mode (mode)
|
||||
{
|
||||
// Set that this process is DPI aware and can handle DPI scaling
|
||||
setProcessDpiAware();
|
||||
@ -192,30 +216,17 @@ m_cursorGrabbed (m_fullscreen)
|
||||
int height = mode.height;
|
||||
ReleaseDC(NULL, screenDC);
|
||||
|
||||
// Choose the window style according to the Style parameter
|
||||
DWORD win32Style = WS_VISIBLE;
|
||||
if (style == Style::None)
|
||||
{
|
||||
win32Style |= WS_POPUP;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (style & Style::Titlebar) win32Style |= WS_CAPTION | WS_MINIMIZEBOX;
|
||||
if (style & Style::Resize) win32Style |= WS_THICKFRAME | WS_MAXIMIZEBOX;
|
||||
if (style & Style::Close) win32Style |= WS_SYSMENU;
|
||||
}
|
||||
|
||||
// In windowed mode, adjust width and height so that window will have the requested client area
|
||||
if (!m_fullscreen)
|
||||
if (!(style & Style::Fullscreen))
|
||||
{
|
||||
RECT rectangle = {0, 0, width, height};
|
||||
AdjustWindowRect(&rectangle, win32Style, false);
|
||||
AdjustWindowRect(&rectangle, m_win32Style, false);
|
||||
width = rectangle.right - rectangle.left;
|
||||
height = rectangle.bottom - rectangle.top;
|
||||
}
|
||||
|
||||
// Create the window
|
||||
m_handle = CreateWindowW(className, title.toWideString().c_str(), win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
|
||||
m_handle = CreateWindowW(className, title.toWideString().c_str(), m_win32Style, left, top, width, height, NULL, NULL, GetModuleHandle(NULL), this);
|
||||
|
||||
// Register to receive device interface change notifications (used for joystick connection handling)
|
||||
DEV_BROADCAST_DEVICEINTERFACE deviceInterface = {sizeof(DEV_BROADCAST_DEVICEINTERFACE), DBT_DEVTYP_DEVICEINTERFACE, 0, GUID_DEVINTERFACE_HID, 0};
|
||||
@ -230,13 +241,13 @@ m_cursorGrabbed (m_fullscreen)
|
||||
++handleCount;
|
||||
}
|
||||
|
||||
// By default, the OS limits the size of the window the the desktop size,
|
||||
// By default, the OS limits the size of the window to the desktop size,
|
||||
// we have to resize it after creation to apply the real size
|
||||
setSize(Vector2u(mode.width, mode.height));
|
||||
|
||||
// Switch to fullscreen if requested
|
||||
if (m_fullscreen)
|
||||
switchToFullscreen(mode);
|
||||
if (style & Style::Fullscreen)
|
||||
switchToFullscreen();
|
||||
|
||||
// Increment window count
|
||||
windowCount++;
|
||||
@ -467,6 +478,51 @@ bool WindowImplWin32::hasFocus() const
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::setState(State state)
|
||||
{
|
||||
State currentState = getState();
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case State::Windowed:
|
||||
if (currentState == State::Fullscreen)
|
||||
switchToWindowed();
|
||||
else
|
||||
ShowWindow(m_handle, SW_RESTORE);
|
||||
break;
|
||||
case State::Minimized:
|
||||
ShowWindow(m_handle, SW_MINIMIZE);
|
||||
break;
|
||||
case State::Maximized:
|
||||
ShowWindow(m_handle, SW_MAXIMIZE);
|
||||
break;
|
||||
case State::Fullscreen:
|
||||
if (currentState != State::Fullscreen)
|
||||
switchToFullscreen();
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
State WindowImplWin32::getState() const
|
||||
{
|
||||
WINDOWPLACEMENT currentState;
|
||||
currentState.length = sizeof(WINDOWPLACEMENT);
|
||||
GetWindowPlacement(m_handle, ¤tState);
|
||||
|
||||
if ((currentState.showCmd == SW_MINIMIZE) || (currentState.showCmd == SW_SHOWMINIMIZED))
|
||||
return State::Minimized;
|
||||
if ((currentState.showCmd == SW_MAXIMIZE) || (currentState.showCmd == SW_SHOWMAXIMIZED))
|
||||
return State::Maximized;
|
||||
if (fullscreenWindow == this)
|
||||
return State::Fullscreen;
|
||||
|
||||
return State::Windowed;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::registerWindowClass()
|
||||
{
|
||||
@ -486,13 +542,13 @@ void WindowImplWin32::registerWindowClass()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::switchToFullscreen(const VideoMode& mode)
|
||||
void WindowImplWin32::switchToFullscreen()
|
||||
{
|
||||
DEVMODE devMode;
|
||||
devMode.dmSize = sizeof(devMode);
|
||||
devMode.dmPelsWidth = mode.width;
|
||||
devMode.dmPelsHeight = mode.height;
|
||||
devMode.dmBitsPerPel = mode.bitsPerPixel;
|
||||
devMode.dmPelsWidth = m_mode.width;
|
||||
devMode.dmPelsHeight = m_mode.height;
|
||||
devMode.dmBitsPerPel = m_mode.bitsPerPixel;
|
||||
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
|
||||
|
||||
// Apply fullscreen mode
|
||||
@ -507,7 +563,7 @@ void WindowImplWin32::switchToFullscreen(const VideoMode& mode)
|
||||
SetWindowLongW(m_handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
|
||||
|
||||
// Resize the window so that it fits the entire screen
|
||||
SetWindowPos(m_handle, HWND_TOP, 0, 0, mode.width, mode.height, SWP_FRAMECHANGED);
|
||||
SetWindowPos(m_handle, HWND_TOP, 0, 0, m_mode.width, m_mode.height, SWP_FRAMECHANGED);
|
||||
ShowWindow(m_handle, SW_SHOW);
|
||||
|
||||
// Set "this" as the current fullscreen window
|
||||
@ -515,6 +571,33 @@ void WindowImplWin32::switchToFullscreen(const VideoMode& mode)
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::switchToWindowed()
|
||||
{
|
||||
// Restore the graphics mode of the display device back to the values from the registry
|
||||
ChangeDisplaySettings(NULL, 0);
|
||||
|
||||
// Set the window flags to what the user requested before switching to fullscreen
|
||||
SetWindowLongW(m_handle, GWL_STYLE, m_win32Style);
|
||||
|
||||
// Compute position and size
|
||||
HDC screenDC = GetDC(NULL);
|
||||
int left = (GetDeviceCaps(screenDC, HORZRES) - static_cast<int>(m_mode.width)) / 2;
|
||||
int top = (GetDeviceCaps(screenDC, VERTRES) - static_cast<int>(m_mode.height)) / 2;
|
||||
ReleaseDC(NULL, screenDC);
|
||||
|
||||
RECT rectangle = {0, 0, static_cast<LONG>(m_mode.width), static_cast<LONG>(m_mode.height)};
|
||||
AdjustWindowRect(&rectangle, m_win32Style, false);
|
||||
int width = rectangle.right - rectangle.left;
|
||||
int height = rectangle.bottom - rectangle.top;
|
||||
|
||||
SetWindowPos(m_handle, HWND_TOP, left, top, width, height, SWP_FRAMECHANGED);
|
||||
|
||||
|
||||
fullscreenWindow = NULL;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
void WindowImplWin32::cleanup()
|
||||
{
|
||||
|
@ -184,6 +184,22 @@ public:
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual bool hasFocus() const;
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Set the window state
|
||||
///
|
||||
/// \param state The new state
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual void setState(State state);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Get the window state
|
||||
///
|
||||
/// \return The window state
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
virtual State getState() const;
|
||||
|
||||
protected:
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -201,12 +217,16 @@ private:
|
||||
void registerWindowClass();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Switch to fullscreen mode
|
||||
///
|
||||
/// \param mode Video mode to switch to
|
||||
/// \brief Switch to fullscreen state
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void switchToFullscreen(const VideoMode& mode);
|
||||
void switchToFullscreen();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Switch to windowed state
|
||||
///
|
||||
////////////////////////////////////////////////////////////
|
||||
void switchToWindowed();
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
/// \brief Free all the graphical resources attached to the window
|
||||
@ -282,8 +302,10 @@ private:
|
||||
bool m_resizing; ///< Is the window being resized?
|
||||
Uint16 m_surrogate; ///< First half of the surrogate pair, in case we're receiving a Unicode character in two events
|
||||
bool m_mouseInside; ///< Mouse is inside the window?
|
||||
bool m_fullscreen; ///< Is the window fullscreen?
|
||||
bool m_cursorGrabbed; ///< Is the mouse cursor trapped?
|
||||
|
||||
const DWORD m_win32Style; ///< Window style in the windows format
|
||||
const VideoMode m_mode; ///< Video mode of the window
|
||||
};
|
||||
|
||||
} // namespace priv
|
||||
|
@ -31,6 +31,8 @@
|
||||
#include <SFML/System/Sleep.hpp>
|
||||
#include <SFML/System/Err.hpp>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace
|
||||
{
|
||||
@ -371,7 +373,28 @@ bool Window::hasFocus() const
|
||||
void Window::setState(State state)
|
||||
{
|
||||
if (m_impl)
|
||||
{
|
||||
// TODO: this if never evaluates to true, even if state IS State::Windowed
|
||||
// I can't figure out why. This is ehy you can only switch to fullscreen once
|
||||
if (state == State::Windowed)
|
||||
{
|
||||
if (this == fullscreenWindow)
|
||||
fullscreenWindow == NULL;
|
||||
}
|
||||
|
||||
if (state == State::Fullscreen)
|
||||
if (fullscreenWindow != NULL)
|
||||
{
|
||||
err() << "Creating more than one fullscreen window is not allowed" << std::endl;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
fullscreenWindow = this;
|
||||
}
|
||||
|
||||
m_impl->setState(state);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user