首页 > 代码库 > 控制其他程序1(金山词霸2009)

控制其他程序1(金山词霸2009)

基于个人需要,想控制其他程序,获取其他程序接运行结果。

具体来说,现在我想要在我的程序中控制金山词霸查询一个单词,最后能在我的程序中显示查询的结果。

 

就像把其他程序作为一个函数来调用,首先想到的是发送消息。

 

需要做到的有

1. 填入要查询的的单词

2. 单词“查词”按钮

3. 获取查询的结果并显示在程序中

 

前两步很容易做到,获取相应的控件的句柄,然后发送相应的消息就行了。

具体用到了

        /// <summary>

        /// 获取子窗体

        /// </summary>

        private void GetChildren()

        {

            Children.Clear();

            IntPtr hwnd = IntPtr.Zero;

            hwnd = User32.FindWindowEx(Wnd, hwnd, nullnull);

            while (hwnd != IntPtr.Zero) 

            {

                WindowInfo child = new WindowInfo(hwnd, this);

                Children.Add(child);

                hwnd = User32.FindWindowEx(Wnd, hwnd, nullnull);

            } 

        }

        /// <summary>

        /// 设置文本

        /// </summary>

        /// <param name="text"></param>

        public void SetText(string text)

        {

            //User32.SetWindowText(Wnd, text);

            //下面这个能够设置Edit,上面则不行

            User32.SendMessage(Wnd, Constant_WM.WM_SETTEXT, IntPtr.Zero, text);

        }

        /// <summary>

        /// 单击按钮

        /// </summary>

public void ButtonClick()

        {

            User32.SendMessage(Wnd, Constant_BM.BM_CLICK, IntPtr.Zero, "0");

        }

 

为了处理上方便,写了个WindowInfo类,封装了句柄相关的信息,内部还有个Children,形成了一个控件树,便于获取子控件。

(User32是一个封装了User32.dll里面的API函数的静态类)

 

获取界面上的主要控件:

 

protected override void GetInfo()

        {

            base.GetInfo();

            GetBtnSearch();

            TxtInput = Window.GetChildByClass("Edit");

            TxtResult = Window.GetChildByClass("Internet Explorer_Server");

        }

 

        public WindowInfo TxtInput { getset; }

        public WindowInfo BtnSearch { getset; }

        public WindowInfo TxtResult { getset; }

 

        private void GetBtnSearch()

        {

            foreach (WindowInfo child in Window.Children)

            {

                if (child.Width == 59 && child.Height == 29)

                {

                    BtnSearch = child;

                }

            }

        }

 

第三步比较麻烦,是一个Internet Explorer_Server类型的控件。

幸亏网上直接有解决方案,他们的目的是要控制IE里面的内容,我只需要获取内容,再把内容给一个WebBrowser控件就行了。

整理了一下,做成一个静态类了HtmlDocumentHelper(代码在最后),需要引用COM里面的“Microsoft HTML Object Library”。

 

最后就完成了一个XDict类,应该算是一种代理吧,用它来间接控制金山词霸。

