import tkinter as tk
import tkinter.ttk as ttk
from ctypes import windll, POINTER, Structure, c_bool, sizeof, windll, pointer, c_int
from ctypes.wintypes import DWORD, HWND, ULONG
from enum import Enum
from typing import Literal


from tkdev.devicon import Icon_Empty, Icon_Folder, Icon_Info, Icon_Error, Icon_Warring, Icon_Question, Icon_Questhead, \
    Icon_Hourglass, Icon_QuickFish, Icon_TkinterDev
from tkdev.devresize import DevResize
from tkdev.devcore import DevAction, DevSysTray
from tkdev.devdraw import DrawButton
from tkdev.devpre import DevPreToolbox
from tkdev.winico import DevTray, WM_EVENT, download_winico
import warnings

try:
    from deprecated.sphinx import deprecated
except ImportError:
    pass

try:
    from win32gui import *
    from win32con import *
    from win32api import *
    from win32ui import *
    from win32com import *
except ImportError:
    pass
try:
    import darkdetect
except ImportError:
    pass

dwm = windll.dwmapi
SetWindowCompositionAttribute = windll.user32.SetWindowCompositionAttribute
SetWindowCompositionAttribute()
windll.shcore.SetProcessDpiAwareness(1)
ScaleFactor = windll.shcore.GetScaleFactorForDevice(0)

try:
    taskbar_height = GetMonitorInfo(MonitorFromPoint((0, 0))).get("Monitor")[3] - \
                     GetMonitorInfo(MonitorFromPoint((0, 0))).get("Work")[3]
except NameError:
    pass
Auto = "auto"
Light = "light"
Dark = "dark"

DWMWA_USE_IMMERSIVE_DARK_MODE = 20


def AddShortCut(File, Link="link.lnk", Path: str = ".//"):

    """
    给文件添加一个快捷键到指定位置

    :param File: 指定文件，
    :param Link: 指定快捷键名称。
    :param Path: 指定保存的位置。
    """

    from win32com.client import Dispatch
    from shutil import move
    Shell = Dispatch("WScript.Shell")
    ShortCut = Shell.CreateShortCut(Link)
    ShortCut.TargetPath = File
    ShortCut.save()
    move(Link, Path)


def AddStartMenu(File: str):
    from getpass import getuser
    from shutil import move
    move(File, f"C:\\Users\\{getuser()}\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs")


