MASM32编程获取Windows当前桌面主题名

简介: MASM32编程获取Windows当前桌面主题名

在网上没有找到现成的代码,只能DIY了。

 

 方法和步骤如下:

 

 1、检查注册表中HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Themes/LastTheme下DisplayName of Modified的值,若其值非空,则为当前主题名;若其值为空,则往下做2。

 

 2、若其值为空,则检查HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/ThemeManager下的ThemeActive项,若其值为字符串"0",则当前使用的是“windows经典”风格;若其值为字符串"1",则需要往下做3。

 

 3、有两种方法可以获得当前主题对应的文件:

 

 一种方法是继续访问注册表HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/Themes/LastTheme下的ThemeFile项的值,其值为当前使用的主题文件名(如:%SystemRoot%/resources/Themes/luna/luna.msstyles);

 若ThemeFile值为空, 则使用HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/ThemeManager下DllName项的值作为当前使用的主题文件名。

 另一种方法是使用uxtheme.dll中的API函数GetCurrentThemeName()来获取当前主题文件名。

 

 4、主题文件(如%SystemRoot%/resources/Themes/luna/luna.msstyles)对应的具体主题名称一般存放在同名的*.theme文件(如:%SystemRoot%/Resources/Themes/Luna.theme)中。

 *.theme文件结构与.INI文件类似,其

[Theme]节中的DisplayName项就是具体主题名称。

 

 如果DisplayName项的值为: “@themeui.dll,-2016”这样的格式,我们可以从HKEY_CURRENT_USER/Software/Microsoft/Windows/ShellNoRoam/MUICache获取该值对应的具体名称,如,"@themeui.dll,-2016"对应的值为"Windows 经典"。

 

 具体代码如下:

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; 文 件 名:SysTheme.asm
; 功   能:显示当前系统主题名
; 作   者:PurpleEndurer,2009-10-29,第1版
; 开发环境:Win XP PRO SP3 + MASM32 v8;
; 源代码和EXE下载地址:; 1、​
; 2、​​http://purpleendurer.ys168.com/​​
;

; log
; -----------------------------------------
; 2009-10-29 修改 GetSysThemeName1() & GetSysThemeName2()
; 2009-09-27 创建!
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.386
.model flat, stdcall
option casemap:none; 2、​​http://purpleendurer.ys168.com/​​
;
include /masm32/include/windows.inc
include /masm32/include/kernel32.inc
includelib /masm32/lib/kernel32.libinclude /masm32/include/user32.inc
includelib /masm32/lib/user32.libinclude /masm32/include/advapi32.inc
includelib /masm32/lib/advapi32.lib
GetSysThemeName1                    proto :LPSTR
GetSysThemeName2                    proto :LPSTR, :DWORD
TranMsstylesFile2ThemeFileSpec  proto :LPSTR
ExpandEnvironmentFileSpec         proto :LPSTR
GetThemeDispName                     proto :LPSTR
TranDllNum2Name                       proto :LPSTR
IsWinClassStyle                            proto :LPSTR
IsModifiedTheme                          proto :LPSTR
IsUnknownTheme                         proto 
; sssssssssssssssssssssssssssssssssssssssssssss
.data
; sssssssssssssssssssssssssssssssssssssssssssss
g_szAppName db "当前主题",0
g_szWinClassStyle db "windows 经典", 0
;g_szWinXP db "Windows XP", 0

g_szRegThemeManager_Path db "Software/Microsoft/Windows/CurrentVersion/ThemeManager", 0

g_szFailOpenRegKey db "未能打开注册键!", 0
g_szThemeActive db "ThemeActive", 0
g_szREG_SZ db "REG_SZ", 0
g_szREG_EXPAND_SZ db "REG_EXPAND_SZ", 0
;g_szFailGetThemeActiveValue db "未能获取ThemeActive值", 0
g_szDllName db "DllName", 0

g_szRegLastTheme_Path db "Software/Microsoft/Windows/CurrentVersion/Themes/Last"
g_szTheme db "Theme", 0

g_szThemeFile db "ThemeFile", 0
g_szFailGetThemeFileValue db "未能获取ThemeFile值", 0
g_szUnknown db "未知", 0
g_szDisplayName_of_Modified db "DisplayName of Modified", 0

