From 70f186f02057a034c24260cc85e48bd171a25235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=81=8D=E5=85=AE=E6=83=9A=E5=85=AE?= <1173718158@qq.com> Date: Wed, 1 Jan 2025 20:48:14 +0800 Subject: [PATCH] . --- cpp/winsharedutils/hwnd.cpp | 40 -------------- cpp/winsharedutils/screenshot.cpp | 85 ++++++++++++++++++++++++++++- py/LunaTranslator/myutils/hwnd.py | 12 +--- py/LunaTranslator/windows.py | 33 ----------- py/LunaTranslator/winsharedutils.py | 6 -- 5 files changed, 85 insertions(+), 91 deletions(-) diff --git a/cpp/winsharedutils/hwnd.cpp b/cpp/winsharedutils/hwnd.cpp index defe0c9b..7426b0f4 100644 --- a/cpp/winsharedutils/hwnd.cpp +++ b/cpp/winsharedutils/hwnd.cpp @@ -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; diff --git a/cpp/winsharedutils/screenshot.cpp b/cpp/winsharedutils/screenshot.cpp index 1361a38c..273295de 100644 --- a/cpp/winsharedutils/screenshot.cpp +++ b/cpp/winsharedutils/screenshot.cpp @@ -90,12 +90,95 @@ std::vector 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; diff --git a/py/LunaTranslator/myutils/hwnd.py b/py/LunaTranslator/myutils/hwnd.py index c93fc960..977deb7a 100644 --- a/py/LunaTranslator/myutils/hwnd.py +++ b/py/LunaTranslator/myutils/hwnd.py @@ -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) diff --git a/py/LunaTranslator/windows.py b/py/LunaTranslator/windows.py index 3b5193a5..26578914 100644 --- a/py/LunaTranslator/windows.py +++ b/py/LunaTranslator/windows.py @@ -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) diff --git a/py/LunaTranslator/winsharedutils.py b/py/LunaTranslator/winsharedutils.py index 0a64d04d..f9913228 100644 --- a/py/LunaTranslator/winsharedutils.py +++ b/py/LunaTranslator/winsharedutils.py @@ -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,)