def AutoStart(File: str, Name: str = "Application"):
    try:
        Key = RegOpenKey(HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Run", 0, KEY_ALL_ACCESS)
        RegSetValueEx(Key, Name, 0, REG_SZ, File)
        RegCloseKey(Key)
    except:
        print('Add Error')


def Package(File, Ofter="-w", StartMenu: bool = True):

    """
    用于打包Python文件。
    """

    try:
        import pyinstaller
    except:
        Install("pyinstaller")
    import sys
    import os
    import os.path

    os.system(os.path.split(sys.executable)[0]+f"\\Scripts\\pyinstaller.exe {Ofter} {File}")

    if StartMenu:
        from getpass import getuser
        print("asdas")
        name = os.path.splitext(os.path.split(File)[1])[0]
        print(name)
        if os.path.exists("dist\\"+name+".exe"):
            path = "dist\\"+name+".exe"
        elif os.path.exists("dist\\"+name+"\\"+name+".exe"):
            path = "dist\\"+name+"\\"+name+".exe"
        print(path)
        print(os.getcwd())
        from win32com.client import Dispatch
        from shutil import move
        Shell = Dispatch("WScript.Shell")
        ShortCut = Shell.CreateShortCut(name+".lnk")
        ShortCut.TargetPath = os.getcwd()+"\\"+path
        ShortCut.save()
        move(name+".lnk", f"C:\\Users\\{getuser()}\\AppData\\Roaming\\Microsoft\\Windows\\Start Menu\\Programs")


def UpGrade(Library, Basic: bool = True, Preview: bool = False, Pypi="https://pypi.tuna.tsinghua.edu.cn/simple/"):
    import os
    import sys
    Pre = ""
    if Basic:
        Librarys = f"-i {Pypi}"
    if Preview:
        Pre = f"--pre"
    print(f"{sys.executable} -m pip install {Library} {Librarys} {Pre} --upgrade")
    os.system(f"{sys.executable} -m pip install {Library} {Librarys} {Pre} --upgrade")


def Install(Library, Basic: bool = True, Preview: bool = False, Pypi="https://pypi.tuna.tsinghua.edu.cn/simple/"):
    import os
    import sys
    Pre = ""
    if Basic:
        Librarys = f"-i {Pypi}"
    if Preview:
        Pre = f"--pre"
    print(f"{sys.executable} -m pip install {Library} {Librarys} {Pre}")
    os.system(f"{sys.executable} -m pip install {Library} {Librarys} {Pre}")


def Install_ALL(Basic=True, Preview: bool = False, Pypi="https://pypi.tuna.tsinghua.edu.cn/simple/"):
    import sys
    Install("win10toast", Basic=Basic, Pypi=Pypi, Preview=Preview)
    Install("pywin32", Basic=Basic, Pypi=Pypi, Preview=Preview)
    if sys.platform == "win32" and sys.getwindowsversion().build >= 22000:
        Install("win32mica", Basic=Basic, Pypi=Pypi, Preview=Preview)
    Install("BlurWindow", Basic=Basic, Pypi=Pypi, Preview=Preview)
    Install("darkdetect", Basic=Basic, Pypi=Pypi, Preview=Preview)
    Install("tkcap", Basic=Basic, Pypi=Pypi, Preview=Preview)
    Install("Deprecated", Basic=Basic, Pypi=Pypi, Preview=Preview)


def UnInstall(Library):
    import os
    import sys
    if Basic:
        print(f"{sys.executable} -m pip uninstall {Library}")
        os.system(f"{sys.executable} -m pip uninstall {Library} ")


class AccentState(Enum):
    ACCENT_DISABLED = 0,
    ACCENT_ENABLE_GRADIENT = 1,
    ACCENT_ENABLE_TRANSPARENTGRADIENT = 2,
    ACCENT_ENABLE_BLURBEHIND = 3,
    ACCENT_ENABLE_ACRYLICBLURBEHIND = 4,
    ACCENT_INVALID_STATE = 5,


class WindowComPositionAttribute(Enum):
    WCA_UNDEFINED = 0,
    WCA_NCRENDERING_ENABLED = 1,
    WCA_NCRENDERING_POLICY = 2,
    WCA_TRANSITIONS_FORCEDISABLED = 3,
    WCA_ALLOW_NCPAINT = 4,
    WCA_CAPTION_BUTTON_BOUNDS = 5,
    WCA_NONCLIENT_RTL_LAYOUT = 6,
    WCA_FORCE_ICONIC_REPRESENTATION = 7,
    WCA_EXTENDED_FRAME_BOUNDS = 8,
    WCA_HAS_ICONIC_BITMAP = 9,
    WCA_THEME_ATTRIBUTES = 10,
    WCA_NCRENDERING_EXILED = 11,
    WCA_NCADORNMENTINFO = 12,
    WCA_EXCLUDED_FROM_LIVEPREVIEW = 13,
    WCA_VIDEO_OVERLAY_ACTIVE = 14,
    WCA_FORCE_ACTIVEWINDOW_APPEARANCE = 15,
    WCA_DISALLOW_PEEK = 16,
    WCA_CLOAK = 17,
    WCA_CLOAKED = 18,
    WCA_ACCENT_POLICY = 19,
    WCA_FREEZE_REPRESENTATION = 20,
    WCA_EVER_UNCLOAKED = 21,
    WCA_VISUAL_OWNER = 22,
    WCA_LAST = 23


class DwmWindowAttribute(Enum):
    DWMWA_NCRENDERING_ENABLED = 1
    DWMWA_NCRENDERING_POLICY = 2
    DWMWA_TRANSITIONS_FORCEDISABLED = 3
    DWMWA_ALLOW_NCPAINT = 4
    DWMWA_CAPTION_BUTTON_BOUNDS = 5
    DWMWA_NONCLIENT_RTL_LAYOUT = 6
    DWMWA_FORCE_ICONIC_REPRESENTATION = 7
    DWMWA_FLIP3D_POLICY = 8
    DWMWA_EXTENDED_FRAME_BOUNDS = 9
    DWMWA_HAS_ICONIC_BITMAP = 10
    DWMWA_DISALLOW_PEEK = 11
    DWMWA_EXCLUDED_FROM_PEEK = 12
    DWMWA_CLOAK = 13
    DWMWA_CLOAKED = 14
    DWMWA_FREEZE_REPRESENTATION = 15
    DWMWA_PASSIVE_UPDATE_MODE = 16
    DWMWA_USE_HOSTBACKDROPBRUSH = 17
    DWMWA_USE_IMMERSIVE_DARK_MODE = 18
    DWMWA_WINDOW_CORNER_PREFERENCE = 19
    DWMWA_BORDER_COLOR = 20
    DWMWA_CAPTION_COLOR = 21
    DWMWA_TEXT_COLOR = 22
    DWMWA_VISIBLE_FRAME_BORDER_THICKNESS = 23
    DWMWA_LAST = 24


class Accent_Poltcy(Structure):
    """ 设置客户区的具体属性 """
    _fields_ = [
        ('AccentState', DWORD),
        ('AccentFlags', DWORD),
        ('GradientColor', DWORD),
        ('AnimationId', DWORD),
    ]


class WindowComPositionAttributeData(Structure):
    _fields_ = [
        ('Attribute', DWORD),
        ('Data', POINTER(Accent_Poltcy)),  # POINTER()接收任何ctypes类型，并返回一个指针类型
        ('SizeOfData', ULONG),
    ]


def dwm_set_window_attribute(window: tk.Tk, attribute, value):
    dwm.DwmSetWindowAttribute(GetParent(window.winfo_id()), attribute, value)


def sendmessage(window: tk.Tk, command, ofter, num):
    SendMessage(GetParent(window.winfo_id()), command, ofter, num)


def window_move(widget: tk.Widget, window: tk.Tk):
    """
    用于拖动窗口。

    :param widget: 为使窗口移动的组件
    :param window: 为被移动的窗口
    """
    def move(evt):
        ReleaseCapture()
        SendMessage(GetParent(window.winfo_id()), WM_SYSCOMMAND,
                    SC_MOVE + HTCAPTION, 0)

    widget.bind("<B1-Motion>", move)


def window_dark(window: tk.Tk):
    """
    设置黑暗主题
    """
    dwm.DwmSetWindowAttribute(GetParent(window.winfo_id()), DWMWA_USE_IMMERSIVE_DARK_MODE, True)


def window_light(window: tk.Tk):
    """
    设置明亮主题
    """
    dwm.DwmSetWindowAttribute(GetParent(window.winfo_id()), DWMWA_USE_IMMERSIVE_DARK_MODE, False)


def window_screenshot(window: tk.Tk, image_name: str = "Image.png"):
    """
    截取窗口图片
    """
    from tkcap import CAP
    cap = CAP(window)
    window.after(800, cap.capture(image_name))
    return cap


def window_acrylic(window: tk.Tk, dark=False, acrylic: bool = False, hexColor: bool = False):
    """
    设置窗口背景材质，改为亚克力材质。
    """
    from BlurWindow.blurWindow import GlobalBlur
    GlobalBlur(GetParent(window.winfo_id()), hexColor=hexColor, Acrylic=acrylic, Dark=dark, QWidget=window)


def window_long(window: tk.Tk, long):
    """
    用于内部工作的组件，设置窗口，

    :param window: 为设置的组件
    :param long: 为设置的参数
    """
    def long():
        hwnd = GetParent(window.winfo_id())
        res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~long)

    window.after(1, long)


