关于python:如何在pyqt中给无边框窗口添加DWM环绕阴影

12次阅读

共计 2870 个字符,预计需要花费 8 分钟才能阅读完成。

coding:utf-8

from ctypes import POINTER, c_bool, c_int, pointer, sizeof, WinDLL, byref
from ctypes.wintypes import DWORD, HWND, LONG, LPCVOID
from win32 import win32api, win32gui
from win32.lib import win32con
from .c_structures import (

ACCENT_POLICY,
ACCENT_STATE,
MARGINS,
DWMNCRENDERINGPOLICY,
DWMWINDOWATTRIBUTE,
WINDOWCOMPOSITIONATTRIB,
WINDOWCOMPOSITIONATTRIBDATA,

)
class WindowEffect:

"""调用 windows api 实现窗口成果"""
def __init__(self):
    # 调用 api
    self.user32 = WinDLL("user32")
    self.dwmapi = WinDLL("dwmapi")
    self.SetWindowCompositionAttribute = self.user32.SetWindowCompositionAttribute
    self.DwmExtendFrameIntoClientArea = self.dwmapi.DwmExtendFrameIntoClientArea
    self.DwmSetWindowAttribute = self.dwmapi.DwmSetWindowAttribute
    self.SetWindowCompositionAttribute.restype = c_bool
    self.DwmExtendFrameIntoClientArea.restype = LONG
    self.DwmSetWindowAttribute.restype = LONG
    self.SetWindowCompositionAttribute.argtypes = [
        c_int,
        POINTER(WINDOWCOMPOSITIONATTRIBDATA),
    ]
    self.DwmSetWindowAttribute.argtypes = [c_int, DWORD, LPCVOID, DWORD]
    self.DwmExtendFrameIntoClientArea.argtypes = [c_int, POINTER(MARGINS)]
    # 初始化构造体
    self.accentPolicy = ACCENT_POLICY()
    self.winCompAttrData = WINDOWCOMPOSITIONATTRIBDATA()
    self.winCompAttrData.Attribute = WINDOWCOMPOSITIONATTRIB.WCA_ACCENT_POLICY.value[0]
    self.winCompAttrData.SizeOfData = [货币代码](https://www.gendan5.com/currencycode.html)sizeof(self.accentPolicy)
    self.winCompAttrData.Data = pointer(self.accentPolicy)
def setAcrylicEffect(self, hWnd: int, gradientColor: str = "F2F2F230", isEnableShadow: bool = True, animationId: int = 0):
    """ 给窗口开启 Win10 的亚克力成果
    Parameters
    ----------
    hWnd: int
        窗口句柄
    gradientColor: str
        十六进制亚克力混合色,对应 rgba 四个重量
    isEnableShadow: bool
        管制是否启用窗口暗影
    animationId: int
        管制磨砂动画
    """
    # 亚克力混合色
    gradientColor = (gradientColor[6:]
        + gradientColor[4:6]
        + gradientColor[2:4]
        + gradientColor[:2]
    )
    gradientColor = DWORD(int(gradientColor, base=16))
    # 磨砂动画
    animationId = DWORD(animationId)
    # 窗口暗影
    accentFlags = DWORD(0x20 | 0x40 | 0x80 |
                        0x100) if isEnableShadow else DWORD(0)
    self.accentPolicy.AccentState = ACCENT_STATE.ACCENT_ENABLE_ACRYLICBLURBEHIND.value[0]
    self.accentPolicy.GradientColor = gradientColor
    self.accentPolicy.AccentFlags = accentFlags
    self.accentPolicy.AnimationId = animationId
    # 开启亚克力
    self.SetWindowCompositionAttribute(hWnd, pointer(self.winCompAttrData))
def setAeroEffect(self, hWnd: int):
    """ 给窗口开启 Aero 成果
    Parameter
    ----------
    hWnd : 窗口句柄
    """
    self.accentPolicy.AccentState = ACCENT_STATE.ACCENT_ENABLE_BLURBEHIND.value[0]
    # 开启 Aero
    self.SetWindowCompositionAttribute(hWnd, pointer(self.winCompAttrData))
def moveWindow(self, hWnd: int):
    """ 挪动窗口
    Parameter
    ----------
    hWnd : 窗口句柄
    """
    win32gui.ReleaseCapture()
    win32api.SendMessage(hWnd, win32con.WM_SYSCOMMAND, win32con.SC_MOVE + win32con.HTCAPTION, 0)
def addShadowEffect(self, hWnd):
    """ 给窗口增加暗影
    Parameter
    ----------
    hWnd: int or `sip.voidptr`
        窗口句柄
    """
    hWnd = int(hWnd)
    self.DwmSetWindowAttribute(
        hWnd,
        DWMWINDOWATTRIBUTE.DWMWA_NCRENDERING_POLICY.value,
        byref(c_int(DWMNCRENDERINGPOLICY.DWMNCRP_ENABLED.value)),
        4,
    )
    margins = MARGINS(-1, -1, -1, -1)
    self.DwmExtendFrameIntoClientArea(hWnd, byref(margins))
正文完
 0