Hide Window – DarkCorners

Date: 17/12/2025

Category: Python

  • Phần mềm hỗ trợ ẩn cửa sổ hàng loạt.
  • Hỗ trợ nhiều ứng dụng, cửa sổ khác nhau.
  1. Khởi động phần mềm.
  2. Chọn những cửa sổ cần ẩn đi được liệt kê ở bên trái.
  3. Nhấn nút [>>].
  4. Danh sách cửa sổ đã ẩn sẽ được hiển ở cột bên phải.
  5. Nếu muốn bỏ ẩn. Chỉ cần chọn ở cột bên phải. Sau đó nhấn [<<].
import sys
import ctypes
from ctypes import wintypes
import tkinter as tk
from tkinter import ttk, messagebox

APP_TITLE = "Hide Window - DarkCorners"
WIDTH, HEIGHT = 800, 400

# --- Elegant bright color palette ---
BG = "#f8fafc"          # Light background
CARD = "#ffffff"        # White panels
FG = "#1a1a1a"          # Text color
ACCENT = "#4a90e2"      # Accent blue
TITLE_COLOR = "#ff4d4d" # Red title
BTN_BG = "#e8eaf6"      # Button background
BTN_HOVER = "#d6e4ff"   # Button hover
BORDER = "#d0d7de"       # Border color
SHADOW = "#cfd8dc"      # Soft shadow

IS_WINDOWS = sys.platform.startswith("win")

# --- Windows helper functions ---
if IS_WINDOWS:
    user32 = ctypes.windll.user32
    kernel32 = ctypes.windll.kernel32
    EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, wintypes.HWND, wintypes.LPARAM)
    SW_HIDE = 0
    SW_SHOW = 5

    def enum_windows_ctypes():
        windows = []
        @EnumWindowsProc
        def _enum(hwnd, lParam):
            if user32.IsWindowVisible(hwnd):
                length = user32.GetWindowTextLengthW(hwnd)
                if length > 0:
                    buff = ctypes.create_unicode_buffer(length + 1)
                    user32.GetWindowTextW(hwnd, buff, length + 1)
                    title = buff.value
                    windows.append((hwnd, title))
            return True
        user32.EnumWindows(_enum, 0)
        return windows

    def hide_window(hwnd):
        try:
            user32.ShowWindow(hwnd, SW_HIDE)
            return True
        except Exception:
            return False

    def show_window(hwnd):
        try:
            user32.ShowWindow(hwnd, SW_SHOW)
            return True
        except Exception:
            return False
else:
    def enum_windows_ctypes():
        return []

    def hide_window(hwnd):
        return False

    def show_window(hwnd):
        return False

