Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio 2010 - Semi-Transparent Floating Windows

Is it possible to make floating windows in Visual Studio 2010 semi-transparent? I would like to be able to float an editor window and reduce the alpha level on it. Could this functionality be created with an extension that modifies the stock editor window?

If not an extension, are there decent third party applications which would be capable of modifying the properties of specific child windows in Visual Studio 2010?

like image 608
Nathan Taylor Avatar asked Oct 15 '10 19:10

Nathan Taylor


1 Answers

The main the problem is, it depends on the tool window, because Visual Studio does not mandate much about how the tool window is actually rendered.

If the tool window has an HNWD to play with, you can set transparency using the SetLayeredWindowAttributes function. If the tool window is WPF, you can use other tricks.

Now, the problem is to get a hold on something useful... Just launch SPY++ over Visual Studio 2010 and you will see there are not many visible HWND around. Some package use unmanaged code, some packages use .NET + Winforms, and more and more, recent packages use .NET + WPF.

UISpy (another spy tool, but based on UI Automation) sees all tool windows but it does not show any Native WIndow Handle (one of the standard property that UI automation can read) which is not good news.

Visual Studio uses the IVsWindowPane interface and specifically the CreatePaneWindow method to create the host window, but there is nothing official to get any HWND handle back to play with.

Hmm! If you have a specific tool window you want to tweak, we can have a deeper look, but I think it's difficult to write a 100% generic tool.

EDIT: I have searched further more. Here is a code that enumerates all windows frames (docked or floating) of the current Visual Studio instance:

// WindowFrame needs Microsoft.VisualStudio.Platform.WindowManagement.dll
public static IEnumerable<WindowFrame> EnumWindowFrames(Microsoft.VisualStudio.OLE.Interop.IServiceProvider sp, __WindowFrameTypeFlags frameTypes)
{
    if (sp == null)
        throw new ArgumentNullException("sp");

    ServiceProvider serviceProvider = new ServiceProvider(sp);
    IVsUIShell4 shell = (IVsUIShell4)serviceProvider.GetService(typeof(SVsUIShell)); // VS 2010 only

    IEnumWindowFrames framesEnum;
    IVsWindowFrame[] frames = new IVsWindowFrame[1];
    uint numFrames;
    shell.GetWindowEnum((uint)frameTypes, out framesEnum);
    if (framesEnum == null)
        yield break;

    while ((framesEnum.Next(1, frames, out numFrames) == VSConstants.S_OK) && (numFrames == 1))
    {
        WindowFrame frame = frames[0] as WindowFrame;
        if (frame != null)
            yield return frame;
    }
}

This will give a list of WindowFrame instances. WindowFrame is not documented but it's public (located in Microsoft.VisualStudio.Platform.WindowManagement.dll) , so you can play with it. Each WindowFrame instance has a FrameView property that has a Content property. This Content property is, most of the time from my findings, a WPF's Panel element. The hierarchy below that panel will then be dependent on how the window is actually implemented.

If it's an unmanaged or Winforms (example, the .SQL editor), there will be an HwndHost in the panel's children collection. I have tried to play with it (using SetLayeredWindowAttributes), but it does not seem to work...

If it's a WPF (example, the brand new C#/VB editor), there will be a huge WPF hiearchy, that will eventually go down to an IWfpTextView implementation. You can change many things along in this hierarchy, and some will work (such as the Background property), but... concerning the transparency, I don't think it's possible because the root window does not allow it (it has AllowTransparency set to false, and it can't be changed once it's displayed). Setting Opacity = 0.5 for example works, but since there is no transparency, the effect is just dimmed windows...

like image 98
Simon Mourier Avatar answered Sep 29 '22 20:09

Simon Mourier