Permalink
Switch branches/tags
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
94 lines (74 sloc) 2.46 KB
--proc/windows/dpiaware: DPI-awareness API
setfenv(1, require'winapi')
require'winapi.monitor'
--Vista+ DPI awareness flag --------------------------------------------------
ffi.cdef[[
BOOL SetProcessDPIAware(void); // Vista+
BOOL IsProcessDPIAware(void); // Vista+
]]
--NOTE: call this before calling any other window or monitor-related API.
--Calling it later will not return an error but it will have no effect.
function SetProcessDPIAware()
return checknz(C.SetProcessDPIAware())
end
--NOTE: At scaling levels below 150% this function always returns 1
--because DPI Virtualization is disabled at low scaling levels.
function IsProcessDPIAware()
return C.IsProcessDPIAware() == 1
end
--Win8.1+ DPI awareness flag -------------------------------------------------
PROCESS_DPI_UNAWARE = 0
PROCESS_SYSTEM_DPI_AWARE = 1
PROCESS_PER_MONITOR_DPI_AWARE = 2
ffi.cdef[[
HRESULT SetProcessDpiAwarenessInternal(int); // Win8.1+
HRESULT GetProcessDpiAwarenessInternal(HANDLE, int*); // Win8.1+
]]
function SetProcessDPIAwareness(awareness)
checknz(C.SetProcessDpiAwarenessInternal(flags(awareness)))
end
function GetProcessDPIAwareness(handle)
local buf = ffi.new'int[1]'
checknz(C.GetProcessDpiAwarenessInternal(handle, buf))
return buf[0]
end
--Win8.1+ per-monitor DPI setting --------------------------------------------
MDT_EFFECTIVE_DPI = 0
MDT_ANGULAR_DPI = 1
MDT_RAW_DPI = 2
MDT_DEFAULT = MDT_EFFECTIVE_DPI
ffi.cdef[[
HRESULT GetDpiForMonitor(
HMONITOR hmonitor,
int dpiType, // MDT_*
UINT *dpiX,
UINT *dpiY
); // Win8.1+
]]
local shcore
function GetDPIForMonitor(hmonitor, MDT, dx, dy)
shcore = shcore or ffi.load'shcore'
local dx = dx or ffi.new'UINT[1]'
local dy = dy or ffi.new'UINT[1]'
checkz(shcore.GetDpiForMonitor(hmonitor, flags(MDT), dx, dy))
return dx[0], dy[0]
end
--Win8.1+ dpi-changed message ------------------------------------------------
function WM.WM_DPICHANGED(wParam, lParam)
local x, y = splitlong(wParam)
local r = ffi.cast('RECT*', lParam)
return x, y, r.x1, r.y1, r.x2, r.y2
end
if not ... then
local win8_1 = true --enable this if on Win8.1+
if win8_1 then
local awareness = PROCESS_PER_MONITOR_DPI_AWARE
SetProcessDPIAwareness(awareness)
assert(GetProcessDPIAwareness() == awareness)
local mon = assert(MonitorFromPoint())
print('DPI', GetDPIForMonitor(mon, MDT_EFFECTIVE_DPI))
else
SetProcessDPIAware()
assert(IsProcessDPIAware())
end
end