Oprócz postu "Jan Goyvaerts": Używam SendMessage zamiast PostMessage. Różnica polega na tym, że SendMessage czeka, aż komenda zostanie odebrana przez okno. Oznacza to, że w SendMessages zwraca, wiesz, że okno tematu jest zamknięte.
Więc jeśli zaczniesz od monstrualnej (ale genialnej) metody rundll32.exe sugerowanej przez "Campbell". Powinieneś poczekać sekundę przed wysłaniem WM_CLOSE. W przeciwnym razie motyw nie zostanie ustawiony, a aplikacja zostanie natychmiast zamknięta.
Poniższy fragment kodu wyodrębnia plik z zasobu (plik themepack). Następnie wykonuje plik desk.cpl z plikiem rundll32.exe, czeka 3 sceondy, a następnie wysyła WM_CLOSE (0x0010), czeka na przetworzenie polecenia (czas potrzebny na ustawienie kompozycji).
private Boolean SwitchToClassicTheme()
{
//First unpack the theme
try
{
//Extract the theme from the resource
String ThemePath = System.Environment.GetFolderPath(Environment.SpecialFolder.Windows) + @"\Resources\Themes\ClassicTheme.themepack";
//WriteFileToCurrentDirectory("ClassicTheme.theme", TabletConfigurator.Resources.ClassicTheme);
if(File.Exists(ThemePath))
{
File.Delete(ThemePath);
}
if(File.Exists(ThemePath))
{
throw new Exception("The file '" + ThemePath + "' exists and can not be deleted. You can try to delete it manually.");
}
using (BinaryWriter sw = new BinaryWriter(new FileStream(ThemePath, FileMode.OpenOrCreate)))
{
sw.Write(TabletConfigurator.Resources.ClassicTheme);
sw.Flush();
sw.Close();
}
if(!File.Exists(ThemePath))
{
throw new Exception("The resource theme file could not be extracted");
}
//Set the theme file as like a user would have clicked it
Boolean bTimedOut = false;
String ThemeOutput = StartProcessAndWait("rundll32.exe", System.Environment.GetFolderPath(Environment.SpecialFolder.System) + @"\shell32.dll,Control_RunDLL " + System.Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\desk.cpl desk,@Themes /Action:OpenTheme /file:\"" + ThemePath + "\"", ref bTimedOut);
System.Threading.Thread.Sleep(3000);
//Wait for the theme to be set
IntPtr hWndTheming = FindWindow("CabinetWClass", null);
SendMessage(hWndTheming, (uint)WM_CLOSE, 0, 0);
//using (Bitmap bm = CaptureScreenShot())
//{
// Boolean PixelIsGray = true;
// while (PixelIsGray)
// {
// System.Drawing.Color pixel = bm.GetPixel(0, 0)
// }
//}
}
catch(Exception ex)
{
ShowError("An exception occured while setting the theme: " + ex.Message);
return false;
}
return true;
}
chory .. jak to wymyśliłeś? – Claudiu
imma dać tę nagrodę, ponieważ jest to faktyczna odpowiedź – Claudiu
Zgaduję, że został opracowany przy użyciu ProcessMonitor podczas ręcznej zmiany tematu. –