In C# or else VB.Net, knowing the ubication of a visual theme .theme file, I would like to apply that visual theme in Windows, without depending on other applications such as RunDll32.exe, just P/Invoking, but avoiding weird/strange things such as opening the personalization window and then using FindWindow
function to close it, the procedure should be automated from platform invoking not interacting with other windows.
This question about how to apply a theme was asked before in S.O by many people (Included by me, with a solution via registry modification plus service stoping/resuming that only works under Windows 7), I think its time for an expert to illustrate us with a WinAPI approach that does not involve RunDll32.exe neither opening the personalization window.
I wonder this could be done by setting some values on the registry key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\ThemeManager
and then posting/sending a message via SendMessage
or PostMessage
or other function, or maybe notifying about an environment change via SendMessageTimeOut
function or SHChangeNotify
or SystemParametersInfo
or another function, because in the uxtheme.dll
library seems there is nothing usefull for this task, the question is what function and with what parameters to apply a visual theme change, there are some commercial applications that can do this, which are the steps to do it then?, I tried all those functions without success.
This is the solution I did for Windows 7 in the past, I remember that is not perfect because for some themes the colors were not applied properlly and only has beeen solved with an user session re-logon to affect changes properlly after modifications:
Private Sub SetAeroTheme(ByVal themeFile As String,
Optional ByVal colorName As String = "NormalColor",
Optional ByVal sizeName As String = "NormalSize")
Dim regKeyPath As String = "Software\Microsoft\Windows\CurrentVersion\ThemeManager"
Using themeService As New ServiceController("Themes")
If themeService.Status = ServiceControllerStatus.Running Then
themeService.Stop()
themeService.WaitForStatus(ServiceControllerStatus.Stopped)
End If
Using regKey As RegistryKey = Registry.CurrentUser.OpenSubKey(regKeyPath, writable:=True)
regKey.SetValue("LoadedBefore", "0", RegistryValueKind.String)
regKey.SetValue("DllName", themeFile, RegistryValueKind.String)
regKey.SetValue("ColorName", colorName, RegistryValueKind.String)
regKey.SetValue("SizeName", sizeName, RegistryValueKind.String)
End Using
If themeService.Status = ServiceControllerStatus.Stopped Then
themeService.Start()
themeService.WaitForStatus(ServiceControllerStatus.Running)
End If
End Using
End Sub
In windows 8 I think because DWM composition changes just that code didn't worked anymore.
There is an undocumented function named "SetSystemVisualStyle" described on pinvoke.net that allows you to change the current "msstyles" file. As this function is undocumented it comes with the caveat: "use at your own risk".
The following function signatures are from the site referenced above.
C# signature
usage:
VB.Net signature
The OP asked that the following information be added to this answer.