用于EagleEye3.0 规则集漏报和误报测试的示例项目,项目收集于github和gitee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

197 lines
5.0 KiB

#pragma once
#include "SDpiScale.h"
#include <WinUser.h>
#include <wtl.mini/msgcrack.h>
#include <wtl.mini/souimisc.h>
#pragma comment(lib,"version.lib")
namespace SOUI{
class SDpiHelper
{
public:
//»ñÈ¡Ò»¸öPEÎļþµÄversion
static BOOL PEVersion(LPCTSTR pszFileName, WORD &wMajor, WORD &wMinor, WORD & wVer3, WORD & wVer4)
{
DWORD dwResHandle;
void *pBuf;
BOOL bRet = FALSE;
DWORD dwVerInfoSize = GetFileVersionInfoSize(pszFileName, &dwResHandle);
if (!dwVerInfoSize) return FALSE;
pBuf = malloc(dwVerInfoSize);
GetFileVersionInfo(pszFileName, dwResHandle, dwVerInfoSize, pBuf);
UINT nVersionLen;
VS_FIXEDFILEINFO *pstFileVersion;
if (VerQueryValue(pBuf, _T("\\"), (void**)&pstFileVersion, &nVersionLen) && nVersionLen >= sizeof(VS_FIXEDFILEINFO))
{
wVer4 = LOWORD(pstFileVersion->dwFileVersionLS);
wVer3 = HIWORD(pstFileVersion->dwFileVersionLS);
wMinor = LOWORD(pstFileVersion->dwFileVersionMS);
wMajor = HIWORD(pstFileVersion->dwFileVersionMS);
}
free(pBuf);
return TRUE;
}
static BOOL IsVerOrGreater(WORD wVers[4], WORD wMajor, WORD wMinor, WORD wSpBuild = 0)
{
if (wVers[0] < wMajor)
return FALSE;
if (wVers[0] > wMajor)
return TRUE;
if (wVers[1] < wMinor)
return FALSE;
if (wVers[1] > wMinor)
return TRUE;
return wVers[2] >= wSpBuild;
}
static int getScale(HWND hWnd)
{
WORD wVers[4];
PEVersion(_T("ntdll.dll"), wVers[0], wVers[1], wVers[2], wVers[3]);
//win7
if (!IsVerOrGreater(wVers, 6, 1, 7600))
return 100;
int nScale = 100;
//For Win10 1607
if (IsVerOrGreater(wVers, 10, 0, 14955))
{
HMODULE hModule = LoadLibrary(_T("User32.dll"));
if (hModule)
{
typedef UINT(WINAPI *FunGetDpiForWindow)(HWND);
FunGetDpiForWindow GetDpiForWindow = (FunGetDpiForWindow)GetProcAddress(hModule, "GetDpiForWindow");
if (GetDpiForWindow)
{
UINT dpi = GetDpiForWindow(hWnd);
nScale = dpi * 100 / 96;
}
FreeLibrary(hModule);
}
}
//for win 8.1 or later
else if (IsVerOrGreater(wVers, 6, 3))
{
HMODULE hModule = LoadLibrary(_T("Shcore.dll"));
if (hModule)
{
CRect winrc;
GetWindowRect(hWnd, &winrc);
HMONITOR hMonitor = MonitorFromRect(winrc, MONITOR_DEFAULTTONEAREST);
UINT dpiX, dpiY;
typedef enum _MONITOR_DPI_TYPE {
MDT_EFFECTIVE_DPI = 0,
MDT_ANGULAR_DPI = 1,
MDT_RAW_DPI = 2,
MDT_DEFAULT = MDT_EFFECTIVE_DPI
} MONITOR_DPI_TYPE;
typedef HRESULT(WINAPI *FunGetDpiForMonitor)(HMONITOR, MONITOR_DPI_TYPE, UINT*, UINT*);
FunGetDpiForMonitor GetDpiForMonitor = (FunGetDpiForMonitor)GetProcAddress(hModule, "GetDpiForMonitor");
if (GetDpiForMonitor)
{
HRESULT hr = GetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
if (SUCCEEDED(hr))
{
nScale = dpiX * 100 / 96;
}
}
FreeLibrary(hModule);
}
}
else
{
nScale = getScaleOld(hWnd);
}
return nScale;
}
private:
static int getScaleOld(HWND hWnd = NULL)
{
HDC screen = ::GetDC(hWnd);
int nScale = 100;
nScale = GetDeviceCaps(screen, LOGPIXELSX) * 100 / 96;
ReleaseDC(hWnd, screen);
return nScale;
}
};
template <class T>
class SDpiHandler
{
protected:
virtual bool IsDpiAware() const{
return true;
}
void OnDpiChanged(WORD dpi, const RECT* desRect)
{
if(!IsDpiAware())
return;
T *pT = static_cast<T*>(this);
int nScale = dpi * 100 / 96;
nScale = SDpiScale::NormalizeScale(nScale);
HandleScaleChange(nScale, desRect);
}
//ÄܹýÖØдЩº¯ÊýÀ´ÆÁ±ÎһЩ²»´¦ÀíµÄDPI¡£¡£±ÈÈçÖ»Ö§³Ö 100 150 200¡£¡£¡£ËùÓж¼Ö§³Ö»ù±¾²»ÏÖʵ
virtual void HandleScaleChange(WORD nScale, const RECT *desRect)
{
T *pT = static_cast<T*>(this);
if (nScale != pT->SWindow::GetScale()) //As ShostWnd::GetScale is under protect, here, we using SWindow::GetScale.
{
pT->SDispatchMessage(UM_SETSCALE, nScale, 0);
pT->UpdateAutoSizeCount(true);
pT->SetWindowPos(
NULL,
desRect->left,
desRect->top,
desRect->right - desRect->left,
desRect->bottom - desRect->top,
SWP_NOZORDER | SWP_NOACTIVATE);
pT->UpdateAutoSizeCount(false);
}
}
void ScaleHost(HWND hWnd)
{
int nScale = SDpiHelper::getScale(hWnd);
if(!IsDpiAware())
nScale = 100;
nScale = SDpiScale::NormalizeScale(nScale);
CRect rc;
::GetWindowRect(hWnd,&rc);
CSize sz = rc.Size();
sz.cx = sz.cx * nScale / 100;
sz.cy = sz.cy * nScale / 100;
CPoint ntl = rc.CenterPoint();
ntl.Offset(-sz.cx / 2, -sz.cy / 2);
rc = CRect(ntl, sz);
HandleScaleChange(nScale, &rc);
}
public:
BOOL ProcessWindowMessage(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT& lResult, DWORD dwMsgMapID = 0)
{
switch (dwMsgMapID)
{
case 0:
if (uMsg == WM_INITDIALOG)
{
ScaleHost(hWnd);
lResult = 0;
}
if (uMsg == WM_DPICHANGED)
{
OnDpiChanged((WORD)HIWORD(wParam), (RECT* const)lParam);
lResult = 0;
}
break;
}
return FALSE;
}
};
}