NB: THIS IS NOT A QUESTION ABOUT A BORDERLESS WINDOW.
So, I stumbled upon this program while I was exploring my Start menu the other day on Windows 7:>
So, unbeknownst to me, hRgn
can take an irregular shape (and DwmEnableBlurBehindWindow
takes an hRgn
, but I knew that). So, here's my solution that's (more or less) compatible with WPF:
...and source code:
MainWindow.xaml:
MainWindow.xaml.cs:
public partial class MainWindow : Window {
public MainWindow() {
InitializeComponent();
this.SourceInitialized += MainWindow_SourceInitialized;
this.KeyDown += MainWindow_KeyDown;
}
void MainWindow_KeyDown(object sender, KeyEventArgs e) {
if (e.Key == Key.Escape) this.Close();
}
void MainWindow_SourceInitialized(object sender, EventArgs e) {
var helper = new WindowInteropHelper(this);
var hwnd = helper.Handle;
var src = HwndSource.FromHwnd(hwnd);
src.CompositionTarget.BackgroundColor = Colors.Transparent;
WindowChrome.SetWindowChrome(this, new WindowChrome {
CaptionHeight = 500,
CornerRadius = new CornerRadius(0),
GlassFrameThickness = new Thickness(0),
NonClientFrameEdges = NonClientFrameEdges.None,
ResizeBorderThickness = new Thickness(0),
UseAeroCaptionButtons = false
});
GraphicsPath path = new GraphicsPath(FillMode.Alternate);
path.StartFigure();
path.AddArc(new RectangleF(0, 0, 500, 500), 0, 360);
path.CloseFigure();
var dbb = new DwmBlurBehind(true);
dbb.SetRegion(Graphics.FromHwnd(hwnd), new Region(path));
DwmApi.DwmEnableBlurBehindWindow(hwnd, ref dbb);
}
}
I think somebody else beat me to it, but here's how my solution works:
When the window's SourceInitialized
event is fired, that means that we have a handle for our window. So in the handler of this function, I get the window handle. Then I make a call to a function I imported from dwmapi.dll called DwmEnableBlurBehindWindow
. This basically turns transparent areas of the window into glass for a certain region. The DwmBlurBehind
struct I got from pinvoke.net, and it converts a GDI+ System.Drawing.Region
into an hRgn
. The hRgn
is passed to DwmEnableBlurBehindWindow
, and it clips the transparent parts to the Region
. In this case, I used a circle. Then the XAML is just the accent borders. It's worth noting that, for some reason, setting Window.Background
to Transparent
doesn't enable hit-testing when AllowsTransparency
is true here. No idea why, but it probably has something to do with the code-behind.