mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-22 20:07:01 +00:00
Backends: Win32: Rework to handle certains Windows 8.1/10 features without a manifest. (#4200, #4191)
This commit is contained in:
parent
020d1ced1d
commit
b66529fe3e
@ -22,7 +22,7 @@
|
|||||||
#include <dwmapi.h>
|
#include <dwmapi.h>
|
||||||
|
|
||||||
// Configuration flags to add in your imconfig.h file:
|
// Configuration flags to add in your imconfig.h file:
|
||||||
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support (this used to be meaningful before <1.81) but we know load XInput dynamically so the option is less relevant now.
|
//#define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD // Disable gamepad support. This was meaningful before <1.81 but we now load XInput dynamically so the option is now less relevant.
|
||||||
|
|
||||||
// Using XInput for gamepad (will load DLL dynamically)
|
// Using XInput for gamepad (will load DLL dynamically)
|
||||||
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
#ifndef IMGUI_IMPL_WIN32_DISABLE_GAMEPAD
|
||||||
@ -33,6 +33,7 @@ typedef DWORD (WINAPI *PFN_XInputGetState)(DWORD, XINPUT_STATE*);
|
|||||||
|
|
||||||
// CHANGELOG
|
// CHANGELOG
|
||||||
// (minor and older changes stripped away, please see git history for details)
|
// (minor and older changes stripped away, please see git history for details)
|
||||||
|
// 2021-06-08: Fix ImGui_ImplWin32_EnableDpiAwareness() and ImGui_ImplWin32_GetDpiScaleForMonitor() to handle Windows 8.1/10 features without a manifest (per-monitor DPI, and properly calls SetProcessDpiAwareness() on 8.1).
|
||||||
// 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS).
|
// 2021-03-23: Inputs: Clearing keyboard down array when losing focus (WM_KILLFOCUS).
|
||||||
// 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
|
// 2021-02-18: Added ImGui_ImplWin32_EnableAlphaCompositing(). Non Visual Studio users will need to link with dwmapi.lib (MinGW/gcc: use -ldwmapi).
|
||||||
// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1.
|
// 2021-02-17: Fixed ImGui_ImplWin32_EnableDpiAwareness() attempting to get SetProcessDpiAwareness from shcore.dll on Windows 8 whereas it is only supported on Windows 8.1.
|
||||||
@ -410,21 +411,30 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA
|
|||||||
// If you are trying to implement your own backend for your own engine, you may ignore that noise.
|
// If you are trying to implement your own backend for your own engine, you may ignore that noise.
|
||||||
//---------------------------------------------------------------------------------------------------------
|
//---------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
// Implement some of the functions and types normally declared in recent Windows SDK.
|
// Perform our own check with RtlVerifyVersionInfo() instead of using functions from <VersionHelpers.h> as they
|
||||||
#if !defined(_versionhelpers_H_INCLUDED_) && !defined(_INC_VERSIONHELPERS)
|
// require a manifest to be functional for checks above 8.1. See https://github.com/ocornut/imgui/issues/4200
|
||||||
static BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp)
|
static BOOL _IsWindowsVersionOrGreater(WORD major, WORD minor, WORD)
|
||||||
{
|
{
|
||||||
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, { 0 }, sp, 0, 0, 0, 0 };
|
typedef LONG(WINAPI* PFN_RtlVerifyVersionInfo)(OSVERSIONINFOEXW*, ULONG, ULONGLONG);
|
||||||
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR;
|
static PFN_RtlVerifyVersionInfo RtlVerifyVersionInfoFn = NULL;
|
||||||
ULONGLONG cond = ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
if (RtlVerifyVersionInfoFn == NULL)
|
||||||
cond = ::VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL);
|
if (HMODULE ntdllModule = ::GetModuleHandleA("ntdll.dll"))
|
||||||
cond = ::VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
RtlVerifyVersionInfoFn = (PFN_RtlVerifyVersionInfo)GetProcAddress(ntdllModule, "RtlVerifyVersionInfo");
|
||||||
return ::VerifyVersionInfoW(&osvi, mask, cond);
|
|
||||||
|
RTL_OSVERSIONINFOEXW versionInfo = { };
|
||||||
|
ULONGLONG conditionMask = 0;
|
||||||
|
versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
|
||||||
|
versionInfo.dwMajorVersion = major;
|
||||||
|
versionInfo.dwMinorVersion = minor;
|
||||||
|
VER_SET_CONDITION(conditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
|
||||||
|
VER_SET_CONDITION(conditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
|
||||||
|
return (RtlVerifyVersionInfoFn(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION, conditionMask) == 0) ? TRUE : FALSE;
|
||||||
}
|
}
|
||||||
#define IsWindowsVistaOrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
|
|
||||||
#define IsWindows8OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WIN8
|
#define _IsWindowsVistaOrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0600), LOBYTE(0x0600), 0) // _WIN32_WINNT_VISTA
|
||||||
#define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0) // _WIN32_WINNT_WINBLUE
|
#define _IsWindows8OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WIN8
|
||||||
#endif
|
#define _IsWindows8Point1OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0603), LOBYTE(0x0603), 0) // _WIN32_WINNT_WINBLUE
|
||||||
|
#define _IsWindows10OrGreater() _IsWindowsVersionOrGreater(HIBYTE(0x0A00), LOBYTE(0x0A00), 0) // _WIN32_WINNT_WINTHRESHOLD / _WIN32_WINNT_WIN10
|
||||||
|
|
||||||
#ifndef DPI_ENUMS_DECLARED
|
#ifndef DPI_ENUMS_DECLARED
|
||||||
typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS;
|
typedef enum { PROCESS_DPI_UNAWARE = 0, PROCESS_SYSTEM_DPI_AWARE = 1, PROCESS_PER_MONITOR_DPI_AWARE = 2 } PROCESS_DPI_AWARENESS;
|
||||||
@ -444,7 +454,7 @@ typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWAR
|
|||||||
// Helper function to enable DPI awareness without setting up a manifest
|
// Helper function to enable DPI awareness without setting up a manifest
|
||||||
void ImGui_ImplWin32_EnableDpiAwareness()
|
void ImGui_ImplWin32_EnableDpiAwareness()
|
||||||
{
|
{
|
||||||
// if (IsWindows10OrGreater()) // This needs a manifest to succeed. Instead we try to grab the function pointer!
|
if (_IsWindows10OrGreater())
|
||||||
{
|
{
|
||||||
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
||||||
if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext"))
|
if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext"))
|
||||||
@ -453,7 +463,7 @@ void ImGui_ImplWin32_EnableDpiAwareness()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (IsWindows8Point1OrGreater())
|
if (_IsWindows8Point1OrGreater())
|
||||||
{
|
{
|
||||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||||
if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness"))
|
if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness"))
|
||||||
@ -474,23 +484,26 @@ void ImGui_ImplWin32_EnableDpiAwareness()
|
|||||||
float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor)
|
||||||
{
|
{
|
||||||
UINT xdpi = 96, ydpi = 96;
|
UINT xdpi = 96, ydpi = 96;
|
||||||
static BOOL bIsWindows8Point1OrGreater = IsWindows8Point1OrGreater();
|
if (_IsWindows8Point1OrGreater())
|
||||||
if (bIsWindows8Point1OrGreater)
|
|
||||||
{
|
{
|
||||||
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
||||||
if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor"))
|
static PFN_GetDpiForMonitor GetDpiForMonitorFn = NULL;
|
||||||
|
if (GetDpiForMonitorFn == NULL && shcore_dll != NULL)
|
||||||
|
GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor");
|
||||||
|
if (GetDpiForMonitorFn != NULL)
|
||||||
|
{
|
||||||
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi);
|
||||||
|
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||||
|
return xdpi / 96.0f;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifndef NOGDI
|
#ifndef NOGDI
|
||||||
else
|
|
||||||
{
|
|
||||||
const HDC dc = ::GetDC(NULL);
|
const HDC dc = ::GetDC(NULL);
|
||||||
xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
|
xdpi = ::GetDeviceCaps(dc, LOGPIXELSX);
|
||||||
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
|
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY);
|
||||||
::ReleaseDC(NULL, dc);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
||||||
|
::ReleaseDC(NULL, dc);
|
||||||
|
#endif
|
||||||
return xdpi / 96.0f;
|
return xdpi / 96.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,7 +526,7 @@ float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd)
|
|||||||
// (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW)
|
// (the Dwm* functions are Vista era functions but we are borrowing logic from GLFW)
|
||||||
void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
||||||
{
|
{
|
||||||
if (!IsWindowsVistaOrGreater())
|
if (!_IsWindowsVistaOrGreater())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BOOL composition;
|
BOOL composition;
|
||||||
@ -522,7 +535,7 @@ void ImGui_ImplWin32_EnableAlphaCompositing(void* hwnd)
|
|||||||
|
|
||||||
BOOL opaque;
|
BOOL opaque;
|
||||||
DWORD color;
|
DWORD color;
|
||||||
if (IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque))
|
if (_IsWindows8OrGreater() || (SUCCEEDED(::DwmGetColorizationColor(&color, &opaque)) && !opaque))
|
||||||
{
|
{
|
||||||
HRGN region = ::CreateRectRgn(0, 0, -1, -1);
|
HRGN region = ::CreateRectRgn(0, 0, -1, -1);
|
||||||
DWM_BLURBEHIND bb = {};
|
DWM_BLURBEHIND bb = {};
|
||||||
|
@ -47,6 +47,9 @@ Other Changes:
|
|||||||
- Demo: Fixed requirement in 1.83 to link with imgui_demo.cpp if IMGUI_DISABLE_METRICS_WINDOW is not set. (#4171)
|
- Demo: Fixed requirement in 1.83 to link with imgui_demo.cpp if IMGUI_DISABLE_METRICS_WINDOW is not set. (#4171)
|
||||||
Normally the right way to disable compiling the demo is to set IMGUI_DISABLE_DEMO_WINDOWS, but we want to avoid
|
Normally the right way to disable compiling the demo is to set IMGUI_DISABLE_DEMO_WINDOWS, but we want to avoid
|
||||||
implying that the file is required.
|
implying that the file is required.
|
||||||
|
- Backends: Win32: Rework to handle certains Windows 8.1/10 features without a manifest. (#4200, #4191)
|
||||||
|
- ImGui_ImplWin32_GetDpiScaleForMonitor() will handle per-monitor DPI on Windows 10 without a manifest.
|
||||||
|
- ImGui_ImplWin32_EnableDpiAwareness() will call SetProcessDpiAwareness() fallback on Windows 8.1 without a manifest.
|
||||||
- Backends: OpenGL3: Handle GL_CLIP_ORIGIN on <4.5 contexts if "GL_ARB_clip_control" extension is detected. (#4170, #3998)
|
- Backends: OpenGL3: Handle GL_CLIP_ORIGIN on <4.5 contexts if "GL_ARB_clip_control" extension is detected. (#4170, #3998)
|
||||||
- Examples: Updated all .vcxproj to VS2015 (toolset v140) to facilitate usage with vcpkg.
|
- Examples: Updated all .vcxproj to VS2015 (toolset v140) to facilitate usage with vcpkg.
|
||||||
- Examples: SDL2: Accomodate for vcpkg install having headers in SDL2/SDL.h vs SDL.h.
|
- Examples: SDL2: Accomodate for vcpkg install having headers in SDL2/SDL.h vs SDL.h.
|
||||||
|
Loading…
Reference in New Issue
Block a user