Somewhat dpi aware (AND STILL TRANSPARENT) window... (Not really done... Prob. won't ever do..)

pull/130/head
Peter Repukat 3 years ago
parent a7335552ab
commit bc585e0232

@ -131,6 +131,9 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>hid.lib;Cfgmgr32.lib;opengl32.lib;sfml-window-d.lib;sfml-system-d.lib;sfml-graphics-d.lib;dwmapi.lib;xinput9_1_0.lib;setupapi.lib;ViGEmClient.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>hid.lib;Cfgmgr32.lib;opengl32.lib;sfml-window-d.lib;sfml-system-d.lib;sfml-graphics-d.lib;dwmapi.lib;xinput9_1_0.lib;setupapi.lib;ViGEmClient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile> <ClCompile>
@ -149,6 +152,9 @@
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>hid.lib;Cfgmgr32.lib;opengl32.lib;xinput9_1_0.lib;setupapi.lib;ViGEmClient.lib;%(AdditionalDependencies)</AdditionalDependencies> <AdditionalDependencies>hid.lib;Cfgmgr32.lib;opengl32.lib;xinput9_1_0.lib;setupapi.lib;ViGEmClient.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link> </Link>
<Manifest>
<EnableDpiAwareness>PerMonitorHighDPIAware</EnableDpiAwareness>
</Manifest>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="..\deps\imgui-sfml\imgui-SFML.cpp" /> <ClCompile Include="..\deps\imgui-sfml\imgui-SFML.cpp" />

@ -24,23 +24,44 @@ limitations under the License.
#ifdef _WIN32 #ifdef _WIN32
#include <SFML/Graphics.hpp> #include <SFML/Graphics.hpp>
#include <VersionHelpers.h>
#include <Windows.h> #include <Windows.h>
#include <dwmapi.h> #include <dwmapi.h>
#if !defined(WM_DPICHANGED)
#define WM_DPICHANGED 0x02E0
#endif #endif
#endif
TargetWindow::TargetWindow(std::function<void()> on_close, std::vector<std::string> screenshot_hotkey) TargetWindow::TargetWindow(std::function<void()> on_close, std::vector<std::string> screenshot_hotkey)
: on_close_(std::move(on_close)), : on_close_(std::move(on_close)),
screenshot_keys_(std::move(screenshot_hotkey)), screenshot_keys_(std::move(screenshot_hotkey)),
overlay_(window_, [this]() { close(); }) overlay_(window_, [this]() { close(); })
{ {
auto desktop_mode = sf::VideoMode::getDesktopMode();
window_.create(sf::VideoMode::getDesktopMode(), "GlosSITarget", sf::Style::None); #ifdef _WIN32
// For some completely odd reason, the Background becomes black when enabled dpi-awareness and making the window desktop-size.
// Scaling down by 1px each direction is barely noticeable and works.
window_.create(sf::VideoMode(desktop_mode.width - 1, desktop_mode.height - 1, 32), "GlosSITarget", sf::Style::None);
//window_.create(sf::VideoMode(1920, 1080, 24), "GlosSITarget");
#else
window_.create(desktop_mode, "GlosSITarget", sf::Style::None);
#endif
window_.setActive(true); window_.setActive(true);
#ifdef _WIN32 #ifdef _WIN32
HWND hwnd = window_.getSystemHandle(); HWND hwnd = window_.getSystemHandle();
auto dpi = GetWindowDPI(hwnd);
spdlog::debug("Screen DPI: {}", dpi);
// transparent windows window... // transparent windows window...
auto style = GetWindowLong(hwnd, GWL_STYLE);
style &= ~WS_OVERLAPPED;
style |= WS_POPUP;
SetWindowLong(hwnd, GWL_STYLE, style);
DWM_BLURBEHIND bb{.dwFlags = DWM_BB_ENABLE, .fEnable = true, .hRgnBlur = nullptr};
DwmEnableBlurBehindWindow(hwnd, &bb);
MARGINS margins; MARGINS margins;
margins.cxLeftWidth = -1; margins.cxLeftWidth = -1;
DwmExtendFrameIntoClientArea(hwnd, &margins); DwmExtendFrameIntoClientArea(hwnd, &margins);
@ -53,9 +74,15 @@ TargetWindow::TargetWindow(std::function<void()> on_close, std::vector<std::stri
if (EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dev_mode) == 0) { if (EnumDisplaySettings(nullptr, ENUM_CURRENT_SETTINGS, &dev_mode) == 0) {
setFpsLimit(60); setFpsLimit(60);
} else { }
else {
setFpsLimit(dev_mode.dmDisplayFrequency); setFpsLimit(dev_mode.dmDisplayFrequency);
} }
ImGuiIO& io = ImGui::GetIO();
io.FontGlobalScale = dpi / 96.f;
ImGui::SFML::UpdateFontTexture();
#else #else
setFpsLimit(60); setFpsLimit(60);
#endif #endif
@ -72,10 +99,10 @@ void TargetWindow::setClickThrough(bool click_through)
#ifdef _WIN32 #ifdef _WIN32
HWND hwnd = window_.getSystemHandle(); HWND hwnd = window_.getSystemHandle();
if (click_through) { if (click_through) {
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST); SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_TRANSPARENT | WS_EX_TOPMOST | WS_EX_COMPOSITED);
} }
else { else {
SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED); SetWindowLong(hwnd, GWL_EXSTYLE, WS_EX_LAYERED | WS_EX_COMPOSITED);
} }
#endif #endif
} }
@ -83,6 +110,7 @@ void TargetWindow::setClickThrough(bool click_through)
void TargetWindow::update() void TargetWindow::update()
{ {
sf::Event event{}; sf::Event event{};
while (window_.pollEvent(event)) { while (window_.pollEvent(event)) {
Overlay::ProcessEvent(event); Overlay::ProcessEvent(event);
if (event.type == sf::Event::Closed) { if (event.type == sf::Event::Closed) {
@ -91,7 +119,7 @@ void TargetWindow::update()
} }
} }
window_.clear(sf::Color::Transparent); window_.clear(sf::Color(0,0,0,0));
overlay_.update(); overlay_.update();
screenShotWorkaround(); screenShotWorkaround();
window_.display(); window_.display();
@ -186,3 +214,36 @@ WindowHandle TargetWindow::getSystemHandle() const
{ {
return window_.getSystemHandle(); return window_.getSystemHandle();
} }
#ifdef _WIN32
// stolen from: https://building.enlyze.com/posts/writing-win32-apps-like-its-2020-part-3/
typedef HRESULT(WINAPI* PGetDpiForMonitor)(HMONITOR hmonitor, int dpiType, UINT* dpiX, UINT* dpiY);
WORD TargetWindow::GetWindowDPI(HWND hWnd)
{
// Try to get the DPI setting for the monitor where the given window is located.
// This API is Windows 8.1+.
HMODULE hShcore = LoadLibraryW(L"shcore");
if (hShcore) {
PGetDpiForMonitor pGetDpiForMonitor =
reinterpret_cast<PGetDpiForMonitor>(GetProcAddress(hShcore, "GetDpiForMonitor"));
if (pGetDpiForMonitor) {
HMONITOR hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY);
UINT uiDpiX;
UINT uiDpiY;
HRESULT hr = pGetDpiForMonitor(hMonitor, 0, &uiDpiX, &uiDpiY);
if (SUCCEEDED(hr)) {
return static_cast<WORD>(uiDpiX);
}
}
}
// We couldn't get the window's DPI above, so get the DPI of the primary monitor
// using an API that is available in all Windows versions.
HDC hScreenDC = GetDC(0);
int iDpiX = GetDeviceCaps(hScreenDC, LOGPIXELSX);
ReleaseDC(0, hScreenDC);
return static_cast<WORD>(iDpiX);
}
#endif

@ -55,6 +55,10 @@ class TargetWindow {
WindowHandle getSystemHandle() const; WindowHandle getSystemHandle() const;
#ifdef _WIN32
static WORD GetWindowDPI(HWND hWnd);
#endif
private: private:
const std::function<void()> on_close_; const std::function<void()> on_close_;
sf::RenderWindow window_; sf::RenderWindow window_;

Loading…
Cancel
Save