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

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

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

  1. private void tmrWatcher_Tick(object sender, EventArgs e)
  2. {
  3. IntPtr hWnd = WindowFromPoint(MousePosition);
  4. dynamic document = GetHtmlDocumentByHandle(hWnd);
  5. if (document != null)
  6. {
  7. Rectangle r = GetHtmlElementPoint(hWnd, MousePosition, document); // 根据鼠标坐标取网页成员坐标
  8. Marshal.FinalReleaseComObject(document);
  9. Console.WriteLine(r.X + ":" + r.Y + ":" + r.Width + ":" + r.Height);
  10. }
  11. }

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

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

  1. public static object GetComObjectByHandle(int Msg, Guid riid, IntPtr hWnd)
  2. {
  3. object _ComObject;
  4. int lpdwResult = 0;
  5. if (!SendMessageTimeout(hWnd, Msg, 0, 0, SMTO_ABORTIFHUNG, 1000, ref lpdwResult))
  6. return null;
  7. if (ObjectFromLresult(lpdwResult, ref riid, 0, out _ComObject))
  8. return null;
  9. return _ComObject;
  10. }
  11.  
  12. public object GetHtmlDocumentByHandle(IntPtr hWnd)
  13. {
  14. string buffer = new string('\0', 24);
  15. GetClassName(hWnd, ref buffer, 25);
  16. if (buffer != "Internet Explorer_Server")
  17. return null;
  18. return GetComObjectByHandle(WM_HTML_GETOBJECT, IID_IHTMLDocument, hWnd);
  19. }

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

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

  1. public Rectangle GetHtmlElementPoint(IntPtr hWnd, Point point, dynamic document)
  2. {
  3. if (document == null && hWnd != IntPtr.Zero)
  4. return Rectangle.Empty;
  5. ScreenToClient(hWnd, ref point);
  6. dynamic element = document.elementFromPoint(point.X, point.Y);
  7. if (element == null) return Rectangle.Empty;
  8. try
  9. {
  10. Rectangle o = new Rectangle()
  11. {
  12. Y = element.offsetTop,
  13. X = element.offsetLeft,
  14. Width = element.offsetWidth,
  15. Height = element.offsetHeight
  16. };
  17. while (element.offsetParent != null)
  18. {
  19. element = element.offsetParent;
  20. o.Y += element.offsetTop;
  21. o.X += element.offsetLeft;
  22. }
  23. return o;
  24. }
  25. catch
  26. {
  27. return Rectangle.Empty;
  28. }
  29. }

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

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

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

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

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

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

  1. [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)]
  2. public static extern bool ScreenToClient(IntPtr hWnd, ref Point lpPoint);
  3.  
  4. [DllImport("user32.dll", SetLastError = true)]
  5. [return: MarshalAs(UnmanagedType.Bool)]
  6. public static extern bool GetClassName(
  7. [In]IntPtr hWnd,
  8. [MarshalAs(UnmanagedType.VBByRefStr)]ref string IpClassName,
  9. [In]int nMaxCount
  10. );
  11.  
  12. [DllImport("oleacc.dll", SetLastError = true)]
  13. [return: MarshalAs(UnmanagedType.Bool)]
  14. public static extern bool ObjectFromLresult(
  15. [In]int lResult,
  16. [In]ref Guid riid,
  17. [In]int wParam,
  18. [Out, MarshalAs(UnmanagedType.IUnknown)]out object ppvObject
  19. );
  20.  
  21. [DllImport("user32.dll", SetLastError = true)]
  22. [return: MarshalAs(UnmanagedType.I4)]
  23. public static extern int RegisterWindowMessage(
  24. [In]string lpString
  25. );
  26.  
  27. [DllImport("user32.dll", EntryPoint = "SendMessageTimeoutA", SetLastError = true)]
  28. [return: MarshalAs(UnmanagedType.Bool)]
  29. public static extern bool SendMessageTimeout(
  30. [In]IntPtr MSG,
  31. [In]int hWnd,
  32. [In]int wParam,
  33. [In]int lParam,
  34. [In]int fuFlags,
  35. [In]int uTimeout,
  36. [In, Out]ref int lpdwResult
  37. );
  38.  
  39. [DllImport("user32.dll", SetLastError = true)]
  40. [return: MarshalAs(UnmanagedType.SysInt)]
  41. public static extern IntPtr WindowFromPoint(
  42. [In]Point Point
  43. );
  44.  
  45. public const int SMTO_ABORTIFHUNG = 2;
  46.  
  47. public readonly static int WM_HTML_GETOBJECT = RegisterWindowMessage("WM_HTML_GETOBJECT");
  48. public readonly static Guid IID_IHTMLDocument = new Guid("626fc520-a41e-11cf-a731-00a0c9082637");

