在网上没有找到现成的代码,只能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