def window_ex_long(window: tk.Tk, long):
    """
    用于内部工作的组件，设置扩展窗口。

    :param window: 为设置的组件，
    :param long: 为设置的参数
    """
    hwnd = GetParent(window.winfo_id())
    res = SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~long)


def window_tiled(window: tk.Tk):
    """
    设置窗口标题

    :param window: 为设置的组件，
    """
    hwnd = GetParent(window.winfo_id())
    res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_TILED)


def window_mica_light(window: tk.Tk):
    """
    设置窗口背景材质为云母，并将主题设为明亮

    :param window: 为设置的组件，
    """
    try:
        import win32mica as mc
        mc.debugging = False
    except ImportError:
        pass
    mc.ApplyMica(GetParent(window.winfo_id()), mc.MICAMODE.LIGHT)


def window_mica_dark(window: tk.Tk):
    """
    设置窗口背景材质为云母，并将主题设为暗黑

    :param window: 为设置的组件，
    """
    try:
        import win32mica as mc
        mc.debugging = False
    except ImportError:
        pass
    mc.ApplyMica(GetParent(window.winfo_id()), mc.MICAMODE.DARK)


def window_pos_bottom_right(window: tk.Tk, padx: int = 15, pady: int = 15):
    """
    将窗口放在右下位置，

    :param window: 为设置的组件。
    :param padx: 表示X间距
    :param pady: 表示Y间距
    """
    window.after(1, lambda: window.geometry(
        f"+{window.winfo_screenwidth() - window.winfo_width() - padx - 10}+"
        f"{window.winfo_screenheight() - taskbar_height - window.winfo_height() - pady - 35}"))


def window_pos_bottom_left(window: tk.Tk, padx: int = 15, pady: int = 15):
    """
    将窗口放在左下位置。

    :param window: 为设置的组件。
    :param padx: 表示X间距
    :param pady: 表示Y间距
    """
    window.after(1, lambda: window.geometry(
        f"+{padx}+{window.winfo_screenheight() - taskbar_height - window.winfo_height() - pady - 35}"))


def window_pos_top_right(window: tk.Tk, padx: int = 15, pady: int = 15):
    """
    将窗口放在右上位置。

    :param window: 为设置的组件。
    :param padx: 表示X间距
    :param pady: 表示Y间距
    """
    window.after(1, lambda: window.geometry(
        f"+{window.winfo_screenwidth() - window.winfo_width() - padx - 10}+{pady}"))


def window_pos_top_left(window: tk.Tk, padx: int = 15, pady: int = 15):
    """
    将窗口放在左上位置

    :param window: 为设置的组件。
    :param padx: 表示X间距
    :param pady: 表示Y间距
    """
    window.after(1, lambda: window.geometry(
        f"+{padx}+{pady}"))


def window_sizebox(window: tk.Tk):
    """
    设置窗口是否有调整大小的边框

    :param window: 为设置的组件。
    """
    def sizebox():
        hwnd = GetParent(window.winfo_id())
        res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_SIZEBOX)

    window.after(1, sizebox)


def window_maxbox(window: tk.Tk):
    """
    设置窗口是否有最大化按钮

    :param window: 为设置的组件。
    """
    def max():
        hwnd = GetParent(window.winfo_id())
        res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MAXIMIZEBOX)

    window.after(1, max)


def window_minbox(window: tk.Tk):
    """
    设置窗口是否有最小化按钮

    :param window: 为设置的组件。
    """
    def min():
        hwnd = GetParent(window.winfo_id())
        res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_MINIMIZEBOX)

    window.after(1, min)


def window_grayed_closebox(window: tk.Tk):
    """
    禁用关闭按钮

    :param window: 为设置的组件。
    """
    def close():
        hwnd = GetParent(window.winfo_id())
        res = EnableMenuItem(GetSystemMenu(hwnd, False), SC_CLOSE, MF_BYCOMMAND | MF_GRAYED)

    window.after(1, max)


def window_enabled_closebox(window: tk.Tk):
    """
    启用关闭按钮

    :param window: 为设置的组件。
    """
    def close():
        hwnd = GetParent(window.winfo_id())
        res = EnableMenuItem(GetSystemMenu(hwnd, False), SC_CLOSE, MF_BYCOMMAND | MF_ENABLED)

    window.after(1, max)


def window_popup(window: tk.Tk):
    """
    使窗口变成弹出状态

    :param window: 为设置的组件。
    """
    def popup():
        hwnd = GetParent(window.winfo_id())
        res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_POPUPWINDOW)

    window.after(1, popup)


def window_custom_taskbar(window: tk.Tk):
    """
    自定义窗口，出现在任务栏中

    :param window: 为设置的组件。
    """
    def over():
        hwnd = GetParent(window.winfo_id())
        res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_OVERLAPPEDWINDOW)
        SetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_DRAWFRAME)

    window.after(1, over)
    window.update()


def window_custom_border_taskbar(window: tk.Tk):
    """
    自定义窗口，保留边框，出现在任务栏中

    :param window: 为设置的组件。
    """
    def custom():
        hwnd = GetParent(window.winfo_id())
        res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_BORDER)

    window.after(1, custom)
    window.update()


