You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python从.msstyle文件中提取窗口控制按钮图标?

用Python提取.msstyle文件中的窗口控制按钮图标

可以实现,核心思路是借助Python调用Windows原生主题API,读取.msstyle文件中的主题资源,提取对应控制按钮的图标。以下是具体实现方案:

依赖准备

需要安装两个Python库:

  • pywin32:用于调用Windows API,模拟C++中LoadLibraryEx、OpenThemeData等操作
  • pillow:用于处理位图并保存为图片文件

执行安装命令:

pip install pywin32 pillow

实现步骤与代码

.msstyle本质是包含主题资源的PE文件,我们需要加载文件后,通过主题API定位到DWMWindow类下的控制按钮元素,绘制并导出图标:

import win32api
import win32gui
import win32con
from PIL import Image
import win32ui

# 主题元素常量(对应Windows uxtheme.h头文件定义)
DWM_WINDOW_CLASS = "DWMWindow"
# 控制按钮的Part ID
TP_MINBUTTON = 1    # 最小化按钮
TP_MAXBUTTON = 2    # 最大化/还原按钮(二者共用同一Part ID,通过状态区分)
TP_CLOSEBUTTON = 3  # 关闭按钮
# 按钮状态ID
TS_NORMAL = 1       # 正常状态
TS_HOT = 2          # 鼠标悬停状态
TS_PRESSED = 3      # 按下状态
TS_DISABLED = 4     # 禁用状态

def extract_button_icon(msstyle_path, part_id, state_id, output_path):
    # 加载.msstyle文件作为数据资源
    lib_handle = win32api.LoadLibraryEx(msstyle_path, 0, win32con.LOAD_LIBRARY_AS_DATAFILE)
    try:
        # 打开主题上下文(传入0作为窗口句柄即可,无需真实窗口)
        theme_handle = win32gui.OpenThemeData(0, DWM_WINDOW_CLASS)
        if not theme_handle:
            print(f"无法打开主题文件:{msstyle_path}")
            return
        
        # 获取按钮元素的尺寸
        width, height = win32gui.GetThemePartSize(theme_handle, None, part_id, state_id, None, win32con.TS_TRUE)
        
        # 创建绘图上下文
        dc = win32ui.CreateDCFromHandle(win32gui.GetDC(0))
        mem_dc = dc.CreateCompatibleDC()
        
        # 创建空位图
        bitmap = win32ui.CreateBitmap()
        bitmap.CreateCompatibleBitmap(dc, width, height)
        old_bitmap = mem_dc.SelectObject(bitmap)
        
        # 绘制主题按钮到位图
        win32gui.DrawThemeBackground(theme_handle, mem_dc.GetSafeHdc(), part_id, state_id, (0, 0, width, height), None)
        
        # 转换位图为PIL图片并保存
        bmp_info = bitmap.GetInfo()
        bmp_data = bitmap.GetBitmapBits(True)
        image = Image.frombuffer('RGB', (bmp_info['bmWidth'], bmp_info['bmHeight']), bmp_data, 'raw', 'BGRX', 0, 1)
        image.save(output_path)
        
        # 清理资源
        mem_dc.SelectObject(old_bitmap)
        bitmap.DeleteObject()
        mem_dc.DeleteDC()
        dc.DeleteDC()
        win32gui.ReleaseDC(0, dc.GetSafeHdc())
        win32gui.CloseThemeData(theme_handle)
    finally:
        # 释放加载的库资源
        win32api.FreeLibrary(lib_handle)

# 示例调用
if __name__ == "__main__":
    # 替换为目标.msstyle文件路径,也可通过注册表ThemeManager下的DllName获取当前系统主题路径
    target_msstyle = r"C:\Windows\Resources\Themes\aero\aero.msstyles"
    
    # 提取各类按钮的不同状态图标
    extract_button_icon(target_msstyle, TP_MINBUTTON, TS_NORMAL, "min_normal.png")
    extract_button_icon(target_msstyle, TP_MAXBUTTON, TS_NORMAL, "max_normal.png")
    extract_button_icon(target_msstyle, TP_MAXBUTTON, TS_PRESSED, "restore_pressed.png")
    extract_button_icon(target_msstyle, TP_CLOSEBUTTON, TS_HOT, "close_hot.png")

注意事项

  • 还原按钮和最大化按钮共用同一个Part ID(TP_MAXBUTTON),通过不同状态区分显示
  • 主题元素的Part ID和状态ID可参考Windows官方文档或uxtheme.h头文件定义
  • 若读取系统默认主题文件,需确保程序有足够的读取权限
  • 不同版本Windows的主题资源结构可能略有差异,需根据实际情况调整常量值

内容的提问来源于stack exchange,提问作者OKwy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 10:22:43