This commit is contained in:
恍兮惚兮 2025-01-01 20:48:14 +08:00
parent 3c9336701e
commit 70f186f020
5 changed files with 85 additions and 91 deletions

View File

@ -110,46 +110,6 @@ DECLARE_API void getprocesses(void (*cb)(DWORD, const wchar_t *))
}
}
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;
DECLARE_API UINT GetMonitorDpiScaling(HWND hwnd)
{
HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (!hMonitor)
return 96;
auto pGetDpiForMonitor = (HRESULT(STDAPICALLTYPE *)(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *))GetProcAddress(GetModuleHandleA("Shcore.dll"), "GetDpiForMonitor");
if (pGetDpiForMonitor)
{
UINT dpiX = 0;
UINT dpiY = 0;
HRESULT hr = pGetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
if (FAILED(hr))
return 96;
else
return dpiX;
}
else
{
MONITORINFOEX info;
info.cbSize = sizeof(MONITORINFOEX);
if (!GetMonitorInfo(hMonitor, &info))
return 96;
HDC hdc = GetDC(NULL);
HDC hdcMonitor = CreateCompatibleDC(hdc);
HDC hdcMonitorScreen = CreateIC(TEXT("DISPLAY"), info.szDevice, NULL, 0);
int dpiX = GetDeviceCaps(hdcMonitorScreen, LOGPIXELSX);
DeleteDC(hdcMonitor);
DeleteDC(hdcMonitorScreen);
ReleaseDC(NULL, hdc);
return dpiX;
}
}
DECLARE_API bool check_window_viewable(HWND hwnd)
{
RECT windowRect;

View File

@ -90,12 +90,95 @@ std::vector<byte> SaveBitmapToBuffer(HBITMAP hBitmap)
return data;
}
namespace
{
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;
UINT GetMonitorDpiScaling(HWND hwnd)
{
HMONITOR hMonitor = MonitorFromWindow(hwnd, MONITOR_DEFAULTTONEAREST);
if (!hMonitor)
return 96;
auto pGetDpiForMonitor = (HRESULT(STDAPICALLTYPE *)(HMONITOR, MONITOR_DPI_TYPE, UINT *, UINT *))GetProcAddress(GetModuleHandleA("Shcore.dll"), "GetDpiForMonitor");
if (pGetDpiForMonitor)
{
UINT dpiX = 0;
UINT dpiY = 0;
HRESULT hr = pGetDpiForMonitor(hMonitor, MDT_EFFECTIVE_DPI, &dpiX, &dpiY);
if (FAILED(hr))
return 96;
else
return dpiX;
}
else
{
MONITORINFOEX info;
info.cbSize = sizeof(MONITORINFOEX);
if (!GetMonitorInfo(hMonitor, &info))
return 96;
HDC hdc = GetDC(NULL);
HDC hdcMonitor = CreateCompatibleDC(hdc);
HDC hdcMonitorScreen = CreateIC(TEXT("DISPLAY"), info.szDevice, NULL, 0);
int dpiX = GetDeviceCaps(hdcMonitorScreen, LOGPIXELSX);
DeleteDC(hdcMonitor);
DeleteDC(hdcMonitorScreen);
ReleaseDC(NULL, hdc);
return dpiX;
}
}
bool checkempty(HWND hwnd, RECT &rect)
{
if (rect.bottom == rect.top || rect.left == rect.right)
{
if (rect.top == -1 && rect.left == -1)
{
if (hwnd)
{
GetClientRect(hwnd, &rect);
if (rect.bottom == rect.top || rect.left == rect.right)
return true;
}
else
return true;
}
else
return true;
}
return false;
}
typedef UINT(WINAPI *tGetDpiForWindow)(HWND hwnd);
float dpiscale(HWND hwnd)
{
UINT dpi = 96;
auto pGetDpiForWindow = (tGetDpiForWindow)GetProcAddress(GetModuleHandle(L"user32.dll"), "GetDpiForWindow");
if (pGetDpiForWindow)
{
dpi = pGetDpiForWindow(hwnd);
}
auto mdpi = GetMonitorDpiScaling(hwnd);
return 1.0f * dpi / mdpi;
}
}
DECLARE_API void gdi_screenshot(HWND hwnd, RECT rect, void (*cb)(byte *, size_t))
{
if (rect.bottom == rect.top || rect.left == rect.right)
if (checkempty(hwnd, rect))
return;
if (!hwnd)
hwnd = GetDesktopWindow();
else
{
auto rate = dpiscale(hwnd);
rect.bottom *= rate;
rect.right *= rate;
rect.left *= rate;
rect.top *= rate;
}
auto hdc = GetDC(hwnd);
if (!hdc)
return;

View File

@ -73,8 +73,7 @@ def grabwindow(app="PNG", callback_origin=None, tocliponly=False):
if not hwnd:
return
hwnd = windows.GetAncestor(hwnd)
_ = windows.GetClientRect(hwnd)
p = gdi_screenshot(0, 0, _[2], _[3], hwnd)
p = gdi_screenshot(-1, -1, -1, -1, hwnd)
callback(p, fname + "_gdi." + app)
isshit = (not callback_origin) and (not tocliponly)
if p.isNull() or isshit:
@ -265,16 +264,7 @@ def safepixmap(bs):
return pixmap
def hwndratex(hwnd):
_dpi = windows.GetDpiForWindow(hwnd)
mdpi = winsharedutils.GetMonitorDpiScaling(hwnd)
return mdpi / _dpi
def gdi_screenshot(x1, y1, x2, y2, hwnd=None):
if hwnd:
rate = hwndratex(hwnd)
x1, y1, x2, y2 = (int(_ / rate) for _ in (x1, y1, x2, y2))
bs = winsharedutils.gdi_screenshot(x1, y1, x2, y2, hwnd)
return safepixmap(bs)

View File

@ -257,8 +257,6 @@ _MoveWindow.argtypes = c_int, c_int, c_int, c_int, c_int, c_bool
SetForegroundWindow = _user32.SetForegroundWindow
SetForegroundWindow.argtypes = (HWND,)
_GetClientRect = _user32.GetClientRect
_GetClientRect.argtypes = c_int, POINTER(RECT)
FindWindow = _user32.FindWindowW
FindWindow.argtypes = LPCWSTR, LPCWSTR
@ -267,8 +265,6 @@ SetFocus = _user32.SetFocus
SetFocus.argtypes = (HWND,)
GetFocus = _user32.GetFocus
GetFocus.restype = HWND
_EnumWindows = _user32.EnumWindows
_EnumWindows.argtypes = WNDENUMPROC, c_void_p
_ShellExecuteW = _shell32.ShellExecuteW
_ShellExecuteW.argtypes = c_void_p, c_wchar_p, c_wchar_p, c_wchar_p, c_wchar_p, c_int
_OpenProcess = _kernel32.OpenProcess
@ -474,22 +470,6 @@ def GetWindowRect(hwnd):
return None
def GetClientRect(hwnd):
_rect = RECT()
_GetClientRect(hwnd, pointer(_rect))
return (_rect.left, _rect.top, _rect.right, _rect.bottom)
def GetDpiForWindow(hwnd):
try:
_GetDpiForWindow = _user32.GetDpiForWindow
_GetDpiForWindow.argtypes = (HWND,)
_GetDpiForWindow.restype = UINT
return _GetDpiForWindow(hwnd)
except:
return 96
def GetCursorPos():
_p = POINT()
_GetCursorPos(pointer(_p))
@ -511,10 +491,6 @@ def MoveWindow(hwnd, X, Y, w, h, bRepaint):
return _MoveWindow(hwnd, X, Y, w, h, bRepaint)
def EnumWindows(lpEnumFunc, lParam):
return _EnumWindows(WNDENUMPROC(lpEnumFunc), 0)
def ShellExecute(hwnd: int, op: str, file: str, params: str, _dir: str, bShow):
return _ShellExecuteW(hwnd, op, file, params, _dir, bShow)
@ -749,15 +725,6 @@ def GetAncestor(hwnd):
return _GetAncestor(hwnd, GA_ROOT)
def GetDpiForWindow(hwnd):
try:
_GetDpiForWindow = _user32.GetDpiForWindow
except:
return 96
return _GetDpiForWindow(hwnd)
_ScreenToClient = _user32.ScreenToClient
_ScreenToClient.argtypes = c_void_p, POINTER(POINT)

View File

@ -351,12 +351,6 @@ clipboard_callback.restype = HWND
clipboard_callback_stop = utilsdll.clipboard_callback_stop
clipboard_callback_stop.argtypes = (HWND,)
clipboard_callback_type = CFUNCTYPE(None, c_wchar_p, c_bool)
GetMonitorDpiScaling = utilsdll.GetMonitorDpiScaling
GetMonitorDpiScaling.argtypes = (HWND,)
GetMonitorDpiScaling.restype = UINT
StartCaptureAsync_cb = CFUNCTYPE(None, c_void_p, c_size_t)
StartCaptureAsync = utilsdll.StartCaptureAsync
StartCaptureAsync.argtypes = (StartCaptureAsync_cb,)