Основная проблема заключается в том, что это зависит от окна инструмента, потому что Visual Studio не требует много информации о том, как фактически отображается окно инструмента.
Если в окне инструмента есть HNWD для игры, вы можете установить прозрачность с помощью функции SetLayeredWindowAttributes . Если окно инструментов WPF, вы можете использовать другие приемы.
Теперь проблема в том, чтобы ухватиться за что-то полезное ... Просто запустите SPY ++ поверх Visual Studio 2010, и вы увидите, что вокруг не так много видимых HWND. Некоторые пакеты используют неуправляемый код, некоторые пакеты используют .NET + Winforms, и все больше и больше, последние пакеты используют .NET + WPF.
UISpy (еще один шпионский инструмент, но основанный на UI Automation ), видит все окна инструментов, но не отображает какой-либо собственный дескриптор окна (одно из стандартных свойств, которое может автоматизировать пользовательский интерфейс). читай) что не очень хорошая новость.
Visual Studio использует интерфейс IVsWindowPane и, в частности, метод CreatePaneWindow для создания окна хоста, но нет ничего официального, чтобы вернуть любой дескриптор HWND для воспроизведения.
Хм! Если у вас есть конкретное окно инструментов, которое вы хотите настроить, мы можем взглянуть глубже, но я думаю, что написать 100% универсальный инструмент сложно.
РЕДАКТИРОВАТЬ : Я искал еще больше. Вот код, который перечисляет все оконные фреймы (закрепленные или плавающие) текущего экземпляра Visual Studio:
// 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;
}
}
Это даст список экземпляров WindowFrame. WindowFrame не документирован, но общедоступен (находится в Microsoft.VisualStudio.Platform.WindowManagement.dll), поэтому вы можете поиграть с ним. Каждый экземпляр WindowFrame имеет свойство FrameView, которое имеет свойство Content. Это свойство Content, по большей части из моих выводов, является элементом Panel WPF. Иерархия под этой панелью будет зависеть от того, как на самом деле реализовано окно.
Если это неуправляемый или Winforms (например, редактор .SQL), в дочерней коллекции панели будет HwndHost. Я пытался поиграть с ним (используя SetLayeredWindowAttributes ), но, похоже, не работает ...
Если это WPF (например, новый редактор C # / VB), то будет огромная иерархия WPF, которая в конечном итоге перейдет к реализации IWfpTextView . Вы можете изменить многие вещи в этой иерархии, и некоторые будут работать (например, свойство Background), но ... что касается прозрачности, я не думаю, что это возможно, потому что корневое окно этого не позволяет (оно имеет * 1034). * AllowTransparency имеет значение false, и его нельзя изменить после его отображения). Например, установка Opacity = 0.5 работает, но поскольку прозрачности нет, эффект - просто затемненные окна ...