Click to See Complete Forum and Search --> : How do I programmatically change Windows Themes in XP?


CrystalAnnoysMe
August 13th, 2009, 02:23 PM
I wrote a small app we use on our computer to keep them running optimally and do some utility things (delete temp files, defrag drives, clean registry, backup my docs to the server, etc). One of the options I ahve in there is "Reset Windows to Defaults" and the objective was to setup windows how we normally would set them up before we give them to our users. So if a user messes with all his/her settings we can click this button and reset it all back. So far it resets IE settings, changes Window Explorer views, puts all the default icons on the desktop and turns off desktop cleanup, etc.

Well one of the last things I want to do is change to the default Windows XP theme and apply it. After a lot of searching the internet I found this:

<DllImport("UxTheme.DLL", BestFitMapping:=False, CallingConvention:=CallingConvention.Winapi, CharSet:=CharSet.Unicode, EntryPoint:="#65")> _
Shared Function SetSystemVisualStyle(ByVal pszFilename As String, ByVal pszColor As String, ByVal pszSize As String, ByVal dwReserved As Integer) As Integer
End Function

Then it can be called in your code with something like this:

SetSystemVisualStyle("C:\WINDOWS\resources\Themes\Luna\Luna.msstyles", "NormalColor", "NormalSize", 0)

It does reset colors and stuff back to the theme. The problem is if a user has "Windows Classic" set and this is run it does apply the theme.....mostly. Things like dialog boxes stay in classic while the menu structure and desktop go the XP style. If you go into display properties it still shows "Windows Classic" but under Appearance it shows "Windows XP" which leads me to believe even though this function is for themes its actually just applying the appearance and not actually setting the theme.

Anyone know how to actually change and apply the theme?

CrystalAnnoysMe
August 13th, 2009, 03:39 PM
Nevermind...have to call the function with a 1 at the end and not 0. That and update some other registry keys afterward. Either way it's working now.

HanneSThEGreaT
August 14th, 2009, 01:15 AM
Thanx for sharing!

I know this thread is solved, but you could also have a look at this article :

http://www.codeguru.com/vb/gen/vb_misc/gamesandfun/article.php/c14319__1/

Just for interest sake :)

commodore73
August 23rd, 2009, 02:53 PM
Nevermind...have to call the function with a 1 at the end and not 0. That and update some other registry keys afterward. Either way it's working now.

Hello,

I am trying to do the same thing. Would you be willing to post your code, or indicate what additional registry keys to set?

Thanks & regards,

-John

carl666
August 23rd, 2009, 03:26 PM
I know this thread is solved, but you could also have a look at this article :
http://www.codeguru.com/vb/gen/vb_misc/gamesandfun/article.php/c14319__1/
Just for interest sake :)

Very bad 'article'...
The registry don't absolutely need to be updated.

dglienna
August 23rd, 2009, 04:49 PM
Did you happen to catch the author of that 'bad' article? :eek:

HanneSThEGreaT
August 24th, 2009, 05:33 AM
Very bad 'article'...
The registry don't absolutely need to be updated.
Hmm.... Strange that the article has got 4 stars and the author of the article ( me ) has got a 4.64 rating out of 5, for all his ( my ) 25 articles..

Anyways, I'm not here to argue the quality of my article(s). I know I'm not the sharpest guy around :)

All I want to ask is why exactly do you say it is a very bad article, is it about the registry ¿

All the members & guests would like to know , because theyr'e here to learn. If you have a better way to do any of the topics covered in that article, please share it with us.

PS... Have you written any articles before ¿

CrystalAnnoysMe
August 24th, 2009, 07:29 AM
Imports System.Runtime.InteropServices
Module GeneralFunctions
<DllImport("UxTheme.DLL", BestFitMapping:=False, CallingConvention:=CallingConvention.Winapi, CharSet:=CharSet.Unicode, EntryPoint:="#65")> _
Friend Function SetSystemVisualStyle(ByVal pszFilename As String, ByVal pszColor As String, ByVal pszSize As String, ByVal dwReserved As Integer) As Integer
End Function
End Module


Then in my code I call the function first and then update the registry so it shows up as modified when someone looks at it:

SetSystemVisualStyle("C:\WINDOWS\resources\Themes\Luna\Luna.msstyles", "NormalColor", "NormalSize", 1)
WriteRegistryValue(Registry.CurrentUser, "Control Panel\Desktop", "Wallpaper", "C:\WINDOWS\Web\Wallpaper\Bliss.bmp", RegistryValueKind.String)
WriteRegistryValue(Registry.CurrentUser, "Control Panel\Desktop", "WallpaperStyle", "2", RegistryValueKind.String)
WriteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Internet Explorer\Desktop\General", "Wallpaper", "C:\WINDOWS\Web\Wallpaper\Bliss.bmp", RegistryValueKind.String)
WriteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Internet Explorer\Desktop\General", "WallpaperStyle", "2", RegistryValueKind.ExpandString)
WriteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Themes\LastTheme", "DisplayName of Modified", "Windows XP (Auto Modified)", RegistryValueKind.String)
DeleteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Themes\LastTheme", "ThemeFile")
WriteRegistryValue(Registry.CurrentUser, "Software\Microsoft\Windows\CurrentVersion\Themes\LastTheme", "Wallpaper", "%SystemRoot%\Web\Wallpaper\Bliss.bmp", RegistryValueKind.ExpandString)

Not going to post my registry functions, you should be able to figure them out. Works very well for what I want.

