如何在pyqt中給無邊框窗口添加DWM環繞陰影

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 (html

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

)
class WindowEffect:windows

""" 調用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))
相關文章
相關標籤/搜索