c wm html getobject,C# 依据鼠标坐标取网页内成员坐标.ie(示例代码)

C# 根据鼠标坐标取网页内成员坐标.ie

有时候你需要后台获取ie浏览器 鼠标所在位置的元素坐标,然而你使用屏幕坐标是不可行的

所以我们需要把坐标转换成浏览器内坐标 然后再通过elementFromPoint获取网页成员。

private void tmrWatcher_Tick(object sender, EventArgs e)

{

IntPtr hWnd = WindowFromPoint(MousePosition);

dynamic document = GetHtmlDocumentByHandle(hWnd);

if (document != null)

{

Rectangle r = GetHtmlElementPoint(hWnd, MousePosition, document); // 根据鼠标坐标取网页成员坐标

Marshal.FinalReleaseComObject(document);

Console.WriteLine(r.X + ":" + r.Y + ":" + r.Width + ":" + r.Height);

}

}

上面是一个时钟tmrWatcher的Tick回调函数,在上面使用了WindowFromPoint函数 主要是获取

MousePosition所在的窗口句柄,然后再通过GetHtmlDocumentByHandle函数(获取文档从句柄)

public static object GetComObjectByHandle(int Msg, Guid riid, IntPtr hWnd)

{

object _ComObject;

int lpdwResult = 0;

if (!SendMessageTimeout(hWnd, Msg, 0, 0, SMTO_ABORTIFHUNG, 1000, ref lpdwResult))

return null;

if (ObjectFromLresult(lpdwResult, ref riid, 0, out _ComObject))

return null;

return _ComObject;

}

public object GetHtmlDocumentByHandle(IntPtr hWnd)

{

string buffer = new string(‘\0‘, 24);

GetClassName(hWnd, ref buffer, 25);

if (buffer != "Internet Explorer_Server")

return null;

return GetComObjectByHandle(WM_HTML_GETOBJECT, IID_IHTMLDocument, hWnd);

}

实际上与我上次的帖子:http://blog.csdn.net/u012395622/article/details/46404193

并没什么太大的出入,而获取一个网页文档的成员只是简单的调度Mshtml COM接口

public Rectangle GetHtmlElementPoint(IntPtr hWnd, Point point, dynamic document)

{

if (document == null && hWnd != IntPtr.Zero)

return Rectangle.Empty;

ScreenToClient(hWnd, ref point);

dynamic element = document.elementFromPoint(point.X, point.Y);

if (element == null) return Rectangle.Empty;

try

{

Rectangle o = new Rectangle()

{

Y = element.offsetTop,

X = element.offsetLeft,

Width = element.offsetWidth,

Height = element.offsetHeight

};

while (element.offsetParent != null)

{

element = element.offsetParent;

o.Y += element.offsetTop;

o.X += element.offsetLeft;

}

return o;

}

catch

{

return Rectangle.Empty;

}

}

上面代码是实现获取 元素在网页内的一个确切坐标,整体并不是很难阅读的。

之所以while(element.offsetParent != null) { ... }是因为网页始终与客户端不相

同我们不能用常规在Win32操作控件位置那样去看待它 它很麻烦,而且层次

很难分明,所以会造成你根本不知道到底有多宽不过还好,一般计算一个

成员元素在窗口什么位置,只要把父容器的位置加起来就行了。反正有点

解释的不清楚,大家莫见怪

[DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]

public static extern bool ScreenToClient(IntPtr hWnd, ref Point lpPoint);

[DllImport("user32.dll", SetLastError = true)]

[return: MarshalAs(UnmanagedType.Bool)]

public static extern bool GetClassName(

[In]IntPtr hWnd,

[MarshalAs(UnmanagedType.VBByRefStr)]ref string IpClassName,

[In]int nMaxCount

);

[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)]

[return: MarshalAs(UnmanagedType.SysInt)]

public static extern IntPtr WindowFromPoint(

[In]Point Point

);

public const int SMTO_ABORTIFHUNG = 2;

public readonly static int WM_HTML_GETOBJECT = RegisterWindowMessage("WM_HTML_GETOBJECT");

public readonly static Guid IID_IHTMLDocument = new Guid("626fc520-a41e-11cf-a731-00a0c9082637");

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值