Sì, è possibile. Tuttavia sii avvisato: questo include un po 'di interoperabilità di Win32 (questo significa P/Invoca in DLL native dal codice gestito) ed è eseguibile solo con alcune API prive di documenti. Anche se, le uniche caratteristiche non documentate coinvolti sono per ottenere lo schema di colore della finestra (o come il DWM lo chiama, il colore della finestra colorazione), che è coperto in quest'altra domanda:
Vista/7: How to get glass color?
Nel mio progetto, faccio uso di una chiamata a 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;
}
ho provato e funziona benissimo con Windows 8 e la sua funzione automatica finestra colorazione. Come suggerito nel link qui sopra, puoi cercare nel registro i valori dei colori come alternativa a un P/Invoke, ma non ho provato quel metodo, e come dichiarato questi non sono documentati e non sono garantiti come stabili.
Una volta ottenuto il colore per disegnare i pennelli sfumati, i pennelli non si aggiorneranno quando la combinazione di colori della finestra cambia, manualmente o automaticamente da Windows. Fortunatamente, Windows trasmette lo WM_DWMCOLORIZATIONCOLORCHANGED
window message ogni volta che ciò accade, quindi è sufficiente ascoltare quel messaggio e aggiornare i colori ogni volta che viene inviato. Lo fai agganciando la procedura della finestra (WndProc()
).
Il valore di WM_DWMCOLORIZATIONCOLORCHANGED
è 0x320
; vorrai definirlo come una costante da qualche parte in modo da poterlo usare nel codice.
Inoltre, a differenza di WinForms, le finestre WPF non hanno un metodo virtuale WndProc()
da sovrascrivere, quindi è necessario crearne uno e collegarlo come delegato agli handle di finestra associati (HWND).
Prendendo qualche esempio di codice da queste risposte miei:
Abbiamo:
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;
}
}
Quando Windows transizione il cambiamento di colore, WM_DWMCOLORIZATIONCOLORCHANGED
è spedito ad ogni keyframe durante la transizione, quindi riceverai numerosi messaggi con una breve interruzione durante il cambio di colore. E 'normale; semplicemente aggiorna i pennelli sfumati come al solito e noterai che quando Windows passa dallo schema dei colori della finestra, i tuoi gradienti passeranno uniformemente insieme al resto dei fotogrammi delle finestre.
Ricordare che potrebbe essere necessario tenere conto di situazioni in cui il DWM non è disponibile, ad esempio quando si esegue su Windows XP o quando si esegue su Windows Vista o versioni successive con composizione desktop disabilitata. Inoltre, devi assicurarti di non utilizzarlo eccessivamente, altrimenti potresti incorrere in un notevole calo delle prestazioni e rallentare la tua app.
Questo include un po 'di interoperabilità ed è possibile solo con alcune * API non documentate *. In effetti, l'ho fatto con il mio progetto per Windows Vista/7, e l'ho testato con successo su Windows 8. Posso provare a mettere insieme una risposta basata su questo, ma mi servirà un po 'di tempo. Vedi anche: [Vista/7: Come ottenere il colore del vetro?] (Http://stackoverflow.com/questions/3560890/vista-7-how-to-get-glass-color) – BoltClock
Grazie mille per l'informazione . Ho usato il trucco del registro e funziona benissimo. – user1868880