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
相关文章
|
3月前
|
网络协议 API Windows
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
MASM32编程调用 API函数RtlIpv6AddressToString,windows 10 容易,Windows 7 折腾
|
3月前
|
Windows
[原创]用MASM32编程获取windows类型
[原创]用MASM32编程获取windows类型
|
3月前
|
JavaScript 前端开发 API
MASM32编程通过WMI获取Windows计划任务
MASM32编程通过WMI获取Windows计划任务
|
3月前
|
小程序 Windows
MASM32编写的程序在Windows 7,10下运行正常,但在Win XP下运行时只闻其声不见其形的故障
MASM32编写的程序在Windows 7,10下运行正常,但在Win XP下运行时只闻其声不见其形的故障
|
3月前
|
安全 Windows
电脑进入桌面后操作无响应?不妨试试禁用Windows Search服务
电脑进入桌面后操作无响应?不妨试试禁用Windows Search服务
|
4月前
|
编译器 开发工具 C语言
解锁QtCreator跨界神技!Windows下轻松驾驭OpenCV动态库,让你的跨平台开发如虎添翼,秒变视觉编程大师!
【8月更文挑战第4天】QtCreator是一款强大的跨平台IDE,便于创建多平台应用。本教程教你如何在Windows环境下集成OpenCV库至Qt项目。首先,下载匹配MinGW的OpenCV预编译版并解压。接着,在QtCreator中新建或打开项目,并在.pro文件中添加OpenCV的头文件和库文件路径。确保编译器设置正确。随后编写测试代码,例如加载和显示图片,并进行编译运行。完成这些步骤后,你就能在QtCreator中利用OpenCV进行图像处理开发了。
236 6
|
4月前
|
数据库 Windows
超详细步骤解析:从零开始,手把手教你使用 Visual Studio 打造你的第一个 Windows Forms 应用程序,菜鸟也能轻松上手的编程入门指南来了!
【8月更文挑战第31天】创建你的第一个Windows Forms (WinForms) 应用程序是一个激动人心的过程,尤其适合编程新手。本指南将带你逐步完成一个简单WinForms 应用的开发。首先,在Visual Studio 中创建一个“Windows Forms App (.NET)”项目,命名为“我的第一个WinForms 应用”。接着,在空白窗体中添加一个按钮和一个标签控件,并设置按钮文本为“点击我”。然后,为按钮添加点击事件处理程序`button1_Click`,实现点击按钮后更新标签文本为“你好,你刚刚点击了按钮!”。
295 0
|
4月前
|
缓存 Shell Windows
Windows 清理C盘空间,将桌面,文档等移D盘
Windows 清理C盘空间,将桌面,文档等移D盘
94 0
|
13天前
|
网络安全 Windows
Windows server 2012R2系统安装远程桌面服务后无法多用户同时登录是什么原因?
【11月更文挑战第15天】本文介绍了在Windows Server 2012 R2中遇到的多用户无法同时登录远程桌面的问题及其解决方法,包括许可模式限制、组策略配置问题、远程桌面服务配置错误以及网络和防火墙问题四个方面的原因分析及对应的解决方案。

相关课程

更多