def window_add_taskbar(window: tk.Tk):
    """
    将窗口放入任务栏

    :param window: 为设置的组件。
    """
    hwnd = GetParent(window.winfo_id())
    res = SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~WS_EX_TOOLWINDOW | WS_EX_APPWINDOW)
    # re-assert the new window style
    window.wm_withdraw()
    window.after(1, lambda: window.wm_deiconify())


def window_border(window: tk.Tk):
    """
    使窗口保留边框，去除标题栏

    :param window: 为设置的组件。
    """
    def border():
        hWnd = GetParent(window.winfo_id())
        SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) & ~WS_CAPTION)
        SetWindowPos(hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_DRAWFRAME)
        UpdateWindow(hWnd)

    window.after(100, border)


def window_embed(window: tk.Tk, toplevel: tk.Toplevel, iswindow: bool = True):
    """
    将窗口嵌入到容器里，

    :param window: 设置为被嵌入的容器
    :param toplevel: 设置为嵌入的窗口
    :param iswindow: 确认容器是否使窗口
    """
    def embed():
        SetParent(GetParent(toplevel.winfo_id()), window.winfo_id())
        toplevel.deiconify()
        if iswindow:
            window.attributes("-topmost", False)

    if iswindow:
        window.attributes("-topmost", True)
    window.after(1, embed)


def window_centre(window: tk.Tk):
    """
    将窗口居中

    :param window: 为设置的组件。
    """
    x = window.winfo_screenwidth() / 2 - window.winfo_width() / 2
    y = window.winfo_screenheight() / 2 - window.winfo_height() / 2
    window.geometry(f"{window.winfo_width()}x{window.winfo_height()}+{round(x)}+{round(y)}")


def window_custom(window: tk.Tk):
    """
    去除窗口标题栏

    :param window: 为设置的组件。
    """
    hwnd = GetParent(window.winfo_id())
    res = SetWindowLong(hwnd, GWL_STYLE, GetWindowLong(hwnd, GWL_STYLE) & ~WS_CAPTION)
    window.update()


def resize_widget(widget: tk.Widget, size: int = 10):
    """
    使窗口可以被调整
    """
    try:
        widget.after(1, lambda: DevResize(widget, size=size))
    except tk.TclError:
        pass


class DevAccumulatorButton(tk.Button):
    def __init__(self):
        super(DevAccumulatorButton, self).__init__()
        pass


class DevAppBar(tk.Frame):
    def __init__(self, master: tk.Widget = None, title: str = "", background="#ffffff", foreground="#000000"):
        """
        应用程序栏，
        """
        super(DevAppBar, self).__init__(master=master, relief=tk.FLAT, background=background)
        self.title = tk.Label(self, text=title, justify=tk.LEFT, background=background, foreground=foreground)
        self.title.pack(fill=tk.Y, side=tk.LEFT, padx=10, pady=5)

    def show(self):
        """
        显示组件在窗口的最上方
        """
        self.pack(fill=tk.X, ipadx=10, ipady=10)


class DevButton(tk.Button):
    def __init__(self, master, text: str = "", borderwidth: int = 0, image=None, font=("等线 Light", 10, "bold"),
                 command=None,
                 default_bg="#ffffff", default_fg="#000000",
                 active_bg="#177aff", active_fg="#d6eaff",
                 click_bg="#175bff", click_fg="#d6deff"):
        super(DevButton, self).__init__(master=master, relief=tk.FLAT, text=text, font=float, command=command,
                                        borderwidth=borderwidth, image=image,
                                        background=default_bg, foreground=default_fg)
        self.default_bg = default_bg
        self.default_fg = default_fg
        self.active_bg = active_bg
        self.active_fg = active_fg
        self.click_bg = click_bg
        self.click_fg = click_fg
        self.bind("<Leave>", self.nofocus)
        self.bind("<Enter>", self.focus)
        self.bind("<Button-1>", self.click)

    def nofocus(self, event=None):
        self.configure(background=self.default_bg, foreground=self.default_fg)

    def focus(self, event=None):
        self.configure(background=self.active_bg, foreground=self.active_fg)

    def click(self, event=None):
        self.configure(activebackground=self.click_bg, activeforeground=self.click_fg)


class DevDrag(object):
    def __init__(self, widget: tk.Widget, dragwidget: tk.Widget, iswindow: bool = False, x: bool = True, y: bool = True,
                 click_func=None, noclick_func=None, move_func=None):
        """
        这个组件能够拖动组件移动，实现更高级的功能。

        :param widget: 设为拖动命令的组件，你拖动这个组件，拖动的组件会移动。
        :param dragwidget: 设为被拖动的组件。
        :param iswindow: 是声明你要拖动的组件是窗口还是组件，是窗口填True，是组件填False。
        """
        self.widget = widget
        self.dragwidget = dragwidget
        self.iswindow = iswindow
        self.movex = tk.IntVar(self.widget, value=0)
        self.movey = tk.IntVar(self.widget, value=0)
        self.moved = tk.BooleanVar(self.widget, value=False)
        if click_func is None:
            self.widget.bind("<Button-1>", self.click)
        else:
            self.widget.bind("<Button-1>", click_func)
        if noclick_func is None:
            self.widget.bind("<ButtonRelease-1>", self.noclick)
        else:
            self.widget.bind("<ButtonRelease-1>", noclick_func)
        if move_func is None:
            self.widget.bind("<B1-Motion>", self.move)
        else:
            self.widget.bind("<B1-Motion>", move_func)
        self.x = x
        self.y = y

    def move(self, event=None):
        """
        内置函数，处理被拖动时移动
        """
        if not self.moved.get():
            return

        if self.x:
            newx = self.dragwidget.winfo_x() + (event.x - self.movex.get())
        else:
            newx = self.dragwidget.winfo_x()

        if self.y:
            newy = self.dragwidget.winfo_y() + (event.y - self.movey.get())
        else:
            newy = self.dragwidget.winfo_y()
        geometry = f"{self.dragwidget.winfo_width()}x{self.dragwidget.winfo_height()}+{newx}+{newy}"
        if self.iswindow:
            self.dragwidget.geometry(geometry)
        else:
            self.dragwidget.place(x=newx, y=newy, width=self.dragwidget.winfo_width(),
                                  height=self.dragwidget.winfo_height())
        self.widget.update()

    def click(self, event=None):
        """
        内置函数，处理被点击时记录按下时的位置信息
        """
        self.movex.set(event.x)
        self.movey.set(event.y)
        self.moved.set(True)

    def noclick(self, event=None):
        """
        内置函数，处理放开后设置是否按下为否
        """
        self.moved.set(False)