# --- Tkinter GUI ---
def center_window(root, width=800, height=400):
    # Lấy kích thước màn hình
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    # Tính vị trí bắt đầu trục ngang và trục đứng
    aaaxxx = (screen_width // 2) - (width // 2)
    bbbyyy = (screen_height // 2) - (height // 2) - (40)
    # Đặt geometry
    root.geometry(f"{width}x{height}+{aaaxxx}+{bbbyyy}")

class HideWindowApp(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title(APP_TITLE)
        center_window(self, 800, 400)
        self.resizable(False, False)
        self.configure(bg=BG)

        self.open_map = {}
        self.hidden_map = {}

        self._build_ui()
        self.refresh_window_lists()

    def _build_ui(self):
        lbl = tk.Label(self, text=APP_TITLE, font=("Segoe UI", 20, "bold"), bg=BG, fg=TITLE_COLOR)
        lbl.pack(fill=tk.X, pady=(10, 6))

        container = tk.Frame(self, bg=BG)
        container.pack(fill=tk.BOTH, expand=True, padx=12, pady=6)

        left_w = int(WIDTH * 0.40) - 24
        mid_w = int(WIDTH * 0.20) - 24
        right_w = left_w

        style = ttk.Style()
        style.configure("TLabelframe", background=CARD, foreground=FG, borderwidth=2, relief="flat")
        style.configure("TLabelframe.Label", background=CARD, foreground=ACCENT, font=("Segoe UI", 10, "bold"))

        # Shadowed frames
        lf_shadow_left = tk.Frame(container, bg=SHADOW)
        lf_shadow_left.place(x=2, y=2, width=left_w, height=HEIGHT - 96)

        lf_left = ttk.LabelFrame(container, text="Danh Sách Cửa Sổ", style="TLabelframe")
        lf_left.place(x=0, y=0, width=left_w - 4, height=HEIGHT - 100)

        self.lb_open = tk.Listbox(lf_left, selectmode=tk.EXTENDED, activestyle='none')
        self.lb_open.pack(fill=tk.BOTH, expand=True, padx=8, pady=8)
        self._style_listbox(self.lb_open)

        lf_shadow_right = tk.Frame(container, bg=SHADOW)
        lf_shadow_right.place(x=left_w + mid_w + 26, y=2, width=right_w, height=HEIGHT - 96)

        lf_right = ttk.LabelFrame(container, text="Cửa Sổ Đã Ẩn", style="TLabelframe")
        lf_right.place(x=left_w + mid_w + 24, y=0, width=right_w - 4, height=HEIGHT - 100)

        self.lb_hidden = tk.Listbox(lf_right, selectmode=tk.EXTENDED, activestyle='none')
        self.lb_hidden.pack(fill=tk.BOTH, expand=True, padx=8, pady=8)
        self._style_listbox(self.lb_hidden)

        mid_frame = tk.Frame(container, bg=BG)
        mid_frame.place(x=left_w + 8, y=30, width=mid_w, height=300)

        def styled_button(parent, text, command):
            b = tk.Button(parent, text=text, command=command, width=12, font=("Segoe UI", 11, "bold"),
                          bg=BTN_BG, fg=FG, activebackground=BTN_HOVER, activeforeground=ACCENT,
                          relief="flat", bd=1, highlightbackground=BORDER)
            b.config(borderwidth=0, highlightthickness=0)
            b.bind("", lambda e: b.config(bg=BTN_HOVER))
            b.bind("", lambda e: b.config(bg=BTN_BG))

            # Rounded corners simulation
            b.configure(highlightbackground=BTN_BG)
            return b

        btn_to_hidden = styled_button(mid_frame, ">>", self.hide_selected)
        btn_to_hidden.pack(pady=(10, 10))

        btn_to_open = styled_button(mid_frame, "<<", self.show_selected)
        btn_to_open.pack(pady=(6, 10))

        btn_refresh = styled_button(mid_frame, "Refresh Lists", self.refresh_window_lists)
        btn_refresh.pack(pady=(10, 10))

        btn_restore_all = styled_button(mid_frame, "Restore All", self.restore_all)
        btn_restore_all.pack(pady=(10, 10))

        btn_exit = styled_button(mid_frame, "Exit", self.quit)
        btn_exit.pack(pady=(10, 10))

        bottom = tk.Frame(self, bg=BG)
        bottom.pack(fill=tk.X, side=tk.BOTTOM, padx=12, pady=4)

        self.status_var = tk.StringVar(value="Ready")
        lbl_status = tk.Label(bottom, textvariable=self.status_var, bg=BG, fg=FG)
        lbl_status.pack(side=tk.LEFT, padx=12)

    def _style_listbox(self, lb: tk.Listbox):
        lb.configure(bg=CARD, fg=FG, bd=1, selectbackground=ACCENT, selectforeground='white', highlightthickness=1, highlightcolor=BORDER)

    def refresh_window_lists(self):
        if not IS_WINDOWS:
            messagebox.showwarning("Unsupported OS", "This tool currently works only on Windows.")
            return

        self.open_map.clear()
        self.hidden_map.clear()
        self.lb_open.delete(0, tk.END)
        self.lb_hidden.delete(0, tk.END)

        try:
            wins = enum_windows_ctypes()
        except Exception as e:
            messagebox.showerror("Error", f"Failed to enumerate windows: {e}")
            return

        for hwnd, title in wins:
            entry = f"{title}  —  (hwnd: {hwnd})"
            self.open_map[entry] = hwnd
            self.lb_open.insert(tk.END, entry)

        self.status_var.set(f"Found {len(wins)} windows")

    def hide_selected(self):
        sel = list(self.lb_open.curselection())
        if not sel:
            return
        entries = [self.lb_open.get(i) for i in sel]
        moved = 0
        for entry in entries:
            hwnd = self.open_map.get(entry)
            if hwnd and hide_window(hwnd):
                self.lb_hidden.insert(tk.END, entry)
                self.hidden_map[entry] = hwnd
                moved += 1
        for i in sorted(sel, reverse=True):
            entry = self.lb_open.get(i)
            self.lb_open.delete(i)
            self.open_map.pop(entry, None)
        self.status_var.set(f"Hidden {moved} window(s)")

    def show_selected(self):
        sel = list(self.lb_hidden.curselection())
        if not sel:
            return
        entries = [self.lb_hidden.get(i) for i in sel]
        moved = 0
        for entry in entries:
            hwnd = self.hidden_map.get(entry)
            if hwnd and show_window(hwnd):
                self.lb_open.insert(tk.END, entry)
                self.open_map[entry] = hwnd
                moved += 1
        for i in sorted(sel, reverse=True):
            entry = self.lb_hidden.get(i)
            self.lb_hidden.delete(i)
            self.hidden_map.pop(entry, None)
        self.status_var.set(f"Restored {moved} window(s)")

    def restore_all(self):
        entries = [self.lb_hidden.get(i) for i in range(self.lb_hidden.size())]
        count = 0
        for entry in entries:
            hwnd = self.hidden_map.get(entry)
            if hwnd and show_window(hwnd):
                count += 1
                self.lb_open.insert(tk.END, entry)
                self.open_map[entry] = hwnd
        self.lb_hidden.delete(0, tk.END)
        self.hidden_map.clear()
        self.status_var.set(f"Restored {count} window(s)")

if __name__ == '__main__':
    app = HideWindowApp()
    app.mainloop()
pyinstaller --noconsole --onefile --windowed --add-data "6-HideWindow-icon.ico;." --icon=6-HideWindow-icon.ico 6-HideWindow-Source.py

Để lại một bình luận