FindWindowEx on Windows Mobile: not supported…

… so how can I grab the handle of a particular child window, considering that FindWindow retrieves all top-level windows? I worked on this when writing a previous post of mine, and got a wonderful comment from Lionel (thanks again smile_regular). Today I had to re-use that code, and found that something was missing and also the code required some enhancements… so here it is!

 

         private static IntPtr FindChildWindow(string strChildClassName, string strChildWindowCaption, IntPtr hWndTopLevel)
        {
            IntPtr hwndCur = IntPtr.Zero;
            hwndCur = GetWindow(hWndTopLevel, (uint)GetWindowFlags.GW_CHILD);
            return RecurseFindWindow(strChildClassName, strChildWindowCaption, hwndCur);
        }

        private static bool m_bFound = false;

        private static IntPtr RecurseFindWindow(string strChildClassName, string strChildWindowCaption, IntPtr hWndParent)
        {
            //bool bFound = false;
            IntPtr hwndCur = IntPtr.Zero;
            char[] chArWindowClass = new char[32];
            if (hWndParent == IntPtr.Zero)
                return IntPtr.Zero;
            else
            {
                //check if we got the searched class name
                GetClassName(hWndParent, chArWindowClass, 256);
                string strWndClass = new string(chArWindowClass);
                strWndClass = strWndClass.Substring(0, strWndClass.IndexOf('\0'));
                if (strWndClass.ToLower() == strChildClassName.ToLower())
                {
                    //check if we got the searched window name
                    int length = GetWindowTextLength(hWndParent);
                    StringBuilder sb = new StringBuilder(length + 1);
                    GetWindowText(hWndParent, sb, sb.Capacity);
                    m_bFound = (sb.ToString().ToLower() == strChildWindowCaption.ToLower());
                    if (m_bFound)
                        return hWndParent;
                }
                else
                {
                    //recurse into first child
                    IntPtr hwndChild = GetWindow(hWndParent, (uint)GetWindowFlags.GW_CHILD);
                    if (hwndChild != IntPtr.Zero)
                        hwndCur = RecurseFindWindow(strChildClassName, strChildWindowCaption, hwndChild);
                    if (!m_bFound)
                    {
                        IntPtr hwndBrother = IntPtr.Zero;
                        //enumerate each brother windows and recurse into
                        do
                        {
                            hwndBrother = GetWindow(hWndParent, (uint)GetWindowFlags.GW_HWNDNEXT);
                            hWndParent = hwndBrother;
                            if (hwndBrother != IntPtr.Zero)
                            {
                                hwndCur = RecurseFindWindow(strChildClassName, strChildWindowCaption, hwndBrother);
                                if (m_bFound)
                                    break;
                            }
                        }
                        while (hwndBrother != IntPtr.Zero);
                    }
                }
                return hwndCur;
            }
        }


        [DllImport("coredll.dll", SetLastError = true)]
        private static extern IntPtr FindWindow(string _ClassName, string _WindowName);

        [DllImport("coredll.dll", SetLastError = true)]
        private static extern IntPtr GetWindow(IntPtr hwnd, uint relationship);

        [DllImport("coredll.dll", SetLastError = true)]
        private static extern IntPtr SendMessage(IntPtr hWnd, int msg, int wParam, int lParam);

        [DllImport("coredll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern int GetClassName(IntPtr hwnd, char[] windowClass, int maxText);

        [DllImport("coredll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern int GetWindowTextLength(IntPtr hWnd);

        [DllImport("coredll.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount);

        [Flags]
        private enum GetWindowFlags
        {
            GW_HWNDFIRST = 0,
            GW_HWNDLAST = 1,
            GW_HWNDNEXT = 2,
            GW_HWNDPREV = 3,
            GW_OWNER = 4,
            GW_CHILD = 5,
        }

 

Cheers,

~raffaele