class DevDocs(tk.PanedWindow):
    def __init__(self, master: tk.Widget):
        super(DevDocs, self).__init__(master=master, orient=tk.HORIZONTAL, height=3)
        self.docsvar = tk.StringVar()
        self.docslist_area = tk.Frame(self)
        self.docslist = tk.Listbox(self.docslist_area, listvariable=self.docsvar)
        self.docslist.bind("<<ListboxSelect>>", self.check)
        self.docslist.pack(fill=tk.BOTH, expand=tk.YES)
        self.docscheck = {}
        self.docstext_area = tk.Frame(self)
        self.docstext = tk.Text(self.docstext_area)
        self.docstext.pack(fill=tk.BOTH, expand=tk.YES)

        self.add(self.docslist_area)
        self.add(self.docstext_area)

    def check(self, event=None):
        self.docstext.delete("0.0", tk.END)
        list = self.docslist.curselection()
        self.docstext.insert("0.0", self.docscheck[list])

    def add_docs(self, list_name: str = "", docs_text: str = ""):
        self.docslist.insert(tk.END, list_name)
        self.docscheck[list_name] = docs_text


class DevExtend(tk.Frame):
    def __init__(self, master: tk.Widget, label: tk.Widget = None, text: str = "", widget: tk.Widget = tk.Message):
        super(DevExtend, self).__init__(master=master)
        if label is None:
            self.label = tk.Label()
        self.text = text
        self.widget = widget

        self.label.pack(fill=tk.X, side=tk.TOP)
        self.extend_area = tk.Frame()
        self.extend_area.pack(fill=tk.BOTH, expand=tk.YES)


class DevFoldFrame(tk.Frame):
    def __init__(self):
        super(DevFoldFrame, self).__init__()


class DevHeaderBar(tk.Frame):
    def __init__(self, master: tk.Tk, border: bool = True, background="#ffffff", double_max: bool = True):
        """
        标题栏组件，能够自定义窗口标题栏。

        :param master: 为被设置窗口。
        :param border: 设置是否保留边框
        :param background: 设置标题栏背景
        :param double_max: 设置是否可以通过双击按钮最大化。
        """
        super(DevHeaderBar, self).__init__(master=master, background=background, height=35)
        self.master = master
        self.master.configure(background="#fdfdfd")
        self.hWnd = GetParent(self.master.winfo_id())
        if border:
            window_border(self.master)
        elif not border:
            window_custom_taskbar(self.master)
        window_move(self, self.master)
        self.ismaximize = False
        if double_max:
            self.bind("<Double-Button-1>", lambda evt: self.maximize())

    def add_close_button(self, text: str = "🗙", font=("微软雅黑", 9),
                         background="#ffffff", foreground="#000000",
                         activebackground="#c42b1c", activeforeground="#ffffff"):
        """
        为标题栏添加关闭按钮。

        :param text: 为关闭按钮的文本
        :param font: 为关闭按钮的字体
        :param background: 为关闭按钮的背景颜色
        :param foreground: 为关闭按钮的前景颜色
        :param activebackground: 为关闭按钮触发时的背景颜色
        :param activeforeground: 为关闭按钮触发时的前景颜色
        """
        self.close_button = tk.Button(self, text=text, border=0, font=font,
                                      background=background, foreground=foreground,
                                      activebackground=activebackground, activeforeground=activeforeground,
                                      command=lambda: self.master.destroy())
        self.close_button.pack(side=tk.RIGHT, ipady=1, ipadx=10, fill=tk.Y)

    def add_maximize_button(self, text: str = "🗖", font=("微软雅黑", 9),
                            background="#ffffff", foreground="#000000",
                            activebackground="#e9e9e9", activeforeground="#b5b5b5"):
        """
        为标题栏添加最大化按钮，

        :param text: 为最大化按钮的文本
        :param font: 为最大化按钮的字体
        :param background: 为最大化按钮的背景颜色
        :param foreground: 为最大化按钮的前景颜色
        :param activebackground: 为最大化按钮触发时的背景颜色
        :param activeforeground: 为最大化按钮触发时的前景颜色
        """
        self.maxmize_button = tk.Button(self, text=text, border=0, font=font,
                                        background=background, foreground=foreground,
                                        activebackground=activebackground, activeforeground=activeforeground,
                                        command=self.maximize_event)
        self.maxmize_button.pack(side=tk.RIGHT, ipady=2, ipadx=12, fill=tk.Y)

    def add_minimize_button(self, text: str = "🗕", font=("微软雅黑", 9),
                            background="#ffffff", foreground="#000000",
                            activebackground="#e9e9e9", activeforeground="#b5b5b5"):
        """
        为标题栏添加最小化按钮，

        :param text: 为最小化按钮的文本
        :param font: 为最小化按钮的字体
        :param background: 为最小化按钮的背景颜色
        :param foreground: 为最小化按钮的前景颜色
        :param activebackground: 为最小化按钮触发时的背景颜色
        :param activeforeground: 为最小化按钮触发时的前景颜色
        """
        self.minimize_button = tk.Button(self, text=text, border=0, font=font,
                                         background=background, foreground=foreground,
                                         activebackground=activebackground, activeforeground=activeforeground,
                                         command=self.minimize)
        self.minimize_button.pack(side=tk.RIGHT, ipady=2, ipadx=12, fill=tk.Y)

    def maximize_event(self):
        """
        内置函数，使窗口最大化
        """
        if self.ismaximize:
            self.master.state("normal")
            self.maxmize_button.configure(text="🗖")
            self.ismaximize = False
        elif not self.ismaximize:
            self.master.state("zoomed")
            self.maxmize_button.configure(text="🗗")
            self.ismaximize = True

    def minimize(self):
        """
        内置函数，使窗口最小化
        """
        self.master.state('icon')

    def maximize(self):
        """
        内置函数，使窗口最大化
        """
        if self.ismaximize:
            self.master.state("normal")
            self.ismaximize = False
        elif not self.ismaximize:
            self.master.state("zoomed")
            self.ismaximize = True


