该方法被广为流传 还有一种方法则是通过Shell对象来获取IE指针,不过只能获取
到IE窗口的网页文档如果不是就不行了 不过在这里我介绍通过MSAA技术的原型
ObjectFromLresult 函数实现获取IE内核网页文档对象指针的一个办法 不局限域
MSDN:https://msdn.microsoft.com/en-us/library/ms696155.aspx
核心代码:
public const int SMTO_ABORTIFHUNG = 2;
public static object GetComObjectByHandle(int Msg, Guid Riid, IntPtr Handle)
{
object pComObject;
int lpdwResult = 0;
if (!SendMessageTimeout(Handle, Msg, 0, 0, SMTO_ABORTIFHUNG, 1000, ref lpdwResult))
return null;
if (ObjectFromLresult(lpdwResult, ref Riid, 0, out pComObject))
return null;
return pComObject;
}
// public readonly static int WM_GETOBJECT = RegisterWindowMessage("WM_GETOBJECT");
public readonly static int WM_HTML_GETOBJECT = RegisterWindowMessage("WM_HTML_GETOBJECT");
public readonly static Guid IID_IHTMLDocument = new Guid("626fc520-a41e-11cf-a731-00a0c9082637");
public static object GetHtmlDocumentByHandle(IntPtr Handle)
{
return GetComObjectByHandle(WM_HTML_GETOBJECT, IID_IHTMLDocument, Handle);
}
示例代码:
private void _AxWeb_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
const int GW_CHILD = 5;
IntPtr hWnd = GetWindow(_AxWeb.Handle, GW_CHILD);
hWnd = GetWindow(hWnd, GW_CHILD);
hWnd = GetWindow(hWnd, GW_CHILD);
object objDocument = GetHtmlDocumentByHandle(hWnd);
Console.WriteLine(Convert.ToString(objDocument ?? string.Empty) == "mshtml.HTMLDocumentClass");
}
API声明:
[DllImport("oleacc.DLL", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool ObjectFromLresult(
[In]int lResult,
[In]ref Guid riid,
[In]int wParam,
[Out, MarshalAs(UnmanagedType.IUnknown)]out object ppvObject
);
[DllImport("user32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.I4)]
public static extern int RegisterWindowMessage(
[In]string lpString
);
[DllImport("user32.dll", EntryPoint = "SendMessageTimeoutA", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool SendMessageTimeout(
[In]IntPtr MSG,
[In]int hWnd,
[In]int wParam,
[In]int lParam,
[In]int fuFlags,
[In]int uTimeout,
[In, Out]ref int lpdwResult
);
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr GetWindow(IntPtr hWnd, int nCmd);