public class XDict : ThirdTool

    {

        public XDict()

        {

            Name = "XDict";

            Path = ConfigurationManager.AppSettings["XDictPath"];

            //Init();

        }

 

        protected override void GetInfo()

        {

            base.GetInfo();

            GetBtnSearch();

            TxtInput = Window.GetChildByClass("Edit");

            TxtResult = Window.GetChildByClass("Internet Explorer_Server");

        }

 

        public WindowInfo TxtInput { getset; }

        public WindowInfo BtnSearch { getset; }

        public WindowInfo TxtResult { getset; }

 

        private void GetBtnSearch()

        {

            foreach (WindowInfo child in Window.Children)

            {

                if (child.Width == 59 && child.Height == 29)

                {

                    BtnSearch = child;

                }

            }

        }

 

        public string Search(string word,bool getResult=true)

        {

            if (Process == nullreturn null;

            string html = "";

            if (TxtInput == null) GetInfo(); 

            if (TxtInput == nullreturn null;

            TxtInput.SetText(word);

            if (BtnSearch == null) GetBtnSearch();

            if (BtnSearch == nullreturn null;

            BtnSearch.ButtonClick();

            if (getResult)

            {

                html = HtmlDocumentHelper.GetHtml(TxtResult.Wnd);

            }

            return html;

        }

    }

 

ThirdTool是负责打开程序,获取程序句柄等通用功能的类,实际上现在已经在写其他程序的代理类了。

这个技术完善的话还是比较通用的:自己做不到的,首先找开源,开源的没有或无法满足的则直接控件已有该功能的软件。嘛,估计上不了大雅之堂,只能个人玩玩。

不知道有没有这种的完善的框架了,先自己研究下,以后再找找看。

 

HtmlDocumentHelper:

public static class HtmlDocumentHelper

    {

        public const int SMTO_ABORTIFHUNG = 0x2;

        public static Guid IID_IHTMLDocument = new Guid("626FC520-A41E-11CF-A731-00A0C9082637");

        [DllImport("OLEACC.dll")]

        public static extern int ObjectFromLresult(int lResult, ref Guid riid, int wParam, ref IHTMLDocument2 ppvObject);

 

        public static IHTMLDocument2 GetIEDocument()

        {

            Process[] processes = Process.GetProcessesByName("iexplore");

            IntPtr hWnd = IntPtr.Zero;

            if (processes.Length > 1)

            {

                foreach (Process process in processes)

                {

                    if (process.MainWindowTitle != "")

                    {

                        hWnd = process.MainWindowHandle;

                    }

                }

            }

 

            return HtmlDocumentHelper.GetDocument(hWnd);

        }

 

        public static IHTMLDocument2 GetDocument(IntPtr hWnd)

        {

            IHTMLDocument2 document=new HTMLDocumentClass();

            if (hWnd != IntPtr.Zero)

            {

                //IntPtr hWnd = processes[2].MainWindowHandle;

                int lngMsg = 0;

                int lRes = 0;

 

                User32.EnumProc proc = new User32.EnumProc(EnumWindows);

                User32.EnumChildWindows(hWnd, proc, ref hWnd);

                if (!hWnd.Equals(IntPtr.Zero))

                {

                    lngMsg = User32.RegisterWindowMessage("WM_HTML_GETOBJECT");

                    if (lngMsg != 0)

                    {

                        User32.SendMessageTimeout(hWnd, lngMsg, 0, 0, SMTO_ABORTIFHUNG, 1000, ref lRes);

                        if (!(bool)(lRes == 0))

                        {

                            int hr = ObjectFromLresult(lRes, ref IID_IHTMLDocument, 0, ref document);

                            if ((bool)(document == null))

                            {

                                //MessageBox.Show("No IHTMLDocument Found!", "Warning");

                            }

                        }

                    }

                }

            }

            return document;

        }

 

        public static string GetHtml(IntPtr hWnd)

        {

            IHTMLDocument2 document = GetDocument(hWnd);

            return GetHtml(document);

        }

 

        public static string GetHtml(IHTMLDocument2 document)

        {

            string text = "";

            foreach (IHTMLElement element in document.all)

            {

                text += element.innerHTML;

            }

            return text;

        }

 

        private static int EnumWindows(IntPtr hWnd, ref IntPtr lParam)

        {

            int retVal = 1;

            StringBuilder classname = new StringBuilder(128);

            User32.GetClassName(hWnd, classname, classname.Capacity);

            /// check if the instance we have found is Internet Explorer_Server

            if ((bool)(string.Compare(classname.ToString(), "Internet Explorer_Server") == 0))

            {

                lParam = hWnd;

                retVal = 0;

            }

            return retVal;

        }

    }

 

控制其他程序1(金山词霸2009)