class DevImage(tk.Label):
    def __init__(self, master: tk.Widget, image: tk.PhotoImage = None, ):
        super(DevImage, self).__init__(master=master, image=image)


class DevMenu(tk.Menubutton):
    def __init__(self, master=None, menu: tk.Menu = None, text: str = "", bg="#fafafa", fg="#000000",
                 active_bg="#3c7bfc", active_fg="#ffffff"):
        super(DevMenu, self).__init__(master=master, menu=menu, text=text, relief=tk.FLAT, background=bg, foreground=fg,
                                      activebackground=active_bg, activeforeground=active_fg)


class DevMenuBar(tk.Frame):
    def __init__(self, master: tk.Widget, bg="#fafafa"):
        super(DevMenuBar, self).__init__(master=master, background=bg)

    def add_menu(self, menu: DevMenu, side=tk.LEFT):
        menu.pack(side=side)

    def show(self):
        self.pack(fill=tk.X, side=tk.TOP)


class DevObject(object):
    def __init__(self):
        """
        可以用于存储组件
        """
        self.obj = {}

    def add_widget(self, widget: tk.Widget, id: str):
        """
        添加组件

        :param widget: 为被存储的组件
        :param id: 为存储组件的ID
        """
        self.obj[id] = widget

    def set_widget(self, id: str, widget: tk.Widget):
        """
        设置组件

        :param widget: 为被存储的组件
        :param id: 为存储组件的ID
        """
        self.obj[id] = widget

    def get_widget(self, id: str) -> tk.Widget:
        """
        获取组件

        :param id: 为存储组件的ID
        """
        return self.obj[id]


class DevPopupWindow(tk.Toplevel):
    def __init__(self, master, widget: tk.Widget):
        """
        这个组件有些不稳定，还在研发当中，请谨慎使用

        :param master:
        :param wiget:
        """
        super(DevPopupWindow, self).__init__(master=master)
        self.overrideredirect(True)
        self.withdraw()
        widget.bind("<Button-1>", lambda event: self.popup(widget.winfo_x() + widget.winfo_width(),
                                                           widget.winfo_y() + widget.winfo_height()))
        self.bind("<Button-3>", lambda event: self.withdraw())

    def popup(self, x=0, y=0):
        self.deiconify()
        self.geometry(f"+{x}+{y}")


class DevBorder(object):
    def __init__(self, widget: tk.Widget = None, iswindow: bool = True, border_color="#e1e1e1"):
        self.widget = widget
        self.iswindow = iswindow
        self.top = tk.Frame(widget, height=0, cursor="sb_v_double_arrow", background=border_color)
        self.top.pack(side=tk.TOP, ipady=1, fill=tk.X)
        self.bottom = tk.Frame(widget, height=0, cursor="sb_v_double_arrow", background=border_color)
        self.bottom.pack(side=tk.BOTTOM, ipady=1, fill=tk.X)
        self.left = tk.Frame(widget, height=0, cursor="sb_h_double_arrow", background=border_color)
        self.left.pack(side=tk.LEFT, ipadx=1, fill=tk.Y)
        self.right = tk.Frame(widget, height=0, cursor="sb_h_double_arrow", background=border_color)
        self.right.pack(side=tk.RIGHT, ipadx=1, fill=tk.Y)

    def top_click(self, evt=None):
        self._topx = self.top.winfo_x()
        self._topy = self.top.winfo_y()
        self._widgetx = self.widget.winfo_x()
        self._widgety = self.widget.winfo_y()
        self._widgetrootx = self.widget.winfo_rootx()
        self._widgetrooty = self.widget.winfo_rooty()

    def top_move(self, evt=None):
        widgetx = 0
        if self.iswindow:
            self.widget.geometry(f"")

    def bottom_move(self, evt=None):
        if self.iswindow:
            self.widget.geometry(f"{self.widget.winfo_width()}x{self.bottom.winfo_y()}")


class DevStack(tk.Frame):
    def __init__(self):
        super(DevStack, self).__init__()
        self._pages = {}

    def add_page(self, page: tk.Widget, id: int = 0):
        self._pages[id] = page

    def show_page(self, id: int):
        self._pages[id].pack(fill=tk.BOTH, expand=tk.YES)
        for item in self._pages.keys():
            if not item == id:
                self.hide_page(item)
                print("Hide" + str(item))
            else:
                print("Show" + str(item))

    def hide_page(self, id: int):
        self._pages[id].pack_forget()

    def get_pages(self):
        return self._pages


