welcome to Qijie's Blog 薛其杰

Using C# language to call windows API, in following codes we mainly used methods located in user32.dll , so we firstly should create a method in C# that will mapping the corresponding method in user32.dll. in these codes, you will see:

1.  to get a window handler

2. to get a control in the window

3.  to get the control text

4. to click a mouse left button in the current position

5.  to invoke a button just same as user click on it

 

 

    public class UITest
    {
        /// <summary>
        
/// To Get a window handler by window caption(Text)
        
/// </summary>
        
/// <param name="caption">window's catpoin</param>
        
/// <param name="delay">set delay time ; which may not find window because of window not completely loaded</param>
        
/// <param name="maxTries">maximum tries times</param>
        
/// <returns>a window handler</returns>
        public static IntPtr FindTopLevelWindow(string caption, int delay, int maxTries)
        {
            IntPtr mwh = IntPtr.Zero;
            bool formFound = false;
            int attempts = 0;

            do
            {
                mwh = FindWindow(null, caption);
                if (mwh == IntPtr.Zero)
                {
                    Thread.Sleep(delay);
                    attempts++;
                }
                else
                {
                    formFound = true;
                }
            } while (attempts < maxTries && !formFound);

            return mwh;
        }

        /// <summary>
        
/// To get control handler by control caption(Text)
        
/// </summary>
        
/// <param name="hwndParent"></param>
        
/// <param name="caption"></param>
        
/// <returns>a control handler</returns>
        public static IntPtr FindControlByCaption(IntPtr hwndParent, string caption)
        {
            if (hwndParent == IntPtr.Zero)
                return IntPtr.Zero;
            IntPtr result = IntPtr.Zero;
            result = FindWindowEx(hwndParent, IntPtr.Zero, null, caption);
            return result;
        }

        /// <summary>
        
/// To Get a control by Index, you can calculate it's index using Spy++
        
/// </summary>
        
/// <param name="hwndParent">parent handler</param>
        
/// <param name="index">index in parent handler</param>
        
/// <returns>a control hander</returns>
        public static IntPtr FindControlByIndex(IntPtr hwndParent, int index)
        {
            if (hwndParent == IntPtr.Zero)
                return IntPtr.Zero;
            if (index == 0)
                return hwndParent;
            else
            {
                int ct = 0;
                IntPtr result = IntPtr.Zero;
                do
                {
                    result = FindWindowEx(hwndParent, result, nullnull);
                    if (result != IntPtr.Zero)
                        ct++;
                }
                while (ct < index && result != IntPtr.Zero);

                return result;
            }
        }

        /// <summary>
        
/// To click on a button or something like that
        
/// </summary>
        
/// <param name="hControl">control to click on</param>
        public static void ClickOn(IntPtr hControl)
        {
            if (hControl == IntPtr.Zero)
                return;
            uint WM_LBUTTONDOWN = 0x0201;
            uint WM_LBUTTONUP = 0x0202;
            PostMessage1(hControl, WM_LBUTTONDOWN, 00);
            PostMessage1(hControl, WM_LBUTTONUP, 00);
        }

        /// <summary>
        
/// Close the window
        
/// </summary>
        
/// <param name="hControl"></param>
        public static void CloseWindow(IntPtr hControl)
        {
            if (hControl == IntPtr.Zero)
                return;
            uint WM_CLOSE = 0x0010;
            PostMessage1(hControl, WM_CLOSE, 00);
        }
        /// <summary>
        
/// send one char to an editable control
        
/// </summary>
        
/// <param name="hControl">an editable control</param>
        
/// <param name="c">one char</param>
        public static void SendChar(IntPtr hControl, char c)
        {
            if (hControl == IntPtr.Zero)
                return;
            uint WM_CHAE = 0x0102;
            SendMessage1(hControl, WM_CHAE, c, 0);
        }

        /// <summary>
        
/// Fill in a string in an Editable control like textbox
        
/// </summary>
        
/// <param name="hControl">an editable control</param>
        
/// <param name="s">a string</param>
        public static void SendString(IntPtr hControl, string s)
        {
            foreach (char c in s)
            {
                SendChar(hControl, c);
            }
        }

        /// <summary>
        
/// To get the display text of control
        
/// </summary>
        
/// <param name="hControl">a control handler</param>
        
/// <returns>text string</returns>
        public static string GetControlText(IntPtr hControl)
        {
            if (hControl == IntPtr.Zero)
                return "Control Not Find!";
            uint WM_GETTEXT = 0x000D;
            uint WM_GETTEXTLENGTH = 0x000E;
            int textLength = 0;
            string result = null;
            textLength = SendMessage5(hControl, WM_GETTEXTLENGTH, 00);
            if (textLength == 0)
                return "Control Text is empty";
            //if we use textLength as wParam, we will get the length of the older text for this control
            byte[] buffer = new byte[256];
            int numFetched = SendMessage3(hControl, WM_GETTEXT, 256, buffer);
            result = System.Text.Encoding.Unicode.GetString(buffer);
            if (result != null)
                return result;
            else
                return "Failed to Get Text";
        }

        /// <summary>
        
/// To check if the specified text was contained in this list box
        
/// </summary>
        
/// <param name="hControl">list box handler</param>
        
/// <param name="itemText"></param>
        
/// <returns>return true if text was contained</returns>
        public static bool IsListBoxContainItem(IntPtr hControl, string itemText)
        {
            if (hControl == IntPtr.Zero)
                return false;
            uint LB_FINDSTRING = 0x018F;
            bool isFound = false;
            int result = -1;
            result = SendMessage4(hControl, LB_FINDSTRING, -1, itemText);
            if (result >= 0)
                isFound = true;
            else
                isFound = false;
            return isFound;

        }

        //Menu
        public static void SelectMenu(IntPtr hwForm, int menuID)
        {
            uint WM_COMMAND = 0x0111;
            SendMessage2(hwForm, WM_COMMAND, menuID, IntPtr.Zero);
        }

        //P/Invoke
        [DllImport("user32.dll", EntryPoint = "FindWindow", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        //hwndChildAfter default is IntPtr.Zero(Find from all controls)
        [DllImport("user32.dll", EntryPoint = "FindWindowEx", CharSet = CharSet.Auto)]
        public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAter, string lpszClass, string lpszWindow);

        //used for sending command "WM_CHAR"
        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
        static extern void SendMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);

        //Used for sending command "WM_COMMAND"
        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
        static extern void SendMessage2(IntPtr hWnd, uint Msg, int wParam, IntPtr lParam);

        //Used for sending command "WM_LBUTTONDOWN" and "WM_LBUTTONUP"
        [DllImport("user32.dll", EntryPoint = "PostMessage", CharSet = CharSet.Auto)]
        static extern void PostMessage1(IntPtr hWnd, uint Msg, int wParam, int lParam);

        //Used for sending command "WM_GETTEXT"
        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
        static extern int SendMessage3(IntPtr hWndControl, uint Msg, int wParam, byte[] lParam);

        //Used for sending command "LB_FINDSTRING"
        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
        static extern int SendMessage4(IntPtr hWnd, uint Msg, int wParam, string lParam);

        //Used for sending command "WM_GETTEXTLENGTH"
        [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
        static extern int SendMessage5(IntPtr hWnd, uint Msg, int wParam, int lParam);

        [DllImport("user32.dll", EntryPoint = "GetMenu", CharSet = CharSet.Auto)]
        public static extern IntPtr GetMenu(IntPtr hWnd);

        [DllImport("user32.dll", EntryPoint = "GetSubMenu", CharSet = CharSet.Auto)]
        public static extern IntPtr GetSubMenu(IntPtr hWnd, int nPos);

        [DllImport("user32.dll", EntryPoint = "GetMenuItemID", CharSet = CharSet.Auto)]
        public static extern int GetMenuItemID(IntPtr hMenu, int nPos);



        //Test used in mouse_event
        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        internal static extern IntPtr GetMessageExtraInfo();

        [DllImport("user32.dll")]
        internal static extern bool GetCursorPos(ref Point lpPoint);

        [DllImport("user32.dll")]
        internal static extern bool SetCursorPos(int X, int Y);

        [DllImport("user32.dll", EntryPoint = "mouse_event", CharSet = CharSet.Auto)]
        static extern void mouse_event(uint command, int x, int y, int dwdata, IntPtr dwExtraInfo);

        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern uint RegisterWindowMessage(string lpString);

        [DllImport("oleacc.dll", PreserveSig = false)]
        [return: MarshalAs(UnmanagedType.Interface)]
        public static extern object ObjectFromLresult(UIntPtr lResult, [MarshalAs(UnmanagedType.LPStruct)] Guid refiid, IntPtr wParam);


        [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
        public static extern IntPtr SendMessageTimeout(IntPtr hWnd, uint Msg, UIntPtr wParam, IntPtr lParam, SendMessageTimeoutFlags fuFlags, uint uTimeout, out UIntPtr lpdwResult);

        public enum SendMessageTimeoutFlags :
        uint
        {
            SMTO_NORMAL = 0x0000,
            SMTO_BLOCK = 0x0001,
            SMTO_ABORTIFHUNG = 0x0002,
            SMTO_NOTIMEOUTIFNOTHUNG = 0x0008
        }


        /// <summary>
        
/// Click left button on the Point(X, Y)
        
/// </summary>
        
/// <param name="x"></param>
        
/// <param name="y"></param>
        public static void ClickOnPosition(int x, int y)
        {
            uint MOUSEEVENTF_LEFTDOWN = 0x0002;
            uint MOUSEEVENTF_LEFTUP = 0x0004;
            mouse_event(MOUSEEVENTF_LEFTDOWN, x, y, 0, GetMessageExtraInfo());
            mouse_event(MOUSEEVENTF_LEFTUP, x, y, 0, GetMessageExtraInfo());
        }

        /// <summary>
        
/// Move Cursor
        
/// </summary>
        
/// <param name="x">X direction Increment</param>
        
/// <param name="y">Y direction Increment</param>
        public static void MoveCursor(int x, int y)
        {
            uint MOUSEEVENTF_MOVE = 0x0001;
            mouse_event(MOUSEEVENTF_MOVE, x, y, 0, GetMessageExtraInfo());

        }

        /// <summary>
        
/// Click on Current cursor position
        
/// </summary>
        public static void ClickOnCurrentPosition()
        {
            try
            {
                System.Drawing.Point defPnt = new System.Drawing.Point();
                GetCursorPos(ref defPnt);

                ClickOnPosition(defPnt.X, defPnt.Y);
                Thread.Sleep(1000);
            }
            catch { }
        }
    }

 

 

posted on 2011-08-18 07:59  零点零一  阅读(543)  评论(0编辑  收藏  举报