mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 04:41:05 +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);
|
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
|
namespace sf
|
||||||
@ -141,8 +163,9 @@ m_lastSize (0, 0),
|
|||||||
m_resizing (false),
|
m_resizing (false),
|
||||||
m_surrogate (0),
|
m_surrogate (0),
|
||||||
m_mouseInside (false),
|
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
|
// Set that this process is DPI aware and can handle DPI scaling
|
||||||
setProcessDpiAware();
|
setProcessDpiAware();
|
||||||
@ -174,8 +197,9 @@ m_lastSize (mode.width, mode.height),
|
|||||||
m_resizing (false),
|
m_resizing (false),
|
||||||
m_surrogate (0),
|
m_surrogate (0),
|
||||||
m_mouseInside (false),
|
m_mouseInside (false),
|
||||||
m_fullscreen ((style & Style::Fullscreen) != 0),
|
m_cursorGrabbed ((style & Style::Fullscreen) != 0),
|
||||||
m_cursorGrabbed (m_fullscreen)
|
m_win32Style (translateStyle(style)),
|
||||||
|
m_mode (mode)
|
||||||
{
|
{
|
||||||
// Set that this process is DPI aware and can handle DPI scaling
|
// Set that this process is DPI aware and can handle DPI scaling
|
||||||
setProcessDpiAware();
|
setProcessDpiAware();
|
||||||
@ -192,30 +216,17 @@ m_cursorGrabbed (m_fullscreen)
|
|||||||
int height = mode.height;
|
int height = mode.height;
|
||||||
ReleaseDC(NULL, screenDC);
|
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
|
// 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};
|
RECT rectangle = {0, 0, width, height};
|
||||||
AdjustWindowRect(&rectangle, win32Style, false);
|
AdjustWindowRect(&rectangle, m_win32Style, false);
|
||||||
width = rectangle.right - rectangle.left;
|
width = rectangle.right - rectangle.left;
|
||||||
height = rectangle.bottom - rectangle.top;
|
height = rectangle.bottom - rectangle.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the window
|
// 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)
|
// 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};
|
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;
|
++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
|
// we have to resize it after creation to apply the real size
|
||||||
setSize(Vector2u(mode.width, mode.height));
|
setSize(Vector2u(mode.width, mode.height));
|
||||||
|
|
||||||
// Switch to fullscreen if requested
|
// Switch to fullscreen if requested
|
||||||
if (m_fullscreen)
|
if (style & Style::Fullscreen)
|
||||||
switchToFullscreen(mode);
|
switchToFullscreen();
|
||||||
|
|
||||||
// Increment window count
|
// Increment window count
|
||||||
windowCount++;
|
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()
|
void WindowImplWin32::registerWindowClass()
|
||||||
{
|
{
|
||||||
@ -486,13 +542,13 @@ void WindowImplWin32::registerWindowClass()
|
|||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void WindowImplWin32::switchToFullscreen(const VideoMode& mode)
|
void WindowImplWin32::switchToFullscreen()
|
||||||
{
|
{
|
||||||
DEVMODE devMode;
|
DEVMODE devMode;
|
||||||
devMode.dmSize = sizeof(devMode);
|
devMode.dmSize = sizeof(devMode);
|
||||||
devMode.dmPelsWidth = mode.width;
|
devMode.dmPelsWidth = m_mode.width;
|
||||||
devMode.dmPelsHeight = mode.height;
|
devMode.dmPelsHeight = m_mode.height;
|
||||||
devMode.dmBitsPerPel = mode.bitsPerPixel;
|
devMode.dmBitsPerPel = m_mode.bitsPerPixel;
|
||||||
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
|
devMode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
|
||||||
|
|
||||||
// Apply fullscreen mode
|
// Apply fullscreen mode
|
||||||
@ -507,7 +563,7 @@ void WindowImplWin32::switchToFullscreen(const VideoMode& mode)
|
|||||||
SetWindowLongW(m_handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
|
SetWindowLongW(m_handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
|
||||||
|
|
||||||
// Resize the window so that it fits the entire screen
|
// 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);
|
ShowWindow(m_handle, SW_SHOW);
|
||||||
|
|
||||||
// Set "this" as the current fullscreen window
|
// 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()
|
void WindowImplWin32::cleanup()
|
||||||
{
|
{
|
||||||
|
@ -184,6 +184,22 @@ public:
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
virtual bool hasFocus() const;
|
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:
|
protected:
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -201,12 +217,16 @@ private:
|
|||||||
void registerWindowClass();
|
void registerWindowClass();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Switch to fullscreen mode
|
/// \brief Switch to fullscreen state
|
||||||
///
|
|
||||||
/// \param mode Video mode to switch to
|
|
||||||
///
|
///
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
void switchToFullscreen(const VideoMode& mode);
|
void switchToFullscreen();
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// \brief Switch to windowed state
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void switchToWindowed();
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// \brief Free all the graphical resources attached to the window
|
/// \brief Free all the graphical resources attached to the window
|
||||||
@ -282,8 +302,10 @@ private:
|
|||||||
bool m_resizing; ///< Is the window being resized?
|
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
|
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_mouseInside; ///< Mouse is inside the window?
|
||||||
bool m_fullscreen; ///< Is the window fullscreen?
|
|
||||||
bool m_cursorGrabbed; ///< Is the mouse cursor trapped?
|
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
|
} // namespace priv
|
||||||
|
@ -31,6 +31,8 @@
|
|||||||
#include <SFML/System/Sleep.hpp>
|
#include <SFML/System/Sleep.hpp>
|
||||||
#include <SFML/System/Err.hpp>
|
#include <SFML/System/Err.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
@ -371,8 +373,29 @@ bool Window::hasFocus() const
|
|||||||
void Window::setState(State state)
|
void Window::setState(State state)
|
||||||
{
|
{
|
||||||
if (m_impl)
|
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);
|
m_impl->setState(state);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
Loading…
Reference in New Issue
Block a user