g_szFailLoadUxtheme_dll db "未能装载"
g_szUxtheme_dll db "uxtheme.dll", 0

g_szFailGetCurrentThemeNameAdress db "获取地址失败:"
g_szGetCurrentThemeName db "GetCurrentThemeName", 0

g_szFailRunGetCurrentThemeName db "运行GetCurrentThemeName失败", 0

g_szDot_theme db ".theme", 0
g_szFailTranToThemeFile db "未能转换为theme文件", 0
g_szMUICache_Path db "Software/Microsoft/Windows/ShellNoRoam/MUICache", 0

g_szDisplayName db "DisplayName", 0
g_szQuestion db "?", 0
g_szSysThemeName db 
; sssssssssssssssssssssssssssssssssssssssssssss
.code
; sssssssssssssssssssssssssssssssssssssssssssss
start:
    mov dword ptr g_szSysThemeName, NULL
    invoke GetSysThemeName1, addr g_szSysThemeName
    invoke MessageBox, NULL, addr g_szSysThemeName, addr g_szAppName, MB_OK

    mov dword ptr g_szSysThemeName, NULL
    invoke GetSysThemeName2, addr g_szSysThemeName, sizeof g_szSysThemeName
    invoke MessageBox, NULL, addr g_szSysThemeName, addr g_szAppName, MB_OK
    invoke 

; ///
;获取当前系统主题名
; ///
GetSysThemeName1 proc lpszSysThemeName: LPSTR
    local bModified[MAX_PATH]: byte
    local hKey1: HKEY
    local bDllNameValue[MAX_PATH]: byte
    local dwDllNameValueLen: dword
    local bThemeFileValue[MAX_PATH]: byte
    local dwThemeFileValueLen: dword
;invoke IsWinClassStyle, lpszSysThemeName
    ;mov eax, lpszSysThemeName
    ;cmp dword ptr [eax], NULL
    ;jne @GetSysThemeName1Ret

    invoke IsModifiedTheme, lpszSysThemeName
    test eax, eax
    jz @GetSysThemeName1Ret

    invoke lstrcpy, addr bModified, lpszSysThemeName

    mov hKey1, 0

    ;--- 打开注册表值DllName所在键ThemeManager
    invoke RegOpenKey, HKEY_CURRENT_USER, addr g_szRegThemeManager_Path, addr hKey1
    .IF eax == ERROR_SUCCESS
        ;--- 取“DllName”值备用
        mov dwDllNameValueLen, sizeof bDllNameValue
        invoke RegQueryValueEx, hKey1, addr g_szDllName, NULL, addr g_szREG_EXPAND_SZ/
            , addr bDllNameValue, addr dwDllNameValueLen

        .if eax != ERROR_SUCCESS
            mov byte ptr bDllNameValue, NULL
        .endif

        invoke RegCloseKey, hKey1

        ;--- 打开注册表值“ThemeFile”所在键LastTheme
        invoke RegOpenKey, HKEY_CURRENT_USER, addr g_szRegLastTheme_Path, addr hKey1
        .if eax != ERROR_SUCCESS
            invoke lstrcpy, lpszSysThemeName, addr g_szFailOpenRegKey
        .else
            ;--- 取“ThemeFile”值
            mov dwThemeFileValueLen, sizeof bThemeFileValue
            invoke RegQueryValueEx, hKey1, addr g_szThemeFile, NULL, addr g_szREG_EXPAND_SZ/
                , addr bThemeFileValue, addr dwThemeFileValueLen
            .IF eax != ERROR_SUCCESS
                invoke lstrcpy, lpszSysThemeName, addr g_szFailGetThemeFileValue
            .ELSE
                invoke lstrcpy, lpszSysThemeName, addr bThemeFileValue

                ;--- “ThemeFile”值为空吗?
                    ;invoke lstrlen, lpszSysThemeName
                    ;test eax, eax
                    ;.if ZERO?  
                mov eax, lpszSysThemeName
                .if byte ptr [eax] == NULL
                    ;--- 若ThemeFile值为空, 则使用DllName值
                    .IF byte ptr bDllNameValue != NULL
                        invoke lstrcpy, lpszSysThemeName, addr bDllNameValue
                        invoke ExpandEnvironmentFileSpec, lpszSysThemeName
                        invoke TranMsstylesFile2ThemeFileSpec, lpszSysThemeName
                        test eax, eax
                        jz @F
                    .ENDIF
                .else       ;否则获取主题文件中DisplayName值
