在网上没有找到现成的代码,只能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、http://download.csdn.net/source/1780209; 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.lib
include /masm32/include/user32.inc
includelib /masm32/lib/user32.lib
include /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 :LPSTR
; 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 MAX_PATH dup(?)
; 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 ExitProcess,NULL
; ///////////////////////////////////////////////////
;获取当前系统主题名
; ///////////////////////////////////////////////////
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 start