在Windows 8中,我已將顏色方案設置爲自動並將配置我的牆紙在x分鐘後更改。配色方案根據活動壁紙而變化。獲取Windows 8自動顏色主題的活動顏色
我正在開發一個WPF應用程序,並希望在Windows更改顏色方案以匹配當前壁紙時更改我的漸變。
有沒有辦法獲取當前/實際的配色方案並通知C#中的更改?
在Windows 8中,我已將顏色方案設置爲自動並將配置我的牆紙在x分鐘後更改。配色方案根據活動壁紙而變化。獲取Windows 8自動顏色主題的活動顏色
我正在開發一個WPF應用程序,並希望在Windows更改顏色方案以匹配當前壁紙時更改我的漸變。
有沒有辦法獲取當前/實際的配色方案並通知C#中的更改?
是的,這是可能的。但是需要注意的是:這包含了很多Win32互操作(這意味着P /從託管代碼調用本地DLL),並且僅適用於某些未公開的API。雖然涉及的只是無證特點是獲得窗口顏色方案(或爲DWM調用它,窗口上色的顏色),這是覆蓋在這個其他問題:
Vista/7: How to get glass color?
在我自己的項目,我使用的調用來DwmGetColorizationParameters()
:
internal static class NativeMethods
{
[DllImport("dwmapi.dll", EntryPoint="#127")]
internal static extern void DwmGetColorizationParameters(ref DWMCOLORIZATIONPARAMS params);
}
public struct DWMCOLORIZATIONPARAMS
{
public uint ColorizationColor,
ColorizationAfterglow,
ColorizationColorBalance,
ColorizationAfterglowBalance,
ColorizationBlurBalance,
ColorizationGlassReflectionIntensity,
ColorizationOpaqueBlend;
}
我測試過它,它與Windows 8和其自動窗功能彩色的偉大工程。正如上面的鏈接中所建議的那樣,您可以在註冊表中查找顏色值作爲P/Invoke的替代方法,但我沒有測試過該方法,並且如上所述,這些方法沒有記錄,並且不能保證穩定。
一旦獲得用於繪製漸變畫筆的顏色,當窗口顏色方案更改時(不管是手動還是自動通過Windows),畫筆都不會更新。幸運的是,無論什麼時候發生,Windows都會播放WM_DWMCOLORIZATIONCOLORCHANGED
window message,所以只需要聽取該消息並在發送時更新顏色。您可以通過掛鉤窗口程序(WndProc()
)來完成此操作。
WM_DWMCOLORIZATIONCOLORCHANGED
的值是0x320
;你會想把它定義爲常量,所以你可以在代碼中使用它。另外,與WinForms不同,WPF窗口沒有虛擬的WndProc()
方法來覆蓋,因此您必須創建一個代理並將其掛接到其關聯的窗口句柄(HWND)。
以一些示例代碼從我的這些問題的答案:
我們:
const int WM_DWMCOLORIZATIONCOLORCHANGED = 0x320;
private IntPtr hwnd;
private HwndSource hsource;
private void Window_SourceInitialized(object sender, EventArgs e)
{
if ((hwnd = new WindowInteropHelper(this).Handle) == IntPtr.Zero)
{
throw new InvalidOperationException("Could not get window handle.");
}
hsource = HwndSource.FromHwnd(hwnd);
hsource.AddHook(WndProc);
}
private static Color GetWindowColorizationColor(bool opaque)
{
var params = NativeMethods.DwmGetColorizationParameters();
return Color.FromArgb(
(byte)(opaque ? 255 : params.ColorizationColor >> 24),
(byte)(params.ColorizationColor >> 16),
(byte)(params.ColorizationColor >> 8),
(byte) params.ColorizationColor
);
}
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
switch (msg)
{
case WM_DWMCOLORIZATIONCOLORCHANGED:
/*
* Update gradient brushes with new color information from
* NativeMethods.DwmGetColorizationParams() or the registry.
*/
return IntPtr.Zero;
default:
return IntPtr.Zero;
}
}
當Windows過渡的顏色變化,WM_DWMCOLORIZATIONCOLORCHANGED
是在每個關鍵幀上分派在轉換過程中,您將在顏色變化期間在短時間內收到許多消息。這個是正常的;只需像往常一樣更新漸變畫筆,並且您會注意到,當Windows轉換窗口顏色方案時,漸變將與其他窗口框架一起順利轉換。
請記住,您可能需要考慮DWM不可用的情況,例如在Windows XP上運行時,或者在Windows Vista或更高版本上運行並禁用桌面合成時。您還需要確保不會過度使用此功能,否則可能會導致嚴重的性能下降並拖慢您的應用程序。
這是我第一次發佈Windows 8的答案... Windows 8.不是太破舊... – BoltClock
哇,202k點:D –
哦,男孩,我剛剛從3年前發現我的評論。 :O –
這可以在.NET 4.5及更高版本中完成,無需P/Invokes。 SystemParameters類現在具有靜態WindowGlassBrush和WindowGlassColor屬性以及StaticPropertyChanged事件。
從XAML,您可以綁定到WindowGlassBrush屬性,如:
<Grid Background="{x:Static SystemParameters.WindowGlassBrush}">
然而,這項任務的背景顏色不會得到更新時自動的Windows改變它的顏色。不幸的是,SystemParameters不不提供WindowGlassBrushKey或WindowGlassColorKey性能與DynamicResource ResourceKeys使用,因此讓變更通知要求後面的代碼來處理StaticPropertyChanged事件。
public partial class MainWindow : Window
{
public MainWindow()
{
this.InitializeComponent();
SystemParameters.StaticPropertyChanged += this.SystemParameters_StaticPropertyChanged;
// Call this if you haven't set Background in XAML.
this.SetBackgroundColor();
}
protected override void OnClosed(EventArgs e)
{
SystemParameters.StaticPropertyChanged -= this.SystemParameters_StaticPropertyChanged;
base.OnClosed(e);
}
private void SetBackgroundColor()
{
this.Background = SystemParameters.WindowGlassBrush;
}
private void SystemParameters_StaticPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "WindowGlassBrush")
{
this.SetBackgroundColor();
}
}
}
System.Data.Services.WindowGlassColor屬性中的SystemParameters.WindowGlassColor屬性.NET 4.5框架只是包裝DwmGetColorizationColor –
我在模板內使用此屬性,有沒有什麼辦法更新模板來替換舊的顏色與新的? –
不幸的是,SystemParameters.WindowGlassBrush將不會返回正確的重音顏色,至少它在我的機器上是不同的。我使用這個代碼:https://gist.github.com/paulcbetts/3c6aedc9f0cd39a77c37 –
這包含了相當多的互操作性,只適用於某些*未公開的API *。事實上,我已經使用我自己的Windows Vista/7項目完成了這個任務,並在Windows 8上成功地進行了測試。我可以嘗試根據這個答案提出一個答案,但我需要一段時間。另請參閱:[Vista/7:如何獲取玻璃顏色?](http://stackoverflow.com/questions/3560890/vista-7-how-to-get-glass-color) – BoltClock
非常感謝您的信息。我使用了註冊表技巧,效果很好。 – user1868880