// 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; }