当前位置: 代码迷 >> C# >> C# 依据鼠标坐标取网页内成员坐标.ie
  详细解决方案

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

热度:19   发布时间:2016-05-05 03:26:11.0
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");

  相关解决方案