views:

1022

answers:

5

There are a couple of tricks for getting glass support for .Net forms.

I think the original source for this method is here: http://blogs.msdn.com/tims/archive/2006/04/18/578637.aspx

Basically:

//reference Desktop Windows Manager (DWM API)
[DllImport( "dwmapi.dll" )]
static extern void DwmIsCompositionEnabled( ref bool pfEnabled );

[DllImport( "dwmapi.dll" )]
static extern int DwmExtendFrameIntoClientArea( IntPtr hWnd, ref MARGINS pMarInset );


//then on form load
//check for Vista
if ( Environment.OSVersion.Version.Major >= 6 )
{
    //check for support
    bool isGlassSupported = false;
    DwmIsCompositionEnabled( ref isGlassSupported );

    if ( isGlassSupported )
        DwmExtendFrameIntoClientArea( this.Handle, ref margins );
...

//finally on print draw a black box over the alpha-ed area
//Before SP1 you could also use a black form background

That final step is the issue - any sub controls drawn over that area seem to also treat black as the alpha transparency mask.

For instance a tab strip over the class area will have transparent text.

Is there a way around this?

Is there an easier way to do this?

The applications I'm working on have to work on both XP and Vista - I need them to degrade gracefully. Are there any best practices here?

+2  A: 

There really isn't an easier way to do this. These APIs are not exposed by the .NET Framework (yet), so the only way to do it is through some kind of interop (or WPF).

As for working with both Windows versions, the code you have should be fine, since the runtime does not go looking for the entry point to the DLL until you actually call the function.

DannySmurf
A: 

DannySmurf said it. You don't have direct "managed" access to these APIs though the .NET framework (I tried this myself a few weeks ago).

I ended up doing something nasty. Created my own UI with GDI+. (Buttons, rounded labels, etc). It looks the same regardless of the Windows version. Win.Forms is really ugly, but that's all you got on the XP < side.

Martín Marconcini
A: 

I don't mind the unmanaged calls - it's the hack of using a black box to mimic the alpha behaviour and the effect it then has on black element in some components on top that's the problem.

Keith
+1  A: 

I think you forgot to set the TransparencyKey of the area you want to be glass. From the article,

In your Windows Forms application, you simply need to set the TransparencyKey property to a color that you won't use elsewhere in the application (I use Gainsboro, for reasons that will become apparent later). Then you can create one or more panels that are docked to the margins of your form and set the background color for the panel to the transparency key. Now when you call DwmExtendFrameIntoClientArea, the glass will show within its margins wherever you've set something of the appropriate transparency key.

Abe Heidebrecht
Thanks, but that doesn't work after SP1 - it seems like the box has to be black.
Keith
A: 

A cheap hack you can use is to place a transparent Panel control over your form and place your controls on it -- black will then be black.

softwerx