Not sure if you actually want your window to be transparent of if you want your window to be masked. If it's the former, this may help:
WINDOWS ONLYI quickly threw together these functions that are based on
Microsoft's documentation:
void makeWindowTransparent(sf::RenderWindow& window)
{
HWND hwnd = window.getSystemHandle();
SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
}
void makeWindowOpaque(sf::RenderWindow& window)
{
HWND hwnd = window.getSystemHandle();
SetWindowLongPtr(hwnd, GWL_EXSTYLE, GetWindowLongPtr(hwnd, GWL_EXSTYLE) & ~WS_EX_LAYERED);
RedrawWindow(hwnd, NULL, NULL, RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN);
}
inline void setWindowAlpha(sf::RenderWindow& window, sf::Uint8 alpha = 255)
{
SetLayeredWindowAttributes(window.getSystemHandle(), 0, alpha, LWA_ALPHA);
}
Here's an short, example program that shows these functions in use:
#include <SFML/Graphics.hpp>
#include <Windows.h>
// include those functions here
int main()
{
const sf::Color windowColor{ sf::Color(255, 0, 0, 192) };
const sf::Color windowColorGrabbed{ sf::Color(255, 255, 0, 64) };
sf::RenderWindow window(sf::VideoMode(800, 600), "", sf::Style::None);
makeWindowTransparent(window); // allow window to be transparent
sf::Vector2i grabbedOffset;
bool grabbedWindow = false;
while (window.isOpen())
{
sf::Event event;
while (window.pollEvent(event))
{
if (event.type == sf::Event::Closed || event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape)
window.close();
else if (event.type == sf::Event::MouseButtonPressed)
{
if (event.mouseButton.button == sf::Mouse::Left)
{
grabbedOffset = window.getPosition() - sf::Mouse::getPosition();
grabbedWindow = true;
}
}
else if (event.type == sf::Event::MouseButtonReleased)
{
if (event.mouseButton.button == sf::Mouse::Left)
grabbedWindow = false;
}
else if (event.type == sf::Event::MouseMoved)
{
if (grabbedWindow)
window.setPosition(sf::Mouse::getPosition() + grabbedOffset);
}
}
sf::Color clearColor{ windowColor };
if (grabbedWindow)
clearColor = windowColorGrabbed;
setWindowAlpha(window, clearColor.a); // change transparency of window
window.clear(clearColor);
window.display();
}
}
This example program creates a window of a solid colour without any styles and makes it transparent. The window can be moved by clicking and dragging on any part of the window itself. The colour and transparency changes depending on whether or not the window is being dragged. You can close the program using the Escape key; you can also close it using other, standard closing methods.
In this example, I have commented the two lines that call the (Windows only) functions that modify the window's transparency. The example only uses two of the three functions. The third one (makeWindowOpaque), which is unused, allows you to reset the window back to normal if transparency is no longer needed.
It should also show a way to "grab" a window. I noticed that you ended up mixing real-time input and events. I would recommend not using real-time input to determine if the mouse button has been pressed for grabbing as it reads that it's pressed even outside of the window, making your application think it's dragging when it's not. Weirdly, it looks like you copied my previous example of dragging in another post and modified it to this
Be aware that I used SetWindowLongPtr and GetWindowLongPtr, as suggested by the documentation, because they work for both 32-bit and 64-bit. Using SetWindowLong and GetWindowLong only works for 32-bit.
See here.
Note: the
sf::RenderWindow& parameter in the functions can be made const since it doesn't directly affect that object but I left the const off to show that the window it controls will be modified.