#include <Windows.h>

namespace dpiaware
{
	typedef BOOL (__stdcall *SystemParametersInfoForDpiFunc)(unsigned uiAction, unsigned uiParam, void *pvParam, unsigned fWinIni, unsigned dpi);
	typedef unsigned (__stdcall *GetDpiForWindowFunc)(HWND hwnd);
	typedef BOOL (__stdcall *EnableNonClientDpiScalingFunc)(HWND hwnd);
	typedef BOOL (__stdcall *EnableChildWindowDpiMessageFunc)(HWND hwnd);
	
	static SystemParametersInfoForDpiFunc s_pfnSystemParametersInfoForDpi;
	static GetDpiForWindowFunc s_pfnGetDpiForWindow;
	static EnableNonClientDpiScalingFunc s_pfnEnableNonClientDpiScaling;
	static EnableChildWindowDpiMessageFunc s_pfnEnableChildWindowDpiMessage;

	bool Initialize()
	{
		s_pfnSystemParametersInfoForDpi = (SystemParametersInfoForDpiFunc)GetProcAddress(GetModuleHandleA("user32.dll"), "SystemParametersInfoForDpi");
		s_pfnGetDpiForWindow = (GetDpiForWindowFunc)GetProcAddress(GetModuleHandleA("user32.dll"), "GetDpiForWindow");
		s_pfnEnableNonClientDpiScaling = (EnableNonClientDpiScalingFunc)GetProcAddress(GetModuleHandleA("user32.dll"), "EnableNonClientDpiScaling");
		s_pfnEnableChildWindowDpiMessage = (EnableChildWindowDpiMessageFunc)GetProcAddress(GetModuleHandleA("user32.dll"), "EnableChildWindowDpiMessage");
		return true;
	}

	unsigned GetDpiForWindow(HWND hwnd)
	{
		if (!s_pfnGetDpiForWindow)
			return 96;
		else
			return s_pfnGetDpiForWindow(hwnd);
	}

	bool SystemParametersInfoForDpi(unsigned uiAction, unsigned uiParam, void *pvParam, unsigned fWinIni, unsigned dpi)
	{
		if (!s_pfnSystemParametersInfoForDpi)
			return SystemParametersInfo(uiAction, uiParam, pvParam, fWinIni);
		else
			return s_pfnSystemParametersInfoForDpi(uiAction, uiParam, pvParam, fWinIni, dpi);

	}

	bool EnableNonClientDpiScaling(HWND hwnd)
	{
		if (s_pfnEnableNonClientDpiScaling)
			return s_pfnEnableNonClientDpiScaling(hwnd);
		return true;
	}

	bool EnableChildWindowDpiMessage(HWND hwnd)
	{
		if (s_pfnEnableChildWindowDpiMessage)
			return s_pfnEnableChildWindowDpiMessage(hwnd);
		return true;
	}
}