private void ExpandOrCollapse(bool collapse) { CheckControlEnabled(); // Check if item can be expanded or collapsed. bool isCollapsed = IsCollapsed(); if ((!collapse && !isCollapsed) || (collapse && isCollapsed)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } NativeMethods.LVGROUP group = new NativeMethods.LVGROUP(); group.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP))); // Note: If we set group.mask to LVGF_GROUPID | LVGF_STATE, // SetGroupInfo() will fail. Setting LVGF_STATE alone works, however. group.mask = NativeMethods.LVGF_STATE; group.iGroupID = _groupID; group.stateMask = NativeMethods.LVGS_COLLAPSED; group.state = collapse ? NativeMethods.LVGS_COLLAPSED : 0; if (!XSendMessage.SetGroupInfo(_hwnd, group)) { throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed)); } }
internal bool AreGroupsValid() { int count = _groups.Count; for (int i = 0; i < count; i++) { Group group = (Group)_groups[i]; if (!ListViewHasGroup(_hwnd, group._groupID)) { return(false); } } // Make sure that no new group have been added, try to match all the GroupId to an // existing one. int itemCount = WindowsListView.GetItemCount(_hwnd); NativeMethods.LVITEM_V6 item = new NativeMethods.LVITEM_V6(); item.mask = NativeMethods.LVIF_GROUPID; for (item.iItem = 0; item.iItem < itemCount; item.iItem++) { if (!XSendMessage.GetItem(_hwnd, ref item) || GetGroup(item.iGroupID) == null) { return(false); } } return(true); }
protected override bool IsFocused() { int groupIndex = (int)Misc.ProxySendMessage(_hwnd, NativeMethods.LVM_GETFOCUSEDGROUP, IntPtr.Zero, IntPtr.Zero); // need to convert the item id to a group id NativeMethods.LVGROUP_V6 groupInfo = new NativeMethods.LVGROUP_V6(); groupInfo.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); groupInfo.mask = NativeMethods.LVGF_GROUPID; unsafe { bool lresult = XSendMessage.XSend(_hwnd, NativeMethods.LVM_GETGROUPINFOBYINDEX, new IntPtr(groupIndex), new IntPtr(&groupInfo), Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); if (!lresult) { // no group for this item should never happen. return(false); } } if (groupInfo.iGroupID == _groupID) { return(true); } return(false); }
private unsafe int GetGroupHeaderHeight() { NativeMethods.LVGROUPMETRICS metric = new NativeMethods.LVGROUPMETRICS(sizeof(NativeMethods.LVGROUPMETRICS), NativeMethods.LVGMF_BORDERSIZE); XSendMessage.XSend(_hwnd, NativeMethods.LVM_GETGROUPMETRICS, IntPtr.Zero, new IntPtr(&(metric.cbSize)), metric.cbSize, XSendMessage.ErrorValue.NoCheck); return(metric.Top + padding); }
// This is new with v6 comctrl on Vista private void ClickSplitButton() { // Make sure that the control is enabled if (!SafeNativeMethods.IsWindowEnabled(_hwnd)) { throw new ElementNotEnabledException(); } WindowsSysHeader parent = _parent as WindowsSysHeader; if (parent != null) { parent.ScrollIntoView(this); } Rect rect = XSendMessage.GetItemRect(_hwnd, NativeMethods.HDM_GETITEMDROPDOWNRECT, _item); NativeMethods.Win32Rect rectW32 = new NativeMethods.Win32Rect(rect); IntPtr center = NativeMethods.Util.MAKELPARAM(rectW32.left + ((rectW32.right - rectW32.left) / 2), rectW32.top + ((rectW32.bottom - rectW32.top) / 2)); // click // This code does not seem to work Misc.ProxySendMessage(_hwnd, NativeMethods.WM_LBUTTONDOWN, new IntPtr(NativeMethods.MK_LBUTTON), center); Misc.ProxySendMessage(_hwnd, NativeMethods.WM_LBUTTONUP, IntPtr.Zero, center); }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // Retrieves the bounding rectangle of the Status Bar Pane. static internal Rect GetBoundingRectangle(IntPtr hwnd, int item) { if (!WindowsFormsHelper.IsWindowsFormsControl(hwnd)) { return(XSendMessage.GetItemRect(hwnd, NativeMethods.SB_GETRECT, item)); } else { Accessible acc = null; if (Accessible.AccessibleObjectFromWindow(hwnd, NativeMethods.OBJID_CLIENT, ref acc) != NativeMethods.S_OK || acc == null) { return(Rect.Empty); } else { // OLEACC's Win32 proxy does use a 1, 2, 3... scheme, but the [....] // controls in some cases supply their own children, using a different scheme. // Using the "ByIndex" approach avoids having to know what the underlying // object's idChild scheme is. acc = Accessible.GetFullAccessibleChildByIndex(acc, item); if (acc == null) { return(Rect.Empty); } else { return(acc.Location); } } } }
// ------------------------------------------------------ // // Internal Methods // // ------------------------------------------------------ #region Internal Methods internal static int GetItemCount(IntPtr hwnd) { // The Display Property Dialog is doing something strange with the their tab control. The // last tab is invisable. So if that is the case remove it from the count, since UIAutomation // can not do anything with it. int count = Misc.ProxySendMessageInt(hwnd, NativeMethods.TCM_GETITEMCOUNT, IntPtr.Zero, IntPtr.Zero); if (count > 0) { NativeMethods.Win32Rect rectW32 = NativeMethods.Win32Rect.Empty; bool result; unsafe { result = XSendMessage.XSend(hwnd, NativeMethods.TCM_GETITEMRECT, new IntPtr(count - 1), new IntPtr(&rectW32), Marshal.SizeOf(rectW32.GetType()), XSendMessage.ErrorValue.Zero); } if (!result) { count--; } if (rectW32.IsEmpty) { count--; } } return(count); }
// ------------------------------------------------------ // // Internal Methods // // ------------------------------------------------------ #region Internal Methods // Create a WindowsToolbar instance. Needs to be internal because // ApplicationWindow pattern needs to call this so needs to be internal internal ProxySimple CreateToolbarItem(int item) { NativeMethods.TBBUTTON tbb = new NativeMethods.TBBUTTON(); // During the FocusChanged WinEvent (EVENT_OBJECT_FOCUS), // some "ToolbarWindow32" children report an item ID (child id) // of 0x80000001, 0x80000002, etc. instead of 1, 2, etc. // However, when created as children of the parent toolbar, // these same items are assigned IDs of 1, 2, etc. // Therefore, map negative item IDs of the form 0x80000001, // 0x80000002, etc. to 1, 2, etc. item = (int)(~0x80000000 & (uint)item); if (!XSendMessage.GetItem(_hwnd, item, ref tbb)) { // If failed to get button infromation the button must not exist, so return null. return(null); } if (Misc.ProxySendMessageInt(_hwnd, NativeMethods.TB_ISBUTTONHIDDEN, new IntPtr(tbb.idCommand), IntPtr.Zero) == 0) { Accessible acc = Accessible.CreateNativeFromEvent(_hwnd, NativeMethods.OBJID_CLIENT, item + 1); if (acc != null) { if (acc.Role == AccessibleRole.MenuItem) { return(new ToolbarItemAsMenuItem(_hwnd, this, item, tbb.idCommand, acc)); } } return(new ToolbarItem(_hwnd, this, item, tbb.idCommand)); } return(null); }
// Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint(int x, int y) { UnsafeNativeMethods.TCHITTESTINFO hti = new UnsafeNativeMethods.TCHITTESTINFO(); hti.pt = new NativeMethods.Win32Point(x, y); if (!Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref hti.pt, 1)) { return(null); } // updown control goes over the tabs hence the order of the check // We cannot let UIAutomation do the do the drilling for the updown as the spinner covers the tab IntPtr updownHwnd = this.GetUpDownHwnd(); if (updownHwnd != IntPtr.Zero && Misc.PtInWindowRect(updownHwnd, x, y)) { return(null); } int index; unsafe { index = XSendMessage.XSendGetIndex(_hwnd, NativeMethods.TCM_HITTEST, IntPtr.Zero, new IntPtr(&hti), Marshal.SizeOf(hti.GetType())); } if (index >= 0) { return(CreateTabItem(index)); } return(null); }
// Retrieve the text of the list portion of Combo. // Or Text of the edit portion of ComboBoxEx32 (path -1 as index) // Use CB_XXX instead of LB_XXX, since CB_XXX will give us back text in ownerdrawn combo static private string SpecialText(IntPtr hwnd, int index) { if (index == -1) { // get the selected element index = Misc.ProxySendMessageInt(hwnd, NativeMethods.CB_GETCURSEL, IntPtr.Zero, IntPtr.Zero); if (index == -1) { return(""); } } int len = Misc.ProxySendMessageInt(hwnd, NativeMethods.CB_GETLBTEXTLEN, new IntPtr(index), IntPtr.Zero); if (len < 1) { return(""); } if (Misc.GetClassName(hwnd).Equals("Internet Explorer_TridentCmboBx")) { // The Trident listbox is a superclassed standard listbox. // Trident listboxes are owner draw that does not have the hasstring style set. // All the control contains is the owner draw data and not text. Private // messages were added to retrieve the owner draw data as text. The new messages // are used just like the normally LB_GETTEXT and CB_GETTEXT messages. return(XSendMessage.GetItemText(hwnd, NativeMethods.WM_USER + NativeMethods.CB_GETLBTEXT, index, len)); } else { return(Misc.GetUnsafeText(hwnd, NativeMethods.CB_GETLBTEXT, new IntPtr(index), len)); } }
//------------------------------------------------------ // // Internal Methods // //------------------------------------------------------ #region Internal Methods // Returns the bounding rectangle of the control. internal static Rect GetBoundingRectangle(IntPtr hwnd, int item) { NativeMethods.Win32Rect rectW32 = NativeMethods.Win32Rect.Empty; unsafe { if (!XSendMessage.XSend(hwnd, NativeMethods.RB_GETRECT, new IntPtr(item), new IntPtr(&rectW32), Marshal.SizeOf(rectW32.GetType()), XSendMessage.ErrorValue.Zero)) { return(Rect.Empty); } } if (!Misc.MapWindowPoints(hwnd, IntPtr.Zero, ref rectW32, 2)) { return(Rect.Empty); } // Work around a bug in the common control. Swap the X and Y value for vertical // rebar bands if (Misc.IsBitSet(Misc.GetWindowStyle(hwnd), (int)CommonControlStyles.CCS_VERT)) { return(new Rect(rectW32.left, rectW32.top, rectW32.bottom - rectW32.top, rectW32.right - rectW32.left)); } else { return(rectW32.ToRect(Misc.IsControlRTL(hwnd))); } }
private unsafe int getRebarBandIDFromPoint(NativeMethods.Win32Point pt) { NativeMethods.RB_HITTESTINFO rbHitTestInfo = new NativeMethods.RB_HITTESTINFO(); rbHitTestInfo.pt = pt; rbHitTestInfo.uFlags = 0; rbHitTestInfo.iBand = 0; return(XSendMessage.XSendGetIndex(_hwnd, NativeMethods.RB_HITTEST, IntPtr.Zero, new IntPtr(&rbHitTestInfo), Marshal.SizeOf(rbHitTestInfo.GetType()))); }
private static string GetItemText(IntPtr hwnd, int itemIndex) { NativeMethods.TCITEM tcitem = new NativeMethods.TCITEM(); tcitem.Init(); tcitem.mask = NativeMethods.TCIF_TEXT; tcitem.cchTextMax = Misc.MaxLengthNameProperty; return(XSendMessage.GetItemText(hwnd, itemIndex, tcitem)); }
// Extract the internal Name property of the Windows Forms control using // the WM_GETCONTROLNAME message. static internal string GetControlName(IntPtr hwnd) { string winFormsID = ""; if (XSendMessage.XSend(hwnd, WM_GETCONTROLNAME, new IntPtr(Misc.MaxLengthNameProperty), ref winFormsID, Misc.MaxLengthNameProperty)) { return(winFormsID); } return(null); }
// ------------------------------------------------------ // // Constructors // // ------------------------------------------------------ #region Constructors internal ToolbarItem(IntPtr hwnd, ProxyFragment parent, int item, int idCommand) : base(hwnd, parent, item) { _idCommand = idCommand; NativeMethods.TBBUTTON tbb = new NativeMethods.TBBUTTON(); int buttonStyle = 0; if (XSendMessage.GetItem(_hwnd, _item, ref tbb)) { buttonStyle = tbb.fsStyle; } // Set the strings to return properly the properties. bool hasImageList = Misc.ProxySendMessageInt(_hwnd, NativeMethods.TB_GETIMAGELIST, IntPtr.Zero, IntPtr.Zero) != 0; int exStyle = Misc.ProxySendMessageInt(_hwnd, NativeMethods.TB_GETEXTENDEDSTYLE, IntPtr.Zero, IntPtr.Zero); _isToggleButton = false; _cControlType = ControlType.Button; // If a separator, say so if (Misc.IsBitSet(buttonStyle, NativeMethods.BTNS_SEP)) { _cControlType = ControlType.Separator; } else if (Misc.IsBitSet(buttonStyle, NativeMethods.BTNS_CHECK)) { // Special case for task list - they use the checked style, but only for visuals... IntPtr hwndParent = Misc.GetParent(_hwnd); if (Misc.GetClassName(hwndParent) != "MSTaskSwWClass") { _isToggleButton = true; } } else if (Misc.IsBitSet(buttonStyle, NativeMethods.BTNS_DROPDOWN) && Misc.IsBitSet(exStyle, NativeMethods.TBSTYLE_EX_DRAWDDARROWS)) { // if its a drop down and it has an arrow its a split button _cControlType = ControlType.SplitButton; } else if (!hasImageList || tbb.iBitmap == NativeMethods.I_IMAGENONE) { // Text-only, no bitmap, so it's effectively a menu item. // (eg. as used in MMC) _cControlType = ControlType.MenuItem; } _fIsContent = _cControlType != ControlType.Separator; // The Start Menu's "Shut Down" and "Log Off" buttons are toolbar items. They need to have the // KeyboardFocusable property be set to true. _fIsKeyboardFocusable = (bool)parent.GetElementProperty(AutomationElement.IsKeyboardFocusableProperty); GetItemId(ref _sAutomationId); }
// ------------------------------------------------------ // // Private Methods // // ------------------------------------------------------ #region Private Methods private unsafe NativeMethods.Win32Rect BoundingRect() { NativeMethods.Win32Rect rectW32 = new NativeMethods.Win32Rect(); if (!XSendMessage.XSend(_hwnd, NativeMethods.TCM_GETITEMRECT, new IntPtr(_item), new IntPtr(&rectW32), Marshal.SizeOf(rectW32.GetType()), XSendMessage.ErrorValue.Zero)) { return(NativeMethods.Win32Rect.Empty); } return(Misc.MapWindowPoints(_hwnd, IntPtr.Zero, ref rectW32, 2) ? rectW32 : NativeMethods.Win32Rect.Empty); }
private void GetItemId(ref string itemId) { NativeMethods.TBBUTTON tbb = new NativeMethods.TBBUTTON(); if (XSendMessage.GetItem(_hwnd, _item, ref tbb)) { if (tbb.idCommand > 0) { itemId = "Item " + tbb.idCommand.ToString(CultureInfo.CurrentCulture); } } }
// Is focus set to the specified item protected override bool IsFocused() { NativeMethods.LVGROUP_V6 groupInfo = new NativeMethods.LVGROUP_V6(); groupInfo.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); groupInfo.iGroupID = _groupId; groupInfo.mask = NativeMethods.LVGF_STATE; groupInfo.stateMask = NativeMethods.LVGS_SUBSETLINKFOCUSED; // Note: return code of GetGroupInfo() is not reliable. XSendMessage.GetGroupInfo(_hwnd, ref groupInfo); // ignore return code. return((groupInfo.state & NativeMethods.LVGS_SUBSETLINKFOCUSED) != 0); }
internal unsafe NativeMethods.Win32Rect GetGroupRect() { NativeMethods.Win32Rect rect = new NativeMethods.Win32Rect(); bool isCollapsed = WindowsListViewGroup.IsCollapsed(_hwnd, _groupID); rect.top = isCollapsed ? NativeMethods.LVGGR_HEADER : NativeMethods.LVGGR_GROUP; XSendMessage.XSend(_hwnd, NativeMethods.LVM_GETGROUPRECT, new IntPtr(_groupID), new IntPtr(&rect), Marshal.SizeOf(rect.GetType())); Misc.MapWindowPoints(_hwnd, IntPtr.Zero, ref rect, 2); return(rect); }
private int GetItemFromIndex(int index) { NativeMethods.HDITEM item = new NativeMethods.HDITEM(); item.Init(); item.mask = NativeMethods.HDI_ORDER; // Send the message... if (!XSendMessage.GetItem(_hwnd, index, ref item)) { return(-1); } return(item.iOrder); }
internal static bool IsCollapsed(IntPtr hwnd, int groupID) { bool isCollapsed = false; NativeMethods.LVGROUP group = new NativeMethods.LVGROUP(); group.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP))); group.iGroupID = groupID; group.mask = NativeMethods.LVGF_STATE; group.stateMask = NativeMethods.LVGS_COLLAPSED; // Note: return code of GetGroupInfo() is not reliable. XSendMessage.GetGroupInfo(hwnd, ref group); // ignore return code. isCollapsed = (group.state & NativeMethods.LVGS_COLLAPSED) != 0; return(isCollapsed); }
// Returns the last child element in the raw hierarchy. internal override ProxySimple GetLastChild() { // return last item in this group GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID); // List view groups in vista can have an extra link at the end that says // something like "show all 11 items...". If one exists expose it as the last child. if (_isComctrlV6OnOsVerV6orHigher) { NativeMethods.LVGROUP_V6 group = new NativeMethods.LVGROUP_V6(); group.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); group.iGroupID = _groupID; group.mask = NativeMethods.LVGF_STATE; group.stateMask = NativeMethods.LVGS_SUBSETED; // Note: return code of GetGroupInfo() is not reliable. XSendMessage.GetGroupInfo(_hwnd, ref group); // ignore return code. // if we are not subseted then the last item is a regular listitem so // it is ok to fall through and let that be created. Otherwise we need to // create the subset link proxy. if ((group.state & NativeMethods.LVGS_SUBSETED) != 0) { int [] items = groupInfo._items; if (groupInfo._count <= 0 || groupInfo._count > items.Length) { return(null); } int index = items [groupInfo._count - 1]; return(CreateGroupSubsetLink(index + 1)); } } if (groupInfo) { int [] items = groupInfo._items; if (groupInfo._count <= 0 || groupInfo._count > items.Length) { return(null); } int index = items [groupInfo._count - 1]; return(CreateListViewItem(index)); } return(null); }
// retrieve an id of the group to which this lvitem belongs // valid only if lv has groups enabled static internal int GetGroupID(IntPtr hwnd, int lvItem) { System.Diagnostics.Debug.Assert(WindowsListView.IsGroupViewEnabled(hwnd), "GetGroupID: called when lv does not have groups"); NativeMethods.LVITEM_V6 item = new NativeMethods.LVITEM_V6(); item.mask = NativeMethods.LVIF_GROUPID; item.iItem = lvItem; if (XSendMessage.GetItem(hwnd, ref item)) { return(item.iGroupID); } return(-1); }
// Returns the next sibling element in the raw hierarchy. // Peripheral controls have always negative values. // Returns null if no next child internal override ProxySimple GetNextSibling(ProxySimple child) { GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID); if (groupInfo) { int [] items = groupInfo._items; int current = child._item; // find the index of the current lvitem int nextLocation = groupInfo.IndexOf(current) + 1; //Array.IndexOf(items, current) + 1; if (nextLocation <= 0) { // No more siblings return(null); } if (nextLocation < groupInfo._count) { return(CreateListViewItem(items [nextLocation])); } // List view groups in vista can have an extra link at the end that says // somthing like "show all 11 items..." if (_isComctrlV6OnOsVerV6orHigher && nextLocation == groupInfo._count) { NativeMethods.LVGROUP_V6 group = new NativeMethods.LVGROUP_V6(); group.Init(Marshal.SizeOf(typeof(NativeMethods.LVGROUP_V6))); group.iGroupID = _groupID; group.mask = NativeMethods.LVGF_STATE; group.stateMask = NativeMethods.LVGS_SUBSETED; // Note: return code of GetGroupInfo() is not reliable. XSendMessage.GetGroupInfo(_hwnd, ref group); // ignore return code. // The items array holds the list items in this group. If we have a subset link we // don't store it with the list items because it isn't really a list item. Instead we just // create the subset link proxy with an item index one more than the last index. if ((group.state & NativeMethods.LVGS_SUBSETED) != 0) { return(CreateGroupSubsetLink(items [groupInfo._count - 1] + 1)); } } } return(null); }
// This is new with v6 comctrl on Vista private bool IsSplitButton() { NativeMethods.HDITEM item = new NativeMethods.HDITEM(); item.Init(); item.mask = NativeMethods.HDI_FORMAT; // Send the message... if (XSendMessage.GetItem(_hwnd, _item, ref item)) { if ((item.fmt & NativeMethods.HDF_SPLITBUTTON) != 0) { return(true); } } return(false); }
// Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint(int x, int y) { NativeMethods.Win32Point pt = new NativeMethods.Win32Point(x, y); NativeMethods.LVHITTESTINFO_INTERNAL hitTest = WindowsListView.SubitemHitTest(_hwnd, pt); if ((hitTest.flags & NativeMethods.LVHT_EX_GROUP_HEADER) != 0) { return(this); } if ((hitTest.flags & NativeMethods.LVHT_ONITEM) != 0 && hitTest.iItem >= 0) { // create the item return(new ListViewItem(_hwnd, this, hitTest.iItem)); } // If we did not land on an item we may be at a subset link these only exist // in v6 comctrl and vista or later. if (_isComctrlV6OnOsVerV6orHigher) { // Allocate a local LVHITTESTINFO struct. NativeMethods.LVHITTESTINFO_V6 hitTestNative = new NativeMethods.LVHITTESTINFO_V6(hitTest); unsafe { XSendMessage.XSendGetIndex(_hwnd, NativeMethods.LVM_HITTEST, new IntPtr(-1), new IntPtr(&hitTestNative), Marshal.SizeOf(hitTestNative.GetType())); } if ((hitTestNative.flags & NativeMethods.LVHT_EX_GROUP_SUBSETLINK) != 0) { GroupManager.GroupInfo groupInfo = GetGroupInfo(_hwnd, ID); int [] items = groupInfo._items; if (groupInfo._count <= 0 || groupInfo._count > items.Length) { return(null); } int index = items [groupInfo._count - 1]; return(CreateGroupSubsetLink(index + 1)); } } return(this); }
// Sets the focus to this item. internal override bool SetFocus() { // // Send the link an LM_SETITEM message. // // Allocate a local LITEM struct. UnsafeNativeMethods.LITEM linkItem = new UnsafeNativeMethods.LITEM(); // Fill in the coordinates about which we care. linkItem.mask = NativeMethods.LIF_ITEMINDEX | NativeMethods.LIF_STATE; linkItem.iLink = _item; linkItem.stateMask = NativeMethods.LIS_FOCUSED; linkItem.state = NativeMethods.LIS_FOCUSED; unsafe { // Send the LM_SETITEM message. return(XSendMessage.XSend(_hwnd, NativeMethods.LM_SETITEM, IntPtr.Zero, new IntPtr(&linkItem), Marshal.SizeOf(linkItem.GetType()))); } }
private bool GetLinkItem(int item) { if (item < 0) { return(false); } // Set the members about which we care. _linkItem.mask = NativeMethods.LIF_ITEMINDEX | NativeMethods.LIF_STATE; _linkItem.iLink = item; _linkItem.state = 0; _linkItem.stateMask = NativeMethods.LIS_ENABLED; unsafe { fixed(UnsafeNativeMethods.LITEM *pLinkItem = &_linkItem) { return(XSendMessage.XSend(_hwnd, NativeMethods.LM_GETITEM, IntPtr.Zero, new IntPtr(pLinkItem), sizeof(UnsafeNativeMethods.LITEM))); } } }
// Returns a Proxy element corresponding to the specified // screen coordinates. internal override ProxySimple ElementProviderFromPoint(int x, int y) { // // Send the link an LM_HITTEST message. // // Allocate a local hit test info struct. UnsafeNativeMethods.LHITTESTINFO HitTestInfo = new UnsafeNativeMethods.LHITTESTINFO(); // Fill in the coordinates that we want to check. HitTestInfo.pt.x = x; HitTestInfo.pt.y = y; // Convert screen coordinates to client coordinates. if (!Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref HitTestInfo.pt, 1)) { base.ElementProviderFromPoint(x, y); } // Fill in index and state info. HitTestInfo.item.mask = NativeMethods.LIF_ITEMINDEX | NativeMethods.LIF_STATE; HitTestInfo.item.iLink = 0; HitTestInfo.item.stateMask = NativeMethods.LIS_ENABLED; HitTestInfo.item.state = 0; bool bGetItemResult; unsafe { // Send the LM_HITTEST message. bGetItemResult = XSendMessage.XSend(_hwnd, NativeMethods.LM_HITTEST, IntPtr.Zero, new IntPtr(&HitTestInfo), Marshal.SizeOf(HitTestInfo.GetType())); } if (bGetItemResult == true && HitTestInfo.item.iLink >= 0 && GetLinkItem(HitTestInfo.item.iLink)) { return(CreateHyperlinkItem(_linkItem, HitTestInfo.item.iLink)); } return(base.ElementProviderFromPoint(x, y)); }
// Returns a Proxy element corresponding to the specified screen coordinates. internal override ProxySimple ElementProviderFromPoint(int x, int y) { NativeMethods.HDHITTESTINFO HitTestInfo = new NativeMethods.HDHITTESTINFO(); HitTestInfo.pt = new NativeMethods.Win32Point(x, y); int index = -1; if (Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref HitTestInfo.pt, 1)) { unsafe { index = XSendMessage.XSendGetIndex(_hwnd, NativeMethods.HDM_HITTEST, IntPtr.Zero, new IntPtr(&HitTestInfo), Marshal.SizeOf(HitTestInfo.GetType())); } } // make sure that hit-test happened on the header item itself if (index != -1 && (NativeMethods.HHT_ONHEADER == (HitTestInfo.flags & 0x000F))) { return(CreateHeaderItem(GetItemFromIndex(index))); } return(this); }