C# 依据鼠标坐标取网页内成员坐标.ie的更多相关文章

  1. Python3爬虫----爬取网页内的图片

    无聊把公司内网爬了一遍. https://github.com/gig886/Python/tree/master/爬虫

  2. python 爬取网页内的代理服务器列表(需调整优化)

    #!/usr/bin/env python # -*- coding: utf-8 -*- # @Date : 2017-08-30 20:38:23 # @Author : EnderZhou (z ...

  3. 利用Python爬取网页图片

    最近几天,研究了一下一直很好奇的爬虫算法.这里写一下最近几天的点点心得.下面进入正文: 你可能需要的工作环境: Python 3.6官网下载 我们这里以sogou作为爬取的对象. 首先我们进入搜狗图片 ...

  4. [转载]爬虫的自我解剖(抓取网页HtmlUnit)

    网络爬虫第一个要面临的问题,就是如何抓取网页,抓取其实很容易,没你想的那么复杂,一个开源HtmlUnit包,4行代码就OK啦,例子如下: 1 2 3 4 final WebClient webClie ...

  5. [python] 常用正则表达式爬取网页信息及分析HTML标签总结【转】

    [python] 常用正则表达式爬取网页信息及分析HTML标签总结 转http://blog.csdn.net/Eastmount/article/details/51082253 标签: pytho ...

  6. HTML-图片热点、网页内嵌、网页拼接、快速切图

    图片热点 规划出图片上的一个区域,可以做出超链接,直接点击图片区域就可以完成跳转的效果.与图片链接不同,热点是图片上的某一个区域或多个区域. 我们用魔兽世界图片来做一个图片热点,点击logo.区域和不 ...

  7. 爬虫的自我解剖(抓取网页HtmlUnit)

    网络爬虫第一个要面临的问题,就是如何抓取网页,抓取其实很容易,没你想的那么复杂,一个开源`HtmlUnit`包,4行代码就OK啦,例子如下: final WebClient webClient=new ...

  8. python分布式抓取网页

    呵呵,前两节好像和python没多大关系..这节完全是贴代码, 这是我第一次写python,很多地方比较乱,主要就看看逻辑流程吧. 对于编码格式确实搞得我头大..取下来页面不知道是什么编码,所以先找c ...

  9. HTML5绘制矩形和圆形并且还有获取在这个图层内的坐标的思路和代码 - feilong_12的专栏 - 博客频道 - CSDN.NET

    body{ font-family: "Microsoft YaHei UI","Microsoft YaHei",SimSun,"Segoe UI& ...

随机推荐

  1. 毕向东_Java基础视频教程第20天_IO流(5~6)

    第20天-05-IO流(文件列表一) static File[] listRoots() List the available filesystem roots. String[] list() Re ...

  2. mysql错误:Statement violates GTID consistency

    在MYSQL中,执行建表语句时CREATE TABLE  aaaa  AS SELECT * FROM menu;  报: 错误代码: 1786Statement violates GTID cons ...

  3. vuejs plus d3

    vuejs 是一个数据驱动视图的前端框架,一切皆可以作为可重用的组件加以使用. d3则是数据可视化javascript库,如何将二者的长处相结合是一个挑战. https://tyronetudehop ...

  4. F5 IIS Log获取客户端源IP

    1.配置F5启用X-Forwarded-For方法: 1:Local Traffic-Profiles-Http-改"Insert XForwarded For"为Enable 2 ...

  5. Javascript 中 true 和 false

    "" == false // true "0" == false // true "" == "0" //false 以 ...

  6. Linux学习---Linux安装ftp组件

    1 安装vsftpd组件 安装完后,有/etc/vsftpd/vsftpd.conf 文件,是vsftp的配置文件. [root@bogon ~]# yum -y install vsftpd 2 添 ...

  7. 通过Windows Server 2008 R2建立iSCSI存储

    名词解释:iSCSI技术是一种由IBM公司研究开发的,是一个供硬件设备使用的可以在IP协议的上层运行的SCSI指令集,这种指令集合可以实现在IP网络上运行 SCSI协议,使其能够在诸如高速千兆以太网上 ...

  8. lvs安装文档

    安装lvs应用模块 1.安装依赖包: [root@client lvs]# yum -y install ipvs* 2.验证本机ip_vs模块是否加载 [root@client lvs]# -.el ...

  9. HashMap源代码解析

    HashMap原理剖析 之前有看过别人的HashMap源代码的分析,今天尝试自己来分析一波,纯属个人愚见.听一些老的程序员说过,当别人跟你说用某样技术到项目中去,而你按照别人的想法实现了的时候,你只能 ...

  10. ubuntu卸载virtualbox

    本想在ubuntu下virtualbox,可惜出错了,需要卸载后再安装,只能百度拼凑后再安装: 1.首先是执行删除命令:sudo apt-get remove virtualbox*( 这样就不用去查 ...