def __get_hwnd_dpi(window_handle): '''Tkinterを高DPIのディスプレイに対応させるため、DPIとスケーリングを再計算する関数。''' if os.name == 'nt': from ctypes import windll, pointer, wintypes try: windll.shcore.SetProcessDpiAwareness(1) except Exception: # Windows serverやバージョンの低いWindowsでは失敗する pass # 拡大率を100%に設定 DPI100pc = 96 # MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2 DPI_type = 0 winH = wintypes.HWND(window_handle) monitorhandle = windll.user32.MonitorFromWindow(winH, wintypes.DWORD(2)) X = wintypes.UINT() Y = wintypes.UINT() try: windll.shcore.GetDpiForMonitor(monitorhandle, DPI_type, pointer(X), pointer(Y)) return X.value, Y.value, (X.value + Y.value) / (2 * DPI100pc) except Exception: # Windows標準のDPIとスケーリング return 96, 96, 1 else: return None, None, 1
def get_hwnd_dpi(window_handle): """ To detect high DPI displays and avoid need to set Windows compatibility flags :param window_handle: :return: """ import os if os.name == "nt": from ctypes import windll, pointer, wintypes windll.shcore.SetProcessDpiAwareness(1) dpi100pc = 96 # DPI 96 is 100% scaling dpi_type = 0 # MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2 win_h = wintypes.HWND(window_handle) monitorhandle = windll.user32.MonitorFromWindow( win_h, wintypes.DWORD(2)) # MONITOR_DEFAULTTONEAREST = 2 x = wintypes.UINT() y = wintypes.UINT() # noinspection PyBroadException try: windll.shcore.GetDpiForMonitor(monitorhandle, dpi_type, pointer(x), pointer(y)) return x.value, y.value, (x.value + y.value) / (2 * dpi100pc) except Exception: return 96, 96, 1 # Assume standard Windows DPI & scaling else: return None, None, 1 # What to do for other OSs?
def Get_HWND_DPI(window_handle): # To detect high DPI displays and avoid need to set Windows compatibility flags import os if os.name == "nt": from ctypes import windll, pointer, wintypes try: windll.shcore.SetProcessDpiAwareness(1) except Exception: pass # this will fail on Windows Server and maybe early Windows DPI100pc = 96 # DPI 96 is 100% scaling DPI_type = 0 # MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2 winH = wintypes.HWND(window_handle) monitorhandle = windll.user32.MonitorFromWindow( winH, wintypes.DWORD(2) ) # MONITOR_DEFAULTTONEAREST = 2 X = wintypes.UINT() Y = wintypes.UINT() try: windll.shcore.GetDpiForMonitor( monitorhandle, DPI_type, pointer(X), pointer(Y) ) return X.value, Y.value, (X.value + Y.value) / (2 * DPI100pc) except Exception: return 96, 96, 1 # Assume standard Windows DPI & scaling else: return None, None, 1 # What to do for other OSs?
def cb(monitor, dc, rect, data): x = wintypes.UINT() y = wintypes.UINT() ctypes.windll.shcore.GetDpiForMonitor(monitor, 0, ctypes.pointer(x), ctypes.pointer(y)) if (x.value, y.value) != (96, 96): print("DPI Scaling does not seem to be set to 100%") ok.append(False) else: ok.append(True) return 0
def get_window_dpi_scaling(cls, window) -> float: if not cls.deactivate_automatic_dpi_awareness: if sys.platform == "darwin": return 1 # scaling works automatically on macOS elif sys.platform.startswith("win"): from ctypes import windll, pointer, wintypes DPI100pc = 96 # DPI 96 is 100% scaling DPI_type = 0 # MDT_EFFECTIVE_DPI = 0, MDT_ANGULAR_DPI = 1, MDT_RAW_DPI = 2 window_hwnd = wintypes.HWND(window.winfo_id()) monitor_handle = windll.user32.MonitorFromWindow(window_hwnd, wintypes.DWORD(2)) # MONITOR_DEFAULTTONEAREST = 2 x_dpi, y_dpi = wintypes.UINT(), wintypes.UINT() windll.shcore.GetDpiForMonitor(monitor_handle, DPI_type, pointer(x_dpi), pointer(y_dpi)) return (x_dpi.value + y_dpi.value) / (2 * DPI100pc) else: return 1 # DPI awareness on Linux not implemented else: return 1
def proc(onkey, hwnd, msg, wparam, lparam): try: if msg == WM_INPUT: hRawInput = lparam ri = RAWINPUT() cbSize = wintypes.UINT(ctypes.sizeof(ri)) r = user32.GetRawInputData(hRawInput, RID_INPUT, ctypes.byref(ri), ctypes.byref(cbSize), ctypes.sizeof(RAWINPUTHEADER)) rk = ri.keyboard ev = RawKeyEvent(ri.keyboard) onkey(ev) return win32gui.DefWindowProc(hwnd, msg, wparam, lparam) except KeyboardInterrupt: exit(0)
def GetFileVersionInfo(path): if isinstance(path, unicode): GetFileVersionInfoSize = __GetFileVersionInfoSizeW _GetFileVersionInfo = __GetFileVersionInfoW VerQueryValue = __VerQueryValueW VerQueryValueSubBlock1 = unicode(r"\VarFileInfo\Translation") VerQueryValueSubBlock2 = unicode( r"\StringFileInfo\%04x%04x\FileVersion") _string_at = wstring_at else: GetFileVersionInfoSize = __GetFileVersionInfoSizeA _GetFileVersionInfo = __GetFileVersionInfoA VerQueryValue = __VerQueryValueA VerQueryValueSubBlock1 = br"\VarFileInfo\Translation" VerQueryValueSubBlock2 = br"\StringFileInfo\%04x%04x\FileVersion" _string_at = string_at size = GetFileVersionInfoSize(path, None) if not size: return None data = create_string_buffer(size) success = _GetFileVersionInfo(path, 0, size, data) assert success buffer = wintypes.LPVOID() length = wintypes.UINT() success = VerQueryValue(data, VerQueryValueSubBlock1, buffer, length) if not success: return None codepage = tuple(array.array("H", string_at(buffer.value, length.value))) success = VerQueryValue(data, VerQueryValueSubBlock2 % codepage, buffer, length) if not success: return None return _string_at(buffer.value, length.value - 1)
def get_scale_factor_for_monitor(hmonitor): scale_factor = wintypes.UINT() ctypes.windll.shcore.GetScaleFactorForMonitor(hmonitor, ctypes.byref(scale_factor)) return scale_factor.value / 100.0