class DevSideBar(tk.Frame):
    def __init__(self, master: tk.Widget, background="#ffffff", ):
        super(DevSideBar, self).__init__(master=master, background=background)

    def add_action(self, text: str = "", icon: str = None, commnad=None,
                   default_bg: str = "#ffffff", default_fg: str = "#000000",
                   font=("等线 Light", 10, "bold"), side=tk.TOP,
                   active_bg: str = "#177aff", active_fg: str = "#d6eaff",
                   click_bg: str = "#175bff", click_fg: str = "#d6deff"):
        if icon is None:
            button_icon = None
        else:
            button_icon = tk.PhotoImage(file=icon)
        return DevButton(self, text=text, image=button_icon, command=commnad,
                         default_bg=default_bg, default_fg=default_fg, font=font,
                         active_bg=active_bg, active_fg=active_fg,
                         click_bg=click_bg, click_fg=click_fg).pack(side=side)

    def show(self, side: str = tk.LEFT):
        self.pack(side=side, fill=tk.Y)


class DevStatusBar(tk.Frame):
    def __init__(self, master: tk.Widget = None, default_text: str = "", sizegrip: bool = True, background="#fcfcfc",
                 foreground="#000000"):
        """
        简单的状态栏，使用show可以将它显示出来，使用add_status在鼠标指针移动到组件上时，状态栏会显示状态文本。

        :param master: 父组件
        :param default_text: 默认文字
        :param background: 背景颜色
        """
        super(DevStatusBar, self).__init__(master=master, background=background, )
        self.widgetlist = []
        self.master = master
        self.default_text = default_text
        self.style = ttk.Style()
        self.style.configure("Dev.TSizegrip", background=background, foreground=foreground)
        self.status = tk.Label(self, text=default_text, background=background, foreground=foreground)
        self.status.pack(side=tk.LEFT, expand=tk.NO)
        self.sizegrip = ttk.Sizegrip(self, style="Dev.TSizegrip")
        if sizegrip:
            self.sizegrip.pack(side=tk.RIGHT, anchor=tk.SE, expand=tk.NO)

    def add_status(self, widget: tk.Widget, status: str = ""):
        self.widgetlist.append(widget)
        widget.bind("<Enter>", lambda event: self.status.configure(text=status))
        widget.bind("<Leave>", lambda event: self.status.configure(text=self.default_text))

    def set_sizegrip(self, sizegrip: ttk.Sizegrip):
        self.sizegrip = sizegrip

    def show(self):
        self.pack(fill=tk.X, side=tk.BOTTOM)


class DevToast(tk.Toplevel):
    def __init__(self, master: tk.Tk = None,
                 title: str = "Title", message: str = "Message", height: int = 80):
        super(DevToast, self).__init__(master=master)
        self.overrideredirect(True)
        self.title = tk.Label(self, text=title, justify=tk.LEFT, anchor=tk.W)
        self.title.pack(side=tk.TOP, fill=tk.X)
        self.message = tk.Label(self, text=message, justify=tk.LEFT, anchor=tk.W)
        self.message.pack(side=tk.TOP, fill=tk.X)
        self.height = height
        self.withdraw()

    def show_toast(self):
        window_pos_bottom_right(self)
        self.deiconify()
        self.after(5000, self.withdraw)


class DevTabber(tk.Frame):
    def __init__(self, master: tk.Widget):
        super(DevTabber, self).__init__(master=master)
        self.actions = {}
        self.actions_button = {}

    def add_action(self, name: str, action: DevAction, use_ttk: bool = False) -> tk.Widget:
        self.actions[name] = action
        if use_ttk:
            self.actions_button[name] = ttk.Button(self, text=action.text, image=action.icon, command=action.command)
        else:
            self.actions_button[name] = tk.Button(self, text=action.text, image=action.icon,
                                                  background=action.background, foreground=action.foreground,
                                                  activebackground=action.active_background,
                                                  activeforeground=action.active_foreground,
                                                  command=action.command)
        return self.actions_button[name]

    def show(self):
        self.pack(fill=tk.X, side=tk.BOTTOM)

    def remove_action(self, name: str):
        self.actions_button[name].forget()

    def get_action(self, name: str):
        return self.actions[name]

    def get_action_button(self, name: str):
        return self.actions_button[name]


