[C#] Win32 改變開啟的IE網址並且瀏覽

2017-07-07

這範例的目的主要是打開所有的Internet Explorer 並且模擬輸入網址並且按下Enter 進行瀏覽,這邊是成功後主要畫面
Image 109
為何有這需求,就剛好公司專案要用到,順便筆記一下,給之後需要的人..
首先,要有兩個步驟,第一步,我們得找到所有開啟的IE

1. C# Win32 的使用部分

        [DllImport("user32.dll")]
        static extern int EnumWindows(CallbackDef callback, int lParam);

        delegate bool CallbackDef(int hWnd, int lParam);

        [DllImport("user32.dll")]
        static extern int GetWindowText(int hWnd, StringBuilder text, int count);

相關參考:
EnumWindows: https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms633497(v=vs.85).aspx
GetWindowText : https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms633520(v=vs.85).aspx

2. 呼叫取得所有開啟 IE  的 Handler :

        /// <summary>
        /// 找尋所有開啟的IE
        /// </summary>
        /// <param name="hWnd"></param>
        /// <param name="lParam"></param>
        /// <returns></returns>
        private bool SearchIE(int hWnd, int lParam)
        {

            string mystring;

            StringBuilder text = new StringBuilder(255);
            GetWindowText(hWnd, text, 255);

            mystring = text.ToString();

            //確認抓到IE
            if (mystring.Contains("Internet Explorer"))
            {
                IEIntPtrs.Add(hWnd);
            }
            return true;

        }

            IEIntPtrs.Clear();
            CallbackDef callback = new CallbackDef(SearchIE);
            EnumWindows(callback, 0);


3. 因為抓到之後,必須要抓到裡面的輸入網址的Edit 的部分

Image 110
所以必須要透過 Win32 的 EnumWindowProc 和 EnumChildWindows 找到下面所有的Handler ,然後用 GetClassName 判斷他是不是 Edit Control

        [DllImport("user32")]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);

        private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);


        [DllImport("USER32.DLL")]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder text, int nMaxCount);
        
        const int WM_KEYDOWN = 0x100;
        
        [DllImport("USER32.DLL")]
        public static extern bool SetForegroundWindow(IntPtr hWnd);


        //所有 IE 的Handler
        private List<int> IEIntPtrs = new List<int>();




        /// <summary>
        /// 取的該Handler 下的子Handler
        /// </summary>
        /// <param name="targetHandler"></param>
        /// <returns></returns>
        public List<IntPtr> GetAllChildHandles(IntPtr targetHandler)
        {
            List<IntPtr> childHandles = new List<IntPtr>();

            GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles);
            IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);

            try
            {
                EnumWindowProc childProc = new EnumWindowProc(EnumWindow);

                EnumChildWindows(targetHandler, childProc, pointerChildHandlesList);
            }
            finally
            {
                gcChildhandlesList.Free();
            }

            return childHandles;
        }

參考文件:
EnumChildWindows :https://msdn.microsoft.com/en-us/library/windows/desktop/ms633494(v=vs.85).aspx
GetClassName :https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms633582(v=vs.85).aspx
SetForegroundWindow : https://msdn.microsoft.com/zh-tw/library/windows/desktop/ms633539(v=vs.85).aspx

呼叫的部分 :
            foreach (var ieHandler in IEIntPtrs)
            {
                //取的抓到IE下 所有的Handler
                var childHandlers = GetAllChildHandles((IntPtr)ieHandler);

                foreach (var childHandler in childHandlers)
                {

                    StringBuilder objType = new StringBuilder(255);
                    GetClassName(childHandler, objType, 255);
                    if (objType.ToString() == "Edit")
                    {
                      
                        SetForegroundWindow((IntPtr)childHandler);
                        SendKeys.Send("http://no2don.blogspot.com\r\n");
                    }

                }
            }

結果:

Image 109

Source Code:
https://github.com/donma/ReferIEUrl


當麻許的超技八 2014 | Donma Hsu Design.