-Allan

TT(n)
August 26th, 2009, 04:26 PM
why exactly do you say it is a very bad article, is it about the registry

Yea, some people are prejudicial, like that.

They think:
Oh, it must be bad, because it's changing my registry.
In fact most API's relating to windows settings indeed change the registry too.

As you get better, and more expert at VB, you will find that all of your code could be used for bad purposes.
What better reason, to use it for good purposes. For example allowing users to control their themes.

That would be bad......Not

Craig Gemmill
August 26th, 2009, 09:41 PM
Hans,

I'm pretty sure the reader did not go beyond the first page, and that's not your fault, it's CG for having tiny page numbers at the bottom.

I think you do a great job explaining how all of that mess is organized in the registry.

If available, an API should always be used over a direct registry modification. So maybe you could improve your article by presenting a side-by-side comparison of the API's on [Page 2], and what registry values they modify.

However, that's a lot of research, and probably not necessary.

Hope you're well.

TT(n)
August 27th, 2009, 01:48 AM
If available, an API should always be used over a direct registry modification

Exactly, I agree with that for the reasoning:
The registry is a widely general tool, that in a sense could cause harm to any number of things.
Therefore it is lumped up with all of the other potentially harmful uses, by anti-virus programs, security settings, and people alike.
It's sort of a case of regicial profiling. lol

In my critique of the article/program, the only thing I saw missing, was the GetCurrentTheme API.
It makes sense that this should be in there for sure.
That way when the theme list is populated, the current them visible and selected.
This by no means, makes the article bad.


_

HanneSThEGreaT
September 1st, 2009, 01:22 AM
Hey guys! :wave:

Wow, thanx for your great reponses! I'll have a look at the available APIs, unfortunately just pressed for time :)

Good seeing you again Craig! Long time no see :thumb:

farrukh_javeid
August 9th, 2010, 02:17 PM
Hello Folks,

I am working on the same application that changes the Windows themes. I have two questions
1. My WriteRegistryValue() is not working. I cant find its references, although I thought it to be Microsoft.Win32.

2. My theme is not changing... I dont know what is the problem?

Need urgent help fellows

CrystalAnnoysMe
August 9th, 2010, 02:45 PM
Hello Folks,

I am working on the same application that changes the Windows themes. I have two questions
1. My WriteRegistryValue() is not working. I cant find its references, although I thought it to be Microsoft.Win32.

2. My theme is not changing... I dont know what is the problem?

Need urgent help fellows

1) Are you using my code sample above? If so then no it probably isn't working....the WriteRegistryValue() I have above is my own function for writting registry settings.

2) Fixing the above will fix the theme being set issue.

farrukh_javeid
August 9th, 2010, 03:22 PM
Thanks for the quick response :).
I need to ask if you have used the function Registry.SetValue()? If yes, in what shape the parameters might be.
Sorry, I am new to visual basic .net

dglienna
August 9th, 2010, 06:14 PM
I'd start a new thread, rather than bring up an old one. Not related, really.

farrukh_javeid
August 10th, 2010, 05:50 AM
I have one more question. Why do we use .msstyles and not .theme files?

CrystalAnnoysMe
August 10th, 2010, 09:03 AM
Thanks for the quick response :).
I need to ask if you have used the function Registry.SetValue()? If yes, in what shape the parameters might be.
Sorry, I am new to visual basic .net

Here's my WriteRegistryValue function:



''' <summary>
''' Writes a value to the registry.
''' </summary>
''' <param name="MainKey">Main key to reach as a registry key such as Registry.CurrentUser.</param>
''' <param name="Subkey">String of the subkey to read.</param>
''' <param name="KeyToWrite">String of the key to write to.</param>
''' <param name="KeyValue">Value to write.</param>
''' <param name="KeyType">Optional - Type of value being passed as a RegistryValueKind. If not specified will assume a string value.</param>
''' <remarks></remarks>
Friend Sub WriteRegistryValue(ByVal MainKey As RegistryKey, ByVal SubKey As String, ByVal KeyToWrite As String, ByVal KeyValue As String, Optional ByVal KeyType As RegistryValueKind = RegistryValueKind.String)
Dim rk As RegistryKey = MainKey.CreateSubKey(SubKey)
Try
rk.SetValue(KeyToWrite, KeyValue, KeyType)
rk.Close()
Catch ex As Security.SecurityException
MsgBox("Unable to write to the registry! You may not have high enough security for registery access." & vbLf & "Key: " & MainKey.ToString & SubKey & vbLf & "Key Name: " & KeyToWrite & vbLf & "Value: " & KeyValue, MsgBoxStyle.OkOnly, "Registry Error")
Debug.WriteLine(ex.Message)
Catch ex As Exception
Debug.WriteLine(ex.Message)
End Try
End Sub

farrukh_javeid
August 12th, 2010, 09:19 AM
Thank you that was a great help but I want to use .theme files as well in my project. Can you guide me how to accomplish this.
Thanks in advance.

CrystalAnnoysMe
August 12th, 2010, 09:22 AM
Thank you that was a great help but I want to use .theme files as well in my project. Can you guide me how to accomplish this.
Thanks in advance.

No idea...sorry. As someone else suggested you might want to jsut start a new thread for that.

farrukh_javeid
August 12th, 2010, 09:29 AM
Thanks for the help though. Ive already created a thread and just waiting for the help.
You're posts have been real helpful.
Regards,