Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>As you've said, <code>DwmExtendFrameIntoClientArea</code> literally extends the transparent glass effect of the window's frame into its client area, which means that if your form's <code>FormBorderStyle</code> is set to "None", your window will effectively be invisible.</p> <p><strong>Instead, you need to use the <a href="http://msdn.microsoft.com/en-us/library/aa969508.aspx"><code>DwmEnableBlurBehindWindow</code> API</a>, which enables the glassy blur effect on a window without requiring it to have a frame/border.</strong> It takes two parameters. The first (<code>hWnd</code>) is the handle to the form that you wish to apply the blur behind effect to. The second (<code>pBlurBehind</code>) is a structure passed by reference that contains data or parameters for the effect.</p> <p>Therefore, you also have to define the <a href="http://msdn.microsoft.com/en-us/library/aa969500.aspx"><code>DWM_BLURBEHIND</code> structure</a>, which itself contains four members. The first (<code>dwFlags</code>) is a bitwise combination of <a href="http://msdn.microsoft.com/en-us/library/aa969533%28v=VS.85%29.aspx">constant values</a> that indicate which members of this structure have been set. The second (<code>fEnable</code>) indicates whether you want to enable or disable the blur effect. The third (<code>hRgnBlur</code>) allows you to specify a particular region within the client area that the blur effect will be applied to; setting this to <code>Nothing</code> indicates that the entire client area will have the blur effect. The fourth (<code>fTransitionOnMaximized</code>) allows you to specify whether or not the form's colorization should transition to match the maximized windows.</p> <p>Here are the final API declarations that you have to include in your code in order to use this function:</p> <pre><code>&lt;StructLayout(LayoutKind.Sequential)&gt; _ Private Structure DWM_BLURBEHIND Public dwFlags As Integer Public fEnable As Boolean Public hRgnBlur As IntPtr Public fTransitionOnMaximized As Boolean End Structure Private Const DWM_BB_ENABLE As Integer = &amp;H1 Private Const DWM_BB_BLURREGION As Integer = &amp;H2 Private Const DWM_BB_TRANSITIONONMAXIMIZED As Integer = &amp;H4 &lt;DllImport("dwmapi.dll", PreserveSig:=False)&gt; _ Private Shared Sub DwmEnableBlurBehindWindow(ByVal hWnd As IntPtr, ByRef pBlurBehind As DWM_BLURBEHIND) End Sub </code></pre> <p>And then here's a simple example of how you would call this function on a particular form:</p> <pre><code>Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) MyBase.OnLoad(e) ''#Set the form's border style to None Me.FormBorderStyle = FormBorderStyle.None ''#Whatever region that you fill with black will become the glassy region ''# (in this example, the entire form becomes transparent) Me.BackColor = Color.Black ''#Create and populate the blur-behind structure Dim bb As DWM_BLURBEHIND bb.dwFlags = DWM_BB_ENABLE bb.fEnable = True bb.hRgnBlur = Nothing ''#Enable the blur-behind effect DwmEnableBlurBehindWindow(Me.Handle, bb) End Sub </code></pre> <p>If instead, you only want to apply the blur behind effect to a particular subregion of the form, you will need to supply a valid region for the <code>hRgnBlur</code> member, and add the <code>DWM_BB_BLURREGION</code> flag to the <code>dwFlags</code> member.</p> <p>You can use the <a href="http://msdn.microsoft.com/en-us/library/system.drawing.region.gethrgn.aspx"><code>Region.GetHrgn</code> method</a> to get a handle to the region you want to specify as the <code>hRgnBlur</code> member. For example, instead of the above code, you can use the following:</p> <pre><code>Protected Overrides Sub OnLoad(ByVal e As System.EventArgs) MyBase.OnLoad(e) ''#Set the form's border style to None Me.FormBorderStyle = FormBorderStyle.None ''#Fill the entire form with black to make it appear transparent Me.BackColor = Color.Black ''#Create a region corresponding to the area of the form you want to render as glass Using g As Graphics = Me.CreateGraphics Dim glassRect As New Rectangle(0, 0, 100, 150) Using rgn As New Region(glassRect) ''#Create and populate the blur-behind structure Dim bb As DWM_BLURBEHIND bb.dwFlags = DWM_BB_ENABLE Or DWM_BB_BLURREGION bb.fEnable = True bb.hRgnBlur = rgn.GetHrgn(g) ''#Enable blur-behind effect DwmEnableBlurBehindWindow(Me.Handle, bb) End Using End Using End Sub </code></pre> <p>Notice how, even when specifying a particular subregion to apply the blur-behind effect to, I still set the entire form's background color to black? This will cause the region we specified to render with a glassy blur-behind effect, and the rest of the form to appear transparent. Of course, you can set the rest of the form's background color to any color that you want (although make sure to fill the rectangle that you want to appear as glass with the color black, as before), but it will appear as partially transparent, just without the glassy blur-behind effect. <a href="http://msdn.microsoft.com/en-us/library/aa969537.aspx">MSDN</a> explains why this is the case:</p> <blockquote> <p>When you apply the blur-behind effect to a subregion of the window, the alpha channel of the window is used for the nonblurred area. This can cause an unexpected transparency in the nonblurred region of a window. Therefore, be careful when you apply a blur effect to a subregion.</p> </blockquote> <p>As far as I'm concerned, that makes applying this effect to only a subregion of the form's window relatively worthless. The only time it seems to me like it might make sense is if you want to render an arbitrary non-rectangular shape as glassy, with the rest of the form remaining transparent.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload