主要问题是,它取决于工具窗口,因为 Visual Studio 对于工具窗口的实际呈现方式没有太多要求。
如果工具窗口有 HNWD 可供使用,您可以使用设置LayeredWindow属性 http://msdn.microsoft.com/en-us/library/ms633540%28v=vs.85%29.aspx功能。如果工具窗口是WPF,则可以使用其他技巧。
现在,问题是要掌握一些有用的东西...只需在 Visual Studio 2010 上启动 SPY++,您就会发现周围没有太多可见的 HWND。有些包使用非托管代码,有些包使用.NET + Winforms,最近的包越来越多地使用.NET + WPF。
UISpy http://msdn.microsoft.com/en-us/library/ms727247.aspx(另一个间谍工具,但基于用户界面自动化 http://en.wikipedia.org/wiki/Microsoft_UI_Automation)可以看到所有工具窗口,但不显示任何 Native WIndow Handle(UI 自动化可以读取的标准属性之一),这不是好消息。
Visual Studio 使用 IVsWindowPane 接口,特别是创建窗格窗口 http://msdn.microsoft.com/en-US/library/microsoft.visualstudio.shell.interop.ivswindowpane.createpanewindow%28v=VS.80%29.aspx方法来创建主机窗口,但没有任何官方可以获取任何 HWND 句柄来使用。
唔!如果您有想要调整的特定工具窗口,我们可以进行更深入的研究,但我认为编写 100% 通用工具很困难。
EDIT: 我又进一步搜索了。以下代码枚举当前 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 属性在大多数情况下是 WPF 的 Panel 元素。该面板下方的层次结构将取决于窗口的实际实现方式。
如果它是非托管或 Winform(例如 .SQL 编辑器),则面板的子集合中将有一个 HwndHost。我尝试玩它(使用设置LayeredWindow属性 http://msdn.microsoft.com/en-us/library/ms633540%28v=vs.85%29.aspx),但似乎不起作用......
如果它是一个 WPF(例如,全新的 C#/VB 编辑器),将会有一个巨大的 WPF 层次结构,最终会下降到一个IWfp文本视图 http://msdn.microsoft.com/en-us/library/microsoft.visualstudio.text.editor.iwpftextview.aspx执行。您可以在此层次结构中更改许多内容,有些内容可以工作(例如背景属性),但是...关于透明度,我认为这是不可能的,因为根窗口不允许这样做(它有允许透明度 http://msdn.microsoft.com/en-us/library/system.windows.window.allowstransparency.aspx设置为false,一旦显示就无法更改)。例如,设置 Opacity = 0.5 是可行的,但由于没有透明度,效果只是使窗口变暗......