我正在使用C#构建WPF应用程序,我想在列表框中显示打开的IE选项卡的缩略图。我本质上是在尝试复制Windows 7中的DWM功能。
我已经弄清楚如何使用Interop.ShDocVW枚举打开的标签列表,但是为了使用DWM API调用,我必须传入hwnd
,并且所有标签都共享相同的句柄作为Internet Explorer。
所以我一直在捣乱EnumWindows
和EnumChildWindows
,但我无法解决任何问题。
有关如何最好地解决这个问题的任何建议吗?
答案 0 :(得分:6)
此代码枚举与IE缩略图对应的窗口句柄,可用作DwmRegisterThumbnail function
的hwndSource
参数
public static IEnumerable<IntPtr> EnumerateIEDwmThumbnails()
{
List<IntPtr> ptrs = new List<IntPtr>();
StringBuilder cls = new StringBuilder(100);
EnumWindows((hwnd, lparam) =>
{
GetClassName(hwnd, cls, cls.Capacity);
if (cls.ToString() == "TabThumbnailWindow")
{
ptrs.Add(hwnd);
}
return true;
}, IntPtr.Zero);
return ptrs;
}
[DllImport("user32.dll")]
private static extern bool EnumWindows(EnumWindowsCallback lpEnumFunc, IntPtr lParam);
private delegate bool EnumWindowsCallback(IntPtr hwnd, IntPtr lParam);
[DllImport("user32.dll")]
private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);
答案 1 :(得分:5)
虽然确实在问题中有详细说明,但我并没有真正专门研究DWM Thumbnail API和DwmRegisterThumbnail function的要求:
hwndSource
用作缩略图源的窗口句柄。 将源窗口句柄设置为顶级以外的任何其他句柄 窗口类型将导致返回值E_INVALIDARG。 [强调我的]
强调的要求使我通过下面列出的FindWindowEx()检索到的子窗口的方法无效,即只有FindWindow()可能用于检索顶级窗口的句柄(感谢Simon指出这一点) out) - Simon's answer提供了一个适当的解决方案,该解决方案基于显然专门为此目的而呈现的顶级IE窗口的类名。
[...]为了使用DWM API调用,我必须传入一个hwnd,并且 选项卡共享与Internet Explorer相同的句柄。
您是如何检查窗口层次结构的?如果我检查IE 9窗口,例如Spy++,它公开了以下Window Classes(缩写)的层次结构:
子窗口有单独的手柄,因此(从头顶开始)您应该能够通过适当调用FindWindowEx function来检索所需的手柄,例如:
HWND hwndIeTab = ::FindWindowEx(hwndIeFrame, NULL, "Internet Explorer_Server", NULL);
为了检索所有需要的标签,您需要通过 FindWindowEx()的第二个参数hwndChildAfter
迭代结果:
子窗口的句柄。搜索从下一个孩子开始 Z顺序的窗口。子窗口必须是直接子窗口 hwndParent,而不仅仅是后代窗口。
因此,您需要通过课程&#34;框架标签&#34;进行迭代。首先检索每个&#34; Internet Explorer_Server&#34;子窗口依次调用 FindWindowEx()(尽管您可能想要进行实验,是否通过第3个参数lpszClass
将孩子传递到更高的位置会产生相同或更好的结果)。< / p>
祝你好运!
答案 2 :(得分:1)
我使用的解决方案是使用Win32 API中的EnumWindows
和GetWindowText
。我使用shdocvw.dll
通过Internet Explorer窗口进行枚举,并将标签的标题传递给解析GetWindowText
结果的方法,以查找带有该标题的窗口的hwnd。
这适用于所有IE窗口,而不仅仅是标签。