In this lesson, we'll explore how to control window titles in SDL2 dynamically. We’ll cover how to set, update, and retrieve titles to provide a polished user experience.
As we’ve seen previously, the first argument to SDL_CreateWindow
is a string, representing what we want the title to be. Below, we create a window whose title is "Sample Window":
SDL_CreateWindow(
"Sample Window",
100, 100, 700, 300, 0
);
SDL_SetWindowTitle()
We can change the title of an existing window using the SDL_SetWindowTitle()
function. We pass the SDL_Window
pointer for the window we want to update, and the new title we want it to use:
SDL_SetWindowTitle(WindowPointer, "New Title");
SDL_GetWindowTitle()
We can get a window’s current title by passing its SDL_Window*
to the SDL_GetWindowTitle()
function:
std::cout << SDL_GetWindowTitle(WindowPointer);
New Title
In this example, we’ll update the window title depending on whether or not the window has input focus.
We’ll initialize the window with focus, and then monitor SDL_WindowEvent
events to update the title when the window gains and loses focus through the lifecycle of our program:
#include <SDL.h>
#include "Window.h"
void HandleWindowEvent(
SDL_WindowEvent& E,
SDL_Window* Window
) {
if (
E.event == SDL_WINDOWEVENT_FOCUS_LOST
) {
SDL_SetWindowTitle(
Window, "My Program (Inactive)"
);
} else if (
E.event == SDL_WINDOWEVENT_FOCUS_GAINED
) {
SDL_SetWindowTitle(
Window, "My Program (Active)"
);
}
}
int main(int argc, char** argv) {
SDL_Init(SDL_INIT_VIDEO);
Window GameWindow;
SDL_Event E;
while (true) {
while (SDL_PollEvent(&E)) {
if (E.type == SDL_WINDOWEVENT) {
HandleWindowEvent(
E.window, GameWindow.SDLWindow
);
} else if (E.type == SDL_QUIT) {
SDL_Quit();
return 0;
}
}
GameWindow.Update();
GameWindow.Render();
}
}
In the previous example, we passed the SDL_Window*
to the event handler as an argument, but we can alternatively retrieve it from the event itself.
Most event types, including SDL_WindowEvent
, include a windowID
member that identifies the corresponding window. We can get the SDL_Window*
associated with this ID by passing it to SDL_GetWindowFromID()
:
void HandleWindowEvent(SDL_WindowEvent& E) {
SDL_Window* Window{SDL_GetWindowFromID(
E.windowID
)};
// ...
}
char*
and std::string
SDL uses the char*
data type to represent strings. Any SDL function that accepts a string argument or returns a string value is likely to be using this char*
type. This includes the functions for managing window titles:
// SDL_GetWindowTitle returns a char*
const char* CurrentTitle{SDL_GetWindowTitle(Window)};
// SDL_SetWindowTitle accepts a char*
char* NewTitle{"New Title"};
SDL_SetWindowTitle(Window, NewTitle);
A char*
is a primitive way to represent strings, originating from the early days of the C language. For this reason, they are often referred to as C-style strings.
In modern programs, we typically prefer working with friendlier types, such as the C++ standard library’s std::string
. This type offers useful capabilities in the form of member functions and overloaded operators:
// Get the number of characters in a std::string
// using the length() member function
std::string SomeString{"Hello"};
std::cout << "String Length: " << SomeString.length();
// Compare two standard strings using the
// overloaded == operator
std::string Other{"Hello"};
if (MyString == OtherString) {
std::cout << "\nStrings are the same";
}
char*
and std::string
InteropabilityTo use std::string
in our code, we need to be able to switch to and from the char*
type when interacting with SDL’s API. The std::string
type can help us with this.
When we have a std::string
and need to get the corresponding char*
to send to SDL, we can use the c_str()
method. Let’s update our Window
class with a SetTitle()
method that accepts a std::string
, and uses its c_str()
method to update the SDL window’s title:
#include <SDL.h>
#include <string>
class Window {
public:
// ...
void SetTitle(const std::string& NewTitle) {
SDL_SetWindowTitle(SDLWindow,
NewTitle.c_str());
}
// ...
private:
SDL_Window* SDLWindow{nullptr};
// ...
}
Going in the opposite direction is even easier. The std::string
type includes constructors and an =
operator that accepts a char*
.
So, when SDL returns a char*
, we can directly use it to create or update a std::string
:
#include <SDL.h>
#include <string>
class Window {
public:
// ...
std::string GetTitle() {
return SDL_GetWindowTitle(SDLWindow)
}
// ...
private:
SDL_Window* SDLWindow{nullptr};
// ...
}
Our C++ course has a full chapter on string data types and advanced techniques for working with text, starting with how individual characters are represented digitally:
This lesson covered managing window titles with SDL2. You now know how to set, retrieve, and dynamically update titles. Key Takeaways:
SDL_SetWindowTitle()
updates titles during runtime.SDL_GetWindowTitle()
retrieves the current title.std::string
and char*
improves modern C++ compatibility.Learn C++ and SDL development by creating hands on, practical projects inspired by classic retro games