@@:
                    invoke GetThemeDispName, lpszSysThemeName
                .endif
                invoke lstrcat, lpszSysThemeName, addr bModified
            .ENDIF
        .endif
    .ENDIF

    .if (hKey1 != 0)
        invoke RegCloseKey, hKey1
    .endif

    invoke IsUnknownTheme, lpszSysThemeName

@GetSysThemeName1Ret:
    ret
GetSysThemeName1 endp


GetCurrentThemeName typedef proto :LPWSTR, :DWORD, :LPWSTR, :DWORD, :LPWSTR, :DWORD
_GetCurrentThemeName typedef ptr GetCurrentThemeName
GetSysThemeName2 proc lpszSysThemeName: LPSTR, dwSysThemeNameLen: DWORD
    local bModified[MAX_PATH]: byte
    local bThemeFile[MAX_PATH*2]: byte
    local lpfnGetCurrentThemeName: _GetCurrentThemeName

    invoke IsWinClassStyle, lpszSysThemeName
    mov eax, lpszSysThemeName
    cmp dword ptr [eax], NULL
    jne @GetSysThemeName2Ret

    invoke IsModifiedTheme, lpszSysThemeName
    test eax, eax
    jz @GetSysThemeName2Ret

    invoke lstrcpy, addr bModified, lpszSysThemeName

    invoke LoadLibrary, addr g_szUxtheme_dll
    .IF eax==NULL
        invoke lstrcpy, lpszSysThemeName, addr g_szFailLoadUxtheme_dll
    .ELSE
        push eax    ;push for FreeLibrary

        invoke GetProcAddress, eax, addr g_szGetCurrentThemeName
        .if eax==NULL
            invoke lstrcpy, lpszSysThemeName, addr g_szFailGetCurrentThemeNameAdress
        .else
            mov lpfnGetCurrentThemeName, eax

; HRESULT GetCurrentThemeName(
 ;     LPWSTR pszThemeFileName,//[out] Pointer to a string that receives the theme path and file name.
 ;     int dwMaxNameChars,     //[in] Value of typeintthat contains the maximum number of characters allowed in the theme file name.
 ;     LPWSTR pszColorBuff,    //[out] Pointer to a string that receives the color scheme name. This parameter may be set to NULL.
 ;     int cchMaxColorChars,   //[in] Value of typeintthat contains the maximum number of characters allowed in the color scheme name.
 ;     LPWSTR pszSizeBuff,     //[out] Pointer to a string that receives the size name. This parameter may be set to NULL.
 ;     int cchMaxSizeChars     //[in] Value of typeintthat contains the maximum number of characters allowed in the size name.
 ; );
 ; Retrieves the name of the current visual style, and optionally retrieves the color scheme name and size name.
 ; The result maybe read from HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/ThemeManager/ThemeActive,DllName
 ; eg.C:/WINDOWS/Resources/Themes/Luna/luna.msstyles,  
 ;
 ; Returns S_OK if successful, otherwise an error code.

           invoke lpfnGetCurrentThemeName, addr bThemeFile, (sizeof bThemeFile)/2, NULL, NULL, NULL, NULL
            .IF eax != S_OK
                invoke lstrcpy, lpszSysThemeName, addr g_szFailRunGetCurrentThemeName
                ;invoke lstrcpy, lpszSysThemeName, addr g_szWinClassStyle    ;当前主题为"Windows 经典"
            .ELSE
                ;invoke MessageBox, NULL, addr bThemeFile, addr g_szAppName, MB_OK
                invoke WideCharToMultiByte, CP_ACP, WC_COMPOSITECHECK, addr bThemeFile, -1/
                    ,lpszSysThemeName, dwSysThemeNameLen, NULL, NULL

                ;invoke MessageBox, NULL, lpszSysThemeName, addr g_szAppName, MB_OK

                invoke TranMsstylesFile2ThemeFileSpec,  lpszSysThemeName
                test eax, eax
                .if ZERO?
                    invoke GetThemeDispName, lpszSysThemeName
                .endif
            .ENDIF
            invoke lstrcat, lpszSysThemeName, addr bModified
        .endif

        call FreeLibrary
    .ENDIF

    invoke IsUnknownTheme, lpszSysThemeName

