예제 #1
0
        // OnEventSystemCaptureEnd - process an EventSystemCaptureEnd WinEvent.
        private void OnEventSystemCaptureEnd(int eventId, IntPtr hwnd, int idObject, int idChild, uint eventTime)
        {
            // Deal only with Combolbox dropdowns...
            if (Accessible.IsComboDropdown(hwnd))
            {
                SafeNativeMethods.GUITHREADINFO guiThreadInfo = new SafeNativeMethods.GUITHREADINFO();

                if (!Misc.GetGUIThreadInfo(0, ref guiThreadInfo))
                {
                    return;
                }

                Accessible acc = Accessible.Create(guiThreadInfo.hwndFocus, UnsafeNativeMethods.OBJID_CLIENT, 0);
                if (acc == null)
                    return;

                HandleFocusChange(hwnd, acc, idObject, idChild, eventTime);
            }
        }
        // determine focus - taking menu mode into account
        private static IRawElementProviderFragment GetFocusedProvider()
        {
            // Menus are special as far as focus goes - they get a special type of keyboard
            // capture from USER32 that is outside of the regular focus mechanism.
            // Therefore they have to be dealt with specially - regular drilling won't work.
            SafeNativeMethods.GUITHREADINFO gti = new SafeNativeMethods.GUITHREADINFO();
            if (Misc.GetGUIThreadInfo(0, ref gti))
            {
                if ((gti.dwFlags & SafeNativeMethods.GUI_INMENUMODE) != 0
                    || (gti.dwFlags & SafeNativeMethods.GUI_SYSTEMMENUMODE) != 0
                    || (gti.dwFlags & SafeNativeMethods.GUI_POPUPMENUMODE) != 0)
                {
                    // We're in menu mode - see if there's a registered menu focus handler:
                    IRawElementProviderSimple provider = ProxyManager.GetUser32FocusedMenuProvider(gti.hwndMenuOwner);
                    if (provider != null)
                    {
                        Debug.Assert(provider is IRawElementProviderFragment, "Expecting a fragment provider");
                        return provider as IRawElementProviderFragment;
                    }
                }
                else
                {
                    return Wrap(gti.hwndFocus);
                }
            }

            return null;
        }
        // detect if we're in the menu mode
        private static bool InMenuMode()
        {
            SafeNativeMethods.GUITHREADINFO gui = new SafeNativeMethods.GUITHREADINFO();

            if (!Misc.GetGUIThreadInfo(0, ref gui))
            {
                return false;
            }
            return (SafeNativeMethods.GUI_INMENUMODE == (gui.dwFlags & SafeNativeMethods.GUI_INMENUMODE));
        }
        // Get current focused HWND
        private static NativeMethods.HWND GetFocusedWindow()
        {
            SafeNativeMethods.GUITHREADINFO gti = new SafeNativeMethods.GUITHREADINFO();

            if (!Misc.GetGUIThreadInfo(0, ref gti))
            {
                return NativeMethods.HWND.NULL;
            }

            return gti.hwndFocus;
        }
        object IRawElementProviderSimple.GetPropertyValue(int propertyId)
        {
            AutomationProperty idProp = AutomationProperty.LookupById(propertyId);
            if (idProp == AutomationElement.AutomationIdProperty)
            {
                // Only child windows have control ids - top-level windows have HMENUs instead
                // So first check that this is not top-level
                if(IsTopLevelWindow(_hwnd))
                {
                    return null;
                }

                int id = Misc.GetWindowLong(_hwnd, SafeNativeMethods.GWL_ID);
                // Ignore controls with no id, or generic static text (-1)
                if( id == 0 || id == -1 )
                {
                    return null;
                }

                // Return string representation of id...
                return id.ToString(CultureInfo.InvariantCulture);
            }
            else if (idProp == AutomationElement.ClassNameProperty)
            {
                return ProxyManager.GetClassName( _hwnd );
            }
            else if (idProp == AutomationElement.NameProperty)
            {
                // For now, assume window text is same as name.
                // Not true for edits, combos, and other controls that use labels,
                // but will deal with that later.
                IntPtr len = Misc.SendMessageTimeout( _hwnd, UnsafeNativeMethods.WM_GETTEXTLENGTH, IntPtr.Zero, IntPtr.Zero );
                int ilen = len.ToInt32();

                if (ilen == 0)
                {
                    return "";
                }

                // Length passes to SendMessage includes terminating NUL
                StringBuilder str = new StringBuilder( ilen + 1 );
                if (Misc.SendMessageTimeout(_hwnd, UnsafeNativeMethods.WM_GETTEXT, new IntPtr(ilen + 1), str) == IntPtr.Zero)
                {
                    str[0] = '\0';
                }

                // get rid of any & used for shortcut keys
                return Misc.StripMnemonic(str.ToString());
            }
            else if (idProp == AutomationElement.IsEnabledProperty)
            {
                return IsWindowReallyEnabled( _hwnd );
            }
            else if (idProp == AutomationElement.ProcessIdProperty)
            {
                // Get the pid of the process that the HWND lives in, not the
                // pid that this proxy lives in
                int pid;
                // GetWindowThreadProcessId does use SetLastError().  So a call to GetLastError() would be meanless.
                // Disabling the PreSharp warning.
#pragma warning suppress 6523
                if (SafeNativeMethods.GetWindowThreadProcessId(_hwnd, out pid) == 0)
                {
                    throw new ElementNotAvailableException();
                }

                return pid;
            }
            else if( idProp == AutomationElement.NativeWindowHandleProperty )
            {
                // Need to downcast to Int32, since IntPtr's are not remotable.
                return ((IntPtr) _hwnd).ToInt32();
            }
            else if (idProp == AutomationElement.HasKeyboardFocusProperty)
            {
                SafeNativeMethods.GUITHREADINFO gti = new SafeNativeMethods.GUITHREADINFO ();

                if (!Misc.GetGUIThreadInfo(0, ref gti))
                {
                    return false;
                }

                return  (gti.hwndFocus == _hwnd) || (SafeNativeMethods.IsChild(_hwnd, gti.hwndFocus));
            }
            else if (idProp == AutomationElement.FrameworkIdProperty)
            {
                return Misc.IsWindowsFormsControl(ProxyManager.GetClassName(_hwnd)) ? "WinForm" : "Win32";
            }
            else if (idProp == AutomationElement.ControlTypeProperty)
            {
                if (IsWindowPatternWindow(_hwnd))
                {
                    return ControlType.Window.Id;
                }
                else
                {
                    return ControlType.Pane.Id;
                }
            }

            return null;
        }