📜 ⬆️ ⬇️

Add Aero Glass window effect

Probably everyone who worked with Windows Vista (for example, there are avid XP users who haven't even seen Aero :)), saw the so-called Aero Glass effect - one of the distinctive effects of Windows Vista in Aero mode. By default, this effect extends to the headers of non-maximized windows and has the appearance of blurring the contents of other windows behind the title bar of the active window:

image

This effect can be extended to the client area of ​​the window, which will be discussed further. As an example, the Windows Vista Explorer window, which can be seen in the screenshot above. The effect in the explorer is distributed to the client area where the controls are located. Naturally, this will only work on Windows Vista. Therefore, before applying this effect, we need to check the Windows version (below and further, the code using C #):
if (Environment.OSVersion.Version.Major >= 6)
{
// Vista features are supported.
}


You also need to know that there is a restriction on the use of the effect: the effect zone always starts from the window borders, that is, you cannot create a “glass” piece somewhere in the middle of the window. This can be bypassed using irrelevant controls if you apply the effect to the whole window.
')
So, for the effect you need to use the Win API DwmExtendFrameIntoClientArea () located in the DwmApi.dll library:
[DllImport("DwmApi.dll")]
public static extern int DwmExtendFrameIntoClientArea(
IntPtr hwnd,
ref Margins pMarInset);


The Margins structure determines how many pixels to extend the effect area into the client area of ​​the window.
Now we will declare the structure Margins:
[StructLayout(LayoutKind.Sequential)]
public struct Margins
{
public int cxLeftWidth;
public int cxRightWidth;
public int cyTopHeight;
public int cyBottomHeight;
}


Now you can actually call the method, in this case we expand the zone of effect in the client area down by 50 pixels:
private void Form1_Load(object sender, EventArgs e)
{
margins = new Margins();
margins.cxLeftWidth = 0;
margins.cxRightWidth = 0;
margins.cyTopHeight = 50;
margins.cyBottomHeight = 0;

int retValue = DwmExtendFrameIntoClientArea(this.Handle, ref margins);

if (retValue < 0)
throw new NotSupportedException();
}


The effect should be applied before the appearance of the window, or it will be necessary to re-create the window:
this.RecreateHandle();


But that's not all. If we execute the code now, then instead of “glass” we will see a black bar. This is because GDI has no idea about the alpha channel, using a black brush in the effect zone solves the problem:
protected override void OnPaintBackground(PaintEventArgs e)
{
e.Graphics.FillRectangle(Brushes.Black, 0, 0, this.ClientSize.Width, margins.cyTopHeight);
}


Now run and see the cherished window:
image

The principle is clear. The rest, such as spreading the effect to the entire area of ​​the window, or adding the ability to drag the mouse over the zone of effect, is a matter of technique.

Source: https://habr.com/ru/post/59899/


All Articles