@GetSysThemeName2Ret:
    ret
GetSysThemeName2 endp
 
 


IsWinClassStyle proc lpszSysThemeName: LPSTR
    local hKey1: HKEY
    local bThemeActiveValue[2]: byte
    local dwThemeActiveValueLen: dword

    mov eax, lpszSysThemeName
    mov dword ptr [eax], NULL

    ;--- 打开注册表值ThemeActive所在键ThemeManager
    invoke RegOpenKey, HKEY_CURRENT_USER, addr g_szRegThemeManager_Path, addr hKey1
    .IF eax == ERROR_SUCCESS
        ;--- 取ThemeActive值
        mov dwThemeActiveValueLen, sizeof bThemeActiveValue
        invoke RegQueryValueEx, hKey1, addr g_szThemeActive, NULL, addr g_szREG_SZ/
                , addr bThemeActiveValue, addr dwThemeActiveValueLen
   
        .if eax == ERROR_SUCCESS && (byte ptr bThemeActiveValue=='0')   ;值为'0',当前主题为"Windows 经典"
            invoke lstrcpy, lpszSysThemeName, addr g_szWinClassStyle
        .endif

        invoke RegCloseKey, hKey1
    .ENDIF
        
    ret
IsWinClassStyle endp

;/
; 取 "@xxx.dll,-nnn" 的对应值
; 如. "@themeui.dll,-2016"="Windows 经典"
;/
TranDllNum2Name proc lpszDllNum: LPSTR
    local hKey1: HKEY
    local bValue[MAX_PATH]: byte
    local dwValueLen: dword

    ;--- 打开注册表键MUICache
    invoke RegOpenKey, HKEY_CURRENT_USER, addr g_szMUICache_Path, addr hKey1
    .IF eax == ERROR_SUCCESS
        ;--- 取lpszDllNum对应值
        mov dwValueLen, sizeof bValue
        invoke RegQueryValueEx, hKey1, lpszDllNum, NULL, addr g_szREG_SZ/
                , addr bValue, addr dwValueLen
   
        .if eax == ERROR_SUCCESS
            invoke lstrcpy, lpszDllNum, addr bValue
        .endif
        invoke RegCloseKey, hKey1
;    .ELSE
;        invoke lstrcpy, lpszDllNum, addr g_szFailOpenRegKey
    .ENDIF

    ret
TranDllNum2Name endp 
 


; //
;将文件说明符中包含环境变量转化具体值
; 如将:%SystemRoot%/resources/Themes/Aquanox/Aquanox.msstyles
; 转为:c:/windows/resources/Themes/Aquanox/Aquanox.msstyles
; //

ExpandEnvironmentFileSpec proc lpszFileSpec: LPSTR
    local bFileSpec[MAX_PATH]: byte

    invoke ExpandEnvironmentStrings, lpszFileSpec, addr bFileSpec, sizeof bFileSpec
    invoke lstrcpy, lpszFileSpec, addr bFileSpec

    ret
ExpandEnvironmentFileSpec endp
 
 

; ///
;获取指定主题文件中的DisplayName值
; 如C:/WINDOWS/Resources/Themes/Aquanox.theme中
;[Theme]
;DisplayName=经典-深色Aquanox风格
; ///
GetThemeDispName proc lpszThemeFileSpec: LPSTR
    local bDispNameValue[MAX_PATH]: byte

    invoke ExpandEnvironmentFileSpec, lpszThemeFileSpec

    invoke GetPrivateProfileString, ADDR g_szTheme, ADDR g_szDisplayName/
        , ADDR g_szQuestion, ADDR bDispNameValue, SIZEOF bDispNameValue, lpszThemeFileSpec

    .if byte ptr bDispNameValue != '?'
        invoke lstrcpy, lpszThemeFileSpec, ADDR bDispNameValue        
        .IF byte ptr bDispNameValue == "@"
            invoke TranDllNum2Name, lpszThemeFileSpec
        .ENDIF
    .endif

    ret