class DevWindow(tk.Tk):
    def __init__(self, title: str = ""):
        """
        快捷使用窗口，内置多种功能，快速使用
        """
        super(DevWindow, self).__init__()
        from sys import getwindowsversion
        self.title(title)
        self.geometry("630x300")
        self.iconbitmap(Icon_Empty)
        self.configure(background="#ffffff")

    def wm_screenshot(self, image="Image.png"):
        """
        截取窗口
        """
        window_screenshot(self, image)

    screenshot = wm_screenshot

    def wm_acrylic(self, mode: Literal["auto", "light", "dark"] = Auto,
                   mica: bool = False, acrylic: bool = False, hexColor: bool = False):
        """
        设置窗口材质为亚克力，

        :param mode: 为主题默认是自动
        """
        if mica:
            self.mica(mode)

        if mode == "auto":
            if darkdetect.isLight():
                window_acrylic(self, dark=False, acrylic=acrylic, hexColor=hexColor)
                self.configure(background="#eff4f9")
            if darkdetect.isDark():
                window_acrylic(self, dark=True, acrylic=acrylic, hexColor=hexColor)
                self.configure(background="#000000")
        elif mode == "light":
            window_acrylic(self, dark=False, acrylic=acrylic, hexColor=hexColor)
            self.configure(background="#eff4f9")
        elif mode == "dark":
            window_acrylic(self, dark=True, acrylic=acrylic, hexColor=hexColor)
            self.configure(background="#000000")
        self.update()

    acrylic = wm_acrylic

    def wm_mica(self, mode: Literal["auto", "light", "dark"] = Auto, all: bool = False):
        """
        设置窗口材质为云母

        :param mode: 为主题默认是自动
        :param all: 选择是否隐藏整个窗口。
        """
        import platform
        if platform.system() == "Windows":
            if all:
                self.configure(background=self.cget("background"))
                self.attributes("-transparent", self.cget("background"))
                self.update()
            if mode == "auto":
                if darkdetect.isLight():
                    window_mica_light(self)
                    self.configure(background="#d3d3d3")
                if darkdetect.isDark():
                    window_mica_dark(self)
                    self.configure(background="#000000")
            elif mode == "light":
                window_mica_light(self)
                self.configure(background="#d3d3d3")
            elif mode == "dark":
                window_mica_dark(self)
                self.configure(background="#000000")
        self.update()

    mica = wm_mica

    def wm_remove_titlebar(self):
        """
        移除标题栏与边框，保留着任务栏
        """
        self.after(0, lambda: window_custom_border_taskbar(self))

    remove_titlebar = wm_remove_titlebar

    def wm_remove_titlebar_none_border(self):
        """
        移除标题栏，无边框
        """
        window_custom_taskbar(self)

    remove_titlebar_none_border = wm_remove_titlebar_none_border

    def wm_run(self):
        """
        运行窗口，没什么作用
        """
        self.mainloop()

    run = wm_run

    def wm_statusbar(self, statusBar: tk.Widget = None):
        """
        设置状态栏，

        :param statusBar: 为被设置的状态栏
        """
        self._statusBar = statusBar
        self._statusBar.pack(fill=tk.X, side=tk.BOTTOM)
        return self._statusBar

    statusbar = wm_statusbar

    def wm_titlebar(self, titleBar: DevHeaderBar = None):
        """
        设置标题栏，

        :param titleBar: 为被设置的标题栏
        """
        self.minsize(100, 30)
        self._titlebar = titleBar
        self._titlebar.pack(fill=tk.X, side=tk.TOP)
        return self._titlebar

    titlebar = wm_titlebar

    def wm_menubar(self, menubar: DevMenuBar = None):
        menubar.show()

    menubar = wm_menubar

    def wm_centre(self):
        """
        居中窗口
        """
        self.after(1, lambda evt=None: window_centre(self))

    centre = wm_centre

    def min_window(self):
        """
        最小化窗口
        """
        self.state("iconic")

    def dpi(self):
        """
        设置dpi高清晰度
        """
        self.tk.call('tk', 'scaling', ScaleFactor / 75)


class DevToplevel(tk.Toplevel, DevWindow):
    def __init__(self, master: tk.Tk = None, title: str = ""):
        super(DevToplevel, self).__init__(master=master)
        self.title(title)
        self.geometry("630x300")
        self.iconbitmap(Icon_Empty)


class DevTooltip(DevToplevel):
    def __init__(self, widget: tk.Widget, window: tk.Tk, message: str = "", after: int = 1000, border: bool = True,
                 padding: int = 3, side=tk.CENTER, height: int = 40,
                 background="#ffffff", foreground="#000000"):

        """
        用于给组件设定工具提示

        :param widget: 表示设置工具提示的组件
        :param window: 表示设置组件的窗口
        :param message: 表示工具提示的文本
        :param after: 表示几秒之后显示
        :param border: 是否设定为窗口的边框
        """
        super(DevTooltip, self).__init__()
        self.configure(background=background, relief=tk.RAISED, border=1)
        from tkdev import window_border
        self._message = ttk.Label(self, background=background, foreground=foreground, text=message, anchor=tk.CENTER)
        self._message.pack(padx=padding, pady=padding, ipadx=padding, ipady=padding, fill=tk.BOTH, expand=tk.YES)
        if border:
            window_border(self)
        if not border:
            self.overrideredirect(True)
        self.withdraw()

        self.widget = widget
        self.window = window
        self._height = height
        self._afterms = after
        self.side = side
        self.padding = padding

        self.ison = False
        self.border = border

        self.widget.bind("<Enter>", lambda evt: self.show())
        self.widget.bind("<Leave>", lambda evt: self.hide())

        self.geometry(f"{self.widget.winfo_width()}x{self._height}")

    @property
    def after_ms(self):
        """
        等待的毫秒
        """
        return self._afterms

    @after_ms.setter
    def after_ms(self, ms: int = 1000):
        self._afterms = ms

    @property
    def message(self):
        """
        工具提示的消息
        """
        return self.message

    @message.setter
    def message(self, text: str):
        self._message.configure(text=text)

    def hide(self):
        """
        内置函数，用于隐藏窗口
        """
        self.ison = False
        self.window.deiconify()
        self.withdraw()

    def show(self):
        """
        内置函数，用于显示窗口
        """
        self.ison = True

        def on():
            self.geometry(f"{self.widget.winfo_width()}x{self._height}")
            if self.ison:
                if self.side == "center":
                    if self.border:
                        self.geometry(
                            f"+{self.widget.winfo_rootx() - 7}+{self.widget.winfo_rooty() + self.widget.winfo_height() + 5}")
                    else:
                        self.geometry(
                            f"+{self.widget.winfo_rootx()}+{self.widget.winfo_rooty() + self.widget.winfo_height() + 5}")
                self.deiconify()

        self.after(self._afterms, on)


if __name__ == '__main__':
    Window = DevWindow()
    Window.mainloop()
