|
@ -28,6 +28,7 @@ |
|
|
|
|
|
|
|
|
// 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)
|
|
|
|
|
|
// 2020-02-17: Added ImGui_ImplWin32_EnableDpiAwareness(), ImGui_ImplWin32_GetDpiScaleForHwnd(), ImGui_ImplWin32_GetDpiScaleForMonitor() helper functions.
|
|
|
// 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT.
|
|
|
// 2020-01-14: Inputs: Added support for #define IMGUI_IMPL_WIN32_DISABLE_GAMEPAD/IMGUI_IMPL_WIN32_DISABLE_LINKING_XINPUT.
|
|
|
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
|
|
|
// 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor.
|
|
|
// 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter().
|
|
|
// 2019-05-11: Inputs: Don't filter value from WM_CHAR before calling AddInputCharacter().
|
|
@ -337,3 +338,102 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA |
|
|
return 0; |
|
|
return 0; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// DPI-related helpers (optional)
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// - Use to enable DPI awareness without having to create an application manifest.
|
|
|
|
|
|
// - Your own app may already do this via a manifest or explicit calls. This is mostly useful for our examples/ apps.
|
|
|
|
|
|
// - In theory we could call simple functions from Windows SDK such as SetProcessDPIAware(), SetProcessDpiAwareness(), etc.
|
|
|
|
|
|
// but most of the functions provided by Microsoft require Windows 8.1/10+ SDK at compile time and Windows 8/10+ at runtime,
|
|
|
|
|
|
// neither we want to require the user to have. So we dynamically select and load those functions to avoid dependencies.
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
// This is the scheme successfully used by GLFW (from which we borrowed some of the code) and other apps aiming to be highly portable.
|
|
|
|
|
|
// ImGui_ImplWin32_EnableDpiAwareness() is just a helper called by main.cpp, we don't call it automatically.
|
|
|
|
|
|
// If you are trying to implement your own back-end for your own engine, you may ignore that noise.
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
|
|
// Implement some of the functions and types normally declared in recent Windows SDK.
|
|
|
|
|
|
#if !defined(_versionhelpers_H_INCLUDED_) && !defined(_INC_VERSIONHELPERS) |
|
|
|
|
|
static BOOL IsWindowsVersionOrGreater(WORD major, WORD minor, WORD sp) |
|
|
|
|
|
{ |
|
|
|
|
|
OSVERSIONINFOEXW osvi = { sizeof(osvi), major, minor, 0, 0, { 0 }, sp }; |
|
|
|
|
|
DWORD mask = VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR; |
|
|
|
|
|
ULONGLONG cond = ::VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL); |
|
|
|
|
|
cond = ::VerSetConditionMask(cond, VER_MINORVERSION, VER_GREATER_EQUAL); |
|
|
|
|
|
cond = ::VerSetConditionMask(cond, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); |
|
|
|
|
|
return ::VerifyVersionInfoW(&osvi, mask, cond); |
|
|
|
|
|
} |
|
|
|
|
|
#define IsWindows8Point1OrGreater() IsWindowsVersionOrGreater(HIBYTE(0x0602), LOBYTE(0x0602), 0) // _WIN32_WINNT_WINBLUE
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
#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 { MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2, MDT_DEFAULT = MDT_EFFECTIVE_DPI } MONITOR_DPI_TYPE; |
|
|
|
|
|
#endif |
|
|
|
|
|
#ifndef _DPI_AWARENESS_CONTEXTS_ |
|
|
|
|
|
DECLARE_HANDLE(DPI_AWARENESS_CONTEXT); |
|
|
|
|
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE (DPI_AWARENESS_CONTEXT)-3 |
|
|
|
|
|
#endif |
|
|
|
|
|
#ifndef DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 |
|
|
|
|
|
#define DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2 (DPI_AWARENESS_CONTEXT)-4 |
|
|
|
|
|
#endif |
|
|
|
|
|
typedef HRESULT(WINAPI* PFN_SetProcessDpiAwareness)(PROCESS_DPI_AWARENESS); // Shcore.lib + dll, Windows 8.1+
|
|
|
|
|
|
typedef HRESULT(WINAPI* PFN_GetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*); // Shcore.lib + dll, Windows 8.1+
|
|
|
|
|
|
typedef DPI_AWARENESS_CONTEXT(WINAPI* PFN_SetThreadDpiAwarenessContext)(DPI_AWARENESS_CONTEXT); // User32.lib + dll, Windows 10 v1607+ (Creators Update)
|
|
|
|
|
|
|
|
|
|
|
|
// Helper function to enable DPI awareness without setting up a manifest
|
|
|
|
|
|
void ImGui_ImplWin32_EnableDpiAwareness() |
|
|
|
|
|
{ |
|
|
|
|
|
// if (IsWindows10OrGreater()) // This needs a manifest to succeed. Instead we try to grab the function pointer!
|
|
|
|
|
|
{ |
|
|
|
|
|
static HINSTANCE user32_dll = ::LoadLibraryA("user32.dll"); // Reference counted per-process
|
|
|
|
|
|
if (PFN_SetThreadDpiAwarenessContext SetThreadDpiAwarenessContextFn = (PFN_SetThreadDpiAwarenessContext)::GetProcAddress(user32_dll, "SetThreadDpiAwarenessContext")) |
|
|
|
|
|
{ |
|
|
|
|
|
SetThreadDpiAwarenessContextFn(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
if (IsWindows8Point1OrGreater()) |
|
|
|
|
|
{ |
|
|
|
|
|
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
|
|
|
|
|
if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn = (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness")) |
|
|
|
|
|
{ |
|
|
|
|
|
SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE); |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
SetProcessDPIAware(); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
#ifdef _MSC_VER |
|
|
|
|
|
#pragma comment(lib, "gdi32") // Link with gdi32.lib for GetDeviceCaps()
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
|
|
float ImGui_ImplWin32_GetDpiScaleForMonitor(void* monitor) |
|
|
|
|
|
{ |
|
|
|
|
|
UINT xdpi = 96, ydpi = 96; |
|
|
|
|
|
if (IsWindows8Point1OrGreater()) |
|
|
|
|
|
{ |
|
|
|
|
|
static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll"); // Reference counted per-process
|
|
|
|
|
|
if (PFN_GetDpiForMonitor GetDpiForMonitorFn = (PFN_GetDpiForMonitor)::GetProcAddress(shcore_dll, "GetDpiForMonitor")) |
|
|
|
|
|
GetDpiForMonitorFn((HMONITOR)monitor, MDT_EFFECTIVE_DPI, &xdpi, &ydpi); |
|
|
|
|
|
} |
|
|
|
|
|
else |
|
|
|
|
|
{ |
|
|
|
|
|
const HDC dc = ::GetDC(NULL); |
|
|
|
|
|
xdpi = ::GetDeviceCaps(dc, LOGPIXELSX); |
|
|
|
|
|
ydpi = ::GetDeviceCaps(dc, LOGPIXELSY); |
|
|
|
|
|
::ReleaseDC(NULL, dc); |
|
|
|
|
|
} |
|
|
|
|
|
IM_ASSERT(xdpi == ydpi); // Please contact me if you hit this assert!
|
|
|
|
|
|
return xdpi / 96.0f; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
float ImGui_ImplWin32_GetDpiScaleForHwnd(void* hwnd) |
|
|
|
|
|
{ |
|
|
|
|
|
HMONITOR monitor = ::MonitorFromWindow((HWND)hwnd, MONITOR_DEFAULTTONEAREST); |
|
|
|
|
|
return ImGui_ImplWin32_GetDpiScaleForMonitor(monitor); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//---------------------------------------------------------------------------------------------------------
|
|
|