GetThemeDispName endp
 
 


;///
; 生成.msstyles 文件对应的.theme文件
; 如     C:/WINDOWS/Resources/Themes/luna/luna.msstyles
; 对应: C:/WINDOWS/Resources/Themes/Luna.theme
; 输入: lpszFileSpec - 指向存储.msstyles文件说明符字符串
; 输出: 
;  若成功, eax= 0, lpszFileSpec 指向存储对应的.theme文件的文件说明符字符串
;  否则 eax=1, lpszFileSpec 指向存储出错信息的字符串
;///

TranMsstylesFile2ThemeFileSpec proc lpszFileSpec: LPSTR
    invoke lstrlen, lpszFileSpec

    ;--- 从串末向前定位最后一个'/'字符
    mov edi, lpszFileSpec
    add edi, eax
    .repeat
        dec edi
        mov al, byte ptr [edi]
    .until (edi==lpszFileSpec || al=='/')

    .IF (edi==lpszFileSpec)
        invoke lstrcpy, lpszFileSpec, addr g_szFailTranToThemeFile
        xor eax, eax
        inc eax
    .ELSE
        mov byte ptr [edi], 0
        invoke lstrcat, lpszFileSpec, addr g_szDot_theme
        xor eax, eax
    .ENDIF

    ret
TranMsstylesFile2ThemeFileSpec endp
 
 


;/
;取注册表HKEY_CURRENT_USER/Software/Microsoft/Windows/CurrentVersion/LastTheme
;中的“DisplayName of Modified”项值
;/
IsModifiedTheme proc lpszThemeName: LPSTR
    local hKey1: HKEY
    local bDispNameModifiedValue[30]: byte
    local dwDispNameModifiedValueLen: dword

    ;--- 打开注册表值“DisplayName of Modified”所在键LastTheme
    invoke RegOpenKey, HKEY_CURRENT_USER, addr g_szRegLastTheme_Path, addr hKey1
    .if eax == ERROR_SUCCESS
        ;--- 读取“DisplayName of Modified”值
        mov dwDispNameModifiedValueLen, sizeof bDispNameModifiedValue

        invoke RegQueryValueEx, hKey1, addr g_szDisplayName_of_Modified, NULL, addr g_szREG_SZ/
                , addr bDispNameModifiedValue, addr dwDispNameModifiedValueLen

        .IF eax == ERROR_SUCCESS
            invoke lstrcpy, lpszThemeName, addr bDispNameModifiedValue
        .ENDIF
        invoke RegCloseKey, hKey1
    .else
        
    .endif

    xor eax, eax

    ;值是否为空或为“更改的主题”。"更"的机内码为0B8FCh
    .if byte ptr bDispNameModifiedValue == NULL || word ptr bDispNameModifiedValue == 0FCB8h
        inc eax
    .endif
    ret

IsModifiedTheme endp
 
 


IsUnknownTheme proc lpszThemeName: LPSTR
    invoke lstrlen, lpszThemeName
    test eax, eax
    .if ZERO?
        invoke lstrcpy, lpszThemeName, addr g_szUnknown
    .endif

    ret
IsUnknownTheme endp

end
相关文章
|
10天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
6天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2506 14
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
6天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1519 14
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
8天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
531 13
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19282 30
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18836 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17524 13
Apache Paimon V0.9最新进展
|
8天前
|
人工智能 自动驾驶 机器人
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
过去22个月,AI发展速度超过任何历史时期,但我们依然还处于AGI变革的早期。生成式AI最大的想象力,绝不是在手机屏幕上做一两个新的超级app,而是接管数字世界,改变物理世界。
458 48
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
|
1天前
|
云安全 存储 运维
叮咚!您有一份六大必做安全操作清单,请查收
云安全态势管理(CSPM)开启免费试用
354 4
叮咚!您有一份六大必做安全操作清单,请查收
|
2天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。