如何用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
相关产品推荐
相关产品推荐

