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");
时间: 2024-10-26 00:23:22

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

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

有时候你需要后台获取ie浏览器 鼠标所在位置的元素坐标,然而你使用屏幕坐标是不可行的 所以我们需要把坐标转换成浏览器内坐标 然后再通过elementFromPoint获取网页成员. private void tmrWatcher_Tick(object sender, EventArgs e) { IntPtr hWnd = WindowFromPoint(MousePosition); dynamic document = GetHtmlDocumentByHandle(hWnd); if (

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

1 #!/usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # @Date : 2017-08-30 20:38:23 4 # @Author : EnderZhou ([email protected]) 5 # @Link : http://www.cnblogs.com/enderzhou/ 6 # @Version : $Id$ 7 8 import requests 9 from bs4 import BeautifulSoup as bs

c# asp.net 鼠标改变控件坐标位置,更改控件坐标,注册表保存读取,打印,查找局域网内打印机等等收集

界面虽然被我弄的很难看,但功能还可以 里边注册表的路径自己设置一下,或者加一个创建注册表的语句,不然会报错 前台: Html代码   <%@ Page Language="C#" AutoEventWireup="true"  CodeFile="FPSZ.aspx.cs" Inherits="_Default" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML

鼠标参数,获取鼠标在网页中的坐标

1. 事件对象 event 标准浏览器 传递给响应函数 IE 把 event 事件对象作为全局对象 window 的一个属性 2. 浏览器滚动条高度 标准浏览器 使用 documen.documentElement.scrollLeft    documen.documentElement.scrollTop Safari 等浏览器 使用 window.pageXOffset    window.pageYOffset 没有 doctype 声明的页面 document.body.scrollL

0187 案例:获取鼠标在盒子内的坐标

我们在盒子内点击,想要得到鼠标距离盒子左右的距离. 首先得到鼠标在页面中的坐标(e.pageX, e.pageY) 其次得到盒子在页面中的距离 ( box.offsetLeft, box.offsetTop) 用鼠标距离页面的坐标减去盒子在页面中的距离,得到 鼠标在盒子内的坐标 如果想要移动一下鼠标,就要获取最新的坐标,使用鼠标移动 var box = document.querySelector('.box'); box.addEventListener('mousemove', functi

抓取网页中的内容、如何解决乱码问题、如何解决登录问题以及对所采集的数据进行处理显示的过程

本文主要介绍如何抓取网页中的内容.如何解决乱码问题.如何解决登录问题以及对所采集的数据进行处理显示的过程.效果如下所示: 1.下载网页并加载至HtmlAgilityPack 这里主要用WebClient类的DownloadString方法和HtmlAgilityPack中HtmlDocument类LoadHtml方法来实现.主要代码如下. var url = page == 1 ? "http://www.cnblogs.com/" : "http://www.cnblogs

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

网络爬虫第一个要面临的问题,就是如何抓取网页,抓取其实很容易,没你想的那么复杂,一个开源HtmlUnit包,4行代码就OK啦,例子如下: 1 2 3 4 final WebClient webClient=new WebClient(); final HtmlPage page=webClient.getPage("http://www.yanyulin.info"); System.out.println(page.asText()); webClient.closeAllWindo

[Ruby]使用Ruby抓取网页及加工处理

并不是专业做网页抓取的爬虫的,只是之前在一个做的挺烂的网站上帮人刷票起步逐渐学习了网页抓取的工具.最初的时候是用Python的urllib2,拿到网页当文本处理,后来才在论坛上看到有BeautifulSoap这种级别的神器,Python处理起这种来实在是方便,可惜后来我遇到了Ruby及Rails,从此移情别恋,乃至读了Metaprogramming Ruby后更是喜欢的不要不要的.最近工作压力不大,闲来无事便想抓取一下股市的一些数据.首先遇到的一个问题便是从哪里拿到上市和深市所有的股票代码,即便

生成器的应用,爬取网页信息

#需求:生成器的应用 #然后每次g.send(url),打印页面内容,利用g可以无限send 1 from urllib.request import urlopen #导入爬虫模块 2 def get(): 3 while True: 4 url = yield #将函数改成协程函数 5 print(urlopen(url).read()) #打印爬取网页的结果 6 7 g = get() #将函数改成生成器 8 next(g) #初始化生成器 9 g.send("http://www.bai