C# 根據滑鼠座標取網頁內成員座標.ie,

來源:互聯網
上載者:User

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");

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.