Saving and restoring window positions is a common requirement for professional applications. Here's how to implement this feature using file I/O:
First, let's create a simple system to save and load window positions:
#include <SDL.h>
#include <fstream>
#include <string>
#include "Window.h"
class PersistentWindow : public Window {
public:
void SavePosition(
const std::string& Filename) {
int X, Y;
SDL_GetWindowPosition(SDLWindow, &X, &Y);
std::ofstream File{Filename};
if (File) { File << X << ' ' << Y; }
}
bool LoadPosition(
const std::string& Filename) {
std::ifstream File{Filename};
int X, Y;
if (File >> X >> Y) {
SDL_SetWindowPosition(SDLWindow, X, Y);
return true;
}
return false;
}
};
Here's a more robust implementation that handles multiple monitors and screen boundaries:
#include <SDL.h>
#include <filesystem>
#include <fstream>
#include <string>
class PersistentWindow : public Window {
public:
struct WindowState {
int X, Y;
int Width, Height;
bool IsMaximized;
};
void SaveState(const std::string& Filename) {
WindowState State;
// Get current state
SDL_GetWindowPosition(
SDLWindow, &State.X, &State.Y);
SDL_GetWindowSize(
SDLWindow, &State.Width, &State.Height);
State.IsMaximized = SDL_GetWindowFlags(
SDLWindow) & SDL_WINDOW_MAXIMIZED;
// Save to file
std::ofstream File{
Filename, std::ios::binary};
if (File) {
File.write(
reinterpret_cast<char*>(&State),
sizeof(WindowState)
);
}
}
bool RestoreState(
const std::string& Filename) {
// Check if file exists
if (!std::filesystem::exists(Filename)) {
return false;
}
// Read saved state
WindowState State;
std::ifstream File{
Filename, std::ios::binary};
if (!File.read(reinterpret_cast<char*>(
&State),
sizeof(WindowState))) {
return false;
}
// Ensure position is on screen
if (EnsureOnScreen(State)) {
// Apply state
SDL_SetWindowSize(
SDLWindow, State.Width, State.Height);
SDL_SetWindowPosition(
SDLWindow, State.X, State.Y);
if (State.IsMaximized) {
SDL_MaximizeWindow(SDLWindow);
}
return true;
}
return false;
}
private:
bool EnsureOnScreen(WindowState& State) {
SDL_DisplayMode Display;
if (SDL_GetCurrentDisplayMode(
0, &Display) != 0) { return false; }
// Ensure window is at least partially visible
State.X = std::max(
-State.Width / 2,
std::min(
State.X,
Display.w - State.Width / 2
)
);
State.Y = std::max(
0, std::min(State.Y, Display.h - 100));
return true;
}
};
Here's how to use the persistent window:
#include <SDL.h>
#include "PersistentWindow.h"
int main(int argc, char** argv) {
SDL_Init(SDL_INIT_VIDEO);
PersistentWindow Window;
// Try to restore previous position
if (!Window.RestoreState("window.dat")) {
// If no saved position, start centered
SDL_SetWindowPosition(
Window.SDLWindow,
SDL_WINDOWPOS_CENTERED,
SDL_WINDOWPOS_CENTERED
);
}
SDL_Event E;
while (true) {
while (SDL_PollEvent(&E)) {
if (E.type == SDL_QUIT) {
// Save position before exit
Window.SaveState("window.dat");
SDL_Quit();
return 0;
}
}
}
}
This implementation includes several important features:
Remember to consider multi-monitor setups and different screen resolutions when restoring window positions. A position that was valid when saved might not be valid when the application is next launched.
Answers to questions are automatically generated and may not have been reviewed.
Learn how to control and monitor the position of SDL windows on screen