// Returns an item corresponding to the focused element (if there is one), or null otherwise. internal override ProxySimple GetFocus() { if (WindowsMenu.IsInSystemMenuMode()) { // Since in system menu mode try to find point on the SystemMenu WindowsTitleBar titleBar = (WindowsTitleBar)CreateNonClientChild(NonClientItem.TitleBar); if (titleBar != null) { ProxyFragment systemMenu = (ProxyFragment)titleBar.CreateTitleBarChild(WindowsTitleBar._systemMenu); if (systemMenu != null) { // need to drill down ourself, since the FragmentRoot of the System Menu Bar will // be NonClient area hence UIAutomation will not drill down ProxySimple proxy = systemMenu.GetFocus(); if (proxy != null) { return(proxy); } } } } return(base.GetFocus()); }
private static IRawElementProviderSimple CreateSystemMenu(IntPtr hwnd) { NonClientArea nonClientArea = new NonClientArea(hwnd); WindowsTitleBar titleBar = (WindowsTitleBar)nonClientArea.CreateNonClientChild(NonClientItem.TitleBar); return(titleBar.CreateTitleBarChild(WindowsTitleBar._systemMenu)); }
// Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint(int x, int y) { int hit = Misc.ProxySendMessageInt(_hwnd, NativeMethods.WM_NCHITTEST, IntPtr.Zero, NativeMethods.Util.MAKELPARAM(x, y)); switch (hit) { case NativeMethods.HTHSCROLL: { ProxyFragment ret = CreateNonClientChild(NonClientItem.HScrollBar); return(ret.ElementProviderFromPoint(x, y)); } case NativeMethods.HTVSCROLL: { ProxyFragment ret = CreateNonClientChild(NonClientItem.VScrollBar); return(ret.ElementProviderFromPoint(x, y)); } case NativeMethods.HTCAPTION: case NativeMethods.HTMINBUTTON: case NativeMethods.HTMAXBUTTON: case NativeMethods.HTHELP: case NativeMethods.HTCLOSE: case NativeMethods.HTSYSMENU: WindowsTitleBar tb = new WindowsTitleBar(_hwnd, this, 0); return(tb.ElementProviderFromPoint(x, y)); case NativeMethods.HTGROWBOX: return(CreateNonClientChild(NonClientItem.Grip)); case NativeMethods.HTBOTTOMRIGHT: return(FindGrip(x, y)); case NativeMethods.HTBOTTOMLEFT: return(FindGripMirrored(x, y)); case NativeMethods.HTMENU: return(FindMenus(x, y)); case NativeMethods.HTLEFT: case NativeMethods.HTRIGHT: case NativeMethods.HTTOP: case NativeMethods.HTTOPLEFT: case NativeMethods.HTTOPRIGHT: case NativeMethods.HTBOTTOM: case NativeMethods.HTBORDER: // We do not handle the borders so return null here and let the // HWNDProvider handle them as the whole window. return(null); default: // Leave all other cases (especially including HTCLIENT) alone... return(null); } }
private ProxySimple FindMenus(int x, int y) { if (WindowsMenu.IsInSystemMenuMode()) { // Since in system menu mode try to find point on the SystemMenu WindowsTitleBar titleBar = (WindowsTitleBar)CreateNonClientChild(NonClientItem.TitleBar); if (titleBar != null) { ProxyFragment systemMenu = (ProxyFragment)titleBar.CreateTitleBarChild(WindowsTitleBar._systemMenu); if (systemMenu != null) { // need to drill down ourself, since the FragmentRoot of the System Menu Bar will // be NonClient area hence UIAutomation will not drill down ProxySimple proxy = systemMenu.ElementProviderFromPoint(x, y); if (proxy != null) { return(proxy); } } } } else { // Not in system menu mode so it may be a Popup Menu, have a go at it ProxyFragment menu = CreateNonClientChild(NonClientItem.Menu); if (menu != null) { // need to drill down ourself, since the FragmentRoot of the MenuBar will // be NonClient area hence UIAutomation will not drill down ProxySimple proxy = menu.ElementProviderFromPoint(x, y); if (proxy != null) { return(proxy); } // We may have been on the Menu but not on a menu Item return(menu); } } return(null); }
private static void RaiseEventsOnWindow(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { ProxyFragment elw = new NonClientArea(hwnd); if (eventId == NativeMethods.EventObjectNameChange) { int style = Misc.GetWindowStyle(hwnd); if (Misc.IsBitSet(style, NativeMethods.WS_CHILD)) { // Full control names do not change. They are named by the static label. return; } else { // But the title bar name does so allow title bar proxy to procees the event. WindowsTitleBar tb = new WindowsTitleBar(hwnd, elw, 0); tb.DispatchEvents(eventId, idProp, idObject, idChild); } } elw.DispatchEvents(eventId, idProp, idObject, idChild); }
internal ProxyHwnd CreateNonClientMenu() { // child windows don't have menus int style = WindowStyle; if (!Misc.IsBitSet(style, NativeMethods.WS_CHILD)) { ProxyHwnd menuProxy = null; if (WindowsMenu.IsInSystemMenuMode()) { // Since in system menu mode try to find point on the SystemMenu WindowsTitleBar titleBar = (WindowsTitleBar)CreateNonClientChild(NonClientItem.TitleBar); if (titleBar != null) { menuProxy = (ProxyHwnd)titleBar.CreateTitleBarChild(WindowsTitleBar._systemMenu); } } else { IntPtr menu = UnsafeNativeMethods.GetMenu(_hwnd); if (menu != IntPtr.Zero) { menuProxy = new WindowsMenu(_hwnd, this, menu, WindowsMenu.MenuType.Toplevel, (int)NonClientItem.Menu); } } if (menuProxy != null) { // if this menu is not visible its really not there if (menuProxy.BoundingRectangle.Width != 0 && menuProxy.BoundingRectangle.Height != 0) { return(menuProxy); } } } return(null); }
internal override void AdviseEventRemoved(AutomationEvent eventId, AutomationProperty [] aidProps) { // we need to create the menu proxy so that the global event for menu will be listened for. // This proxy will get advise of events needed for menus ProxyHwnd menuProxy = CreateNonClientMenu(); if (menuProxy == null) { // If the window does not have a menu, it at least has a system menu. WindowsTitleBar titleBar = (WindowsTitleBar)CreateNonClientChild(NonClientItem.TitleBar); if (titleBar != null) { menuProxy = (ProxyHwnd)titleBar.CreateTitleBarChild(WindowsTitleBar._systemMenu); } } if (menuProxy != null) { menuProxy.AdviseEventRemoved(eventId, aidProps); } base.AdviseEventRemoved(eventId, aidProps); }
// Called by UIA when we're in menu mode // Note that we have to drill all the way down to an item here, UIA expects us // to return the lowest focused item. internal static IRawElementProviderSimple CreateFocusedMenuItem(IntPtr hwnd, int idChild, int idObject) { NativeMethods.GUITHREADINFO gui; if (!Misc.ProxyGetGUIThreadInfo(0, out gui)) { return null; } // The following code assumes that regardless of the type of menu mode // we're in, there's only one chain of cascaded menus present - you never // have two unrelated sets of menus present at a time. // So, we can look for *any* visible popup menu window (which could get us // half-way into a cascade chain, or at the start or end), // then follow the chain (by looking for selected items) to the lowest // item. // If no visible menu popup present, then need to special case // based on menu mode (eg. sys vs menubar vs popup). // first, check that we're really in menu mode (all menu mode flags // also include this... if (!Misc.IsBitSet(gui.dwFlags, NativeMethods.GUI_INMENUMODE)) return null; IntPtr hwndPopup = IntPtr.Zero; for (; ; ) { hwndPopup = Misc.FindWindowEx(IntPtr.Zero, hwndPopup, WindowsMenu.MenuClassName, null); if (hwndPopup == IntPtr.Zero) break; if (!SafeNativeMethods.IsWindowVisible(hwndPopup)) continue; // No other tests needed - it's menu-class and visible, use it... break; } if (hwndPopup != IntPtr.Zero) { // Now drill down to lowest item... for (; ; ) { // Get hmenu of popup... IntPtr hmenu = HmenuFromHwnd(hwndPopup); if (hmenu == IntPtr.Zero) return null; // Check for item focused in the popup... int i = GetHighlightedMenuItem(hmenu); if (i == -1) { // No selected item - could be the menu itself (eg. context menus // sometimes appear with no item having focus) return Create(hwndPopup, 0); } // Got an item - it could be a sub-menu or a leaf node item... IntPtr hSubMenu = UnsafeNativeMethods.GetSubMenu(hmenu, i); if (hSubMenu == IntPtr.Zero) { // actual menu item... return Create(hwndPopup, i + 1); } // Check to see if there's a popup open for that sub hmenu... IntPtr hwndSubMenuPopup = GetPopupHwndForHMenu(hSubMenu); if (hwndSubMenuPopup == IntPtr.Zero) { // No popup present - so just means that a popup item is selected, // but not popped out... return Create(hwndPopup, i + 1); } // Popup is present - so reassign the loop variable, and drill into it... hwndPopup = hwndSubMenuPopup; } } // No popup present, so must be a special case... // // For any of these, the item could be a menu itself or an item in a menu - // most reliable approach is to pick an appropriate starting point (eg. sysmenu or menubar), // and follow the trail of focused items. if (Misc.IsBitSet(gui.dwFlags, NativeMethods.GUI_SYSTEMMENUMODE)) { // Sys menu mode but no popup, means it must be the sys menu button (on the non-client area) // Can't create a sys menu area directly - have to create nonclientarea then titlebar first... NonClientArea nonClient = (NonClientArea)NonClientArea.Create(gui.hwndActive, 0); WindowsTitleBar titlebar = new WindowsTitleBar(gui.hwndActive, nonClient, 0); return CreateSystemMenu(gui.hwndActive, titlebar); } else if (Misc.IsBitSet(gui.dwFlags, NativeMethods.GUI_POPUPMENUMODE)) { // Popup/context menu mode but no popup - shouldn't happen, unless it's just // disappeared. return null; } else if (Misc.IsBitSet(gui.dwFlags, NativeMethods.GUI_INMENUMODE)) { // Menu/menubar mode, but no menu present - so could be item on menu bar // or menu bar itself... IntPtr hmenu = UnsafeNativeMethods.GetMenu(gui.hwndActive); int i = GetHighlightedMenuItem(hmenu); if (i == -1) { // No selected item - so its the menubar itself... // Need to create this via NonClient proxy... return NonClientArea.CreateMenuBarItem(gui.hwndActive, 0, 0/*ignored by CreateMenuBarItem*/); } else { // selected item on menubar... return NonClientArea.CreateMenuBarItem(gui.hwndActive, i + 1, 0/*ignored by CreateMenuBarItem*/); } } return null; }
private static void RaiseEventsOnWindow(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild) { ProxyFragment elw = new NonClientArea(hwnd); if (eventId == NativeMethods.EventObjectNameChange) { int style = Misc.GetWindowStyle(hwnd); if (Misc.IsBitSet(style, NativeMethods.WS_CHILD)) { // Full control names do not change. They are named by the static label. return; } else { // But the title bar name does so allow title bar proxy to procees the event. WindowsTitleBar tb = new WindowsTitleBar(hwnd, elw, 0); tb.DispatchEvents(eventId, idProp, idObject, idChild); } } elw.DispatchEvents(eventId, idProp, idObject, idChild); }
// Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint (int x, int y) { int hit = Misc.ProxySendMessageInt(_hwnd, NativeMethods.WM_NCHITTEST, IntPtr.Zero, NativeMethods.Util.MAKELPARAM(x, y)); switch (hit) { case NativeMethods.HTHSCROLL: { ProxyFragment ret = CreateNonClientChild(NonClientItem.HScrollBar); return ret.ElementProviderFromPoint(x, y); } case NativeMethods.HTVSCROLL: { ProxyFragment ret = CreateNonClientChild(NonClientItem.VScrollBar); return ret.ElementProviderFromPoint(x, y); } case NativeMethods.HTCAPTION : case NativeMethods.HTMINBUTTON : case NativeMethods.HTMAXBUTTON : case NativeMethods.HTHELP : case NativeMethods.HTCLOSE : case NativeMethods.HTSYSMENU : WindowsTitleBar tb = new WindowsTitleBar(_hwnd, this, 0); return tb.ElementProviderFromPoint (x, y); case NativeMethods.HTGROWBOX: return CreateNonClientChild(NonClientItem.Grip); case NativeMethods.HTBOTTOMRIGHT: return FindGrip(x, y); case NativeMethods.HTBOTTOMLEFT: return FindGripMirrored(x, y); case NativeMethods.HTMENU: return FindMenus(x, y); case NativeMethods.HTLEFT: case NativeMethods.HTRIGHT: case NativeMethods.HTTOP: case NativeMethods.HTTOPLEFT: case NativeMethods.HTTOPRIGHT: case NativeMethods.HTBOTTOM: case NativeMethods.HTBORDER: // We do not handle the borders so return null here and let the // HWNDProvider handle them as the whole window. return null; default: // Leave all other cases (especially including HTCLIENT) alone... return null; } }
// Create the approiate child this can return null if that child does not exist internal ProxyFragment CreateNonClientChild(NonClientItem item) { switch (item) { case NonClientItem.HScrollBar: if (WindowsScrollBar.HasHorizontalScrollBar(_hwnd)) { // the listview needs special handling WindowsListViewScrollBar inherits from WindowsScrollBar // and overrides some of its behavoir if (Misc.ProxyGetClassName(_hwnd) == "SysListView32") { return(new WindowsListViewScrollBar(_hwnd, this, (int)item, NativeMethods.SB_HORZ)); } else { return(new WindowsScrollBar(_hwnd, this, (int)item, NativeMethods.SB_HORZ)); } } break; case NonClientItem.VScrollBar: if (WindowsScrollBar.HasVerticalScrollBar(_hwnd)) { // the listview needs special handling WindowsListViewScrollBar inherits from WindowsScrollBar // and overrides some of its behavoir if (Misc.ProxyGetClassName(_hwnd) == "SysListView32") { return(new WindowsListViewScrollBar(_hwnd, this, (int)item, NativeMethods.SB_VERT)); } else { return(new WindowsScrollBar(_hwnd, this, (int)item, NativeMethods.SB_VERT)); } } break; case NonClientItem.TitleBar: { // Note 2 checks above will succeed for the win32popup menu, hence adding this last one if (WindowsTitleBar.HasTitleBar(_hwnd)) { return(new WindowsTitleBar(_hwnd, this, (int)item)); } break; } case NonClientItem.Menu: { return(CreateNonClientMenu()); } case NonClientItem.Grip: { int style = WindowStyle; if (Misc.IsBitSet(style, NativeMethods.WS_VSCROLL) && Misc.IsBitSet(style, NativeMethods.WS_HSCROLL)) { if (WindowsGrip.IsGripPresent(_hwnd, false)) { return(new WindowsGrip(_hwnd, this, (int)item)); } } break; } default: return(null); } return(null); }