예제 #1
0
파일: WindowsTab.cs 프로젝트: JianwenSun/cc
        // Removes this element from the selection
        void ISelectionItemProvider.RemoveFromSelection()
        {
            // Make sure that the control is enabled
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            // If not selected, done
            if (!((ISelectionItemProvider)this).IsSelected)
            {
                return;
            }

            // If multiple selections allowed, unselect element
            if (WindowsTab.SupportMultipleSelection(_hwnd) == true)
            {
                NativeMethods.Win32Point pt = new NativeMethods.Win32Point();
                if (GetClickablePoint(out pt, true))
                {
                    Input.SendKeyboardInput(Key.LeftCtrl, true);
                    Misc.MouseClick(pt.x, pt.y);
                    Input.SendKeyboardInput(Key.LeftCtrl, false);
                    return;
                }

                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }
            // else if button style and single select, send deselectall message
            else if (Misc.IsBitSet(WindowStyle, NativeMethods.TCS_BUTTONS))
            {
                Misc.ProxySendMessage(_hwnd, NativeMethods.TCM_DESELECTALL, IntPtr.Zero, IntPtr.Zero);
                return;
            }

            throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
        }
예제 #2
0
파일: WindowsTab.cs 프로젝트: JianwenSun/cc
        // Press a tab
        private void Select()
        {
            if (Misc.IsBitSet(WindowStyle, (NativeMethods.TCS_BUTTONS | NativeMethods.TCS_FOCUSNEVER)))
            {
                // The TCM_SETCURFOCUS message cannot be used with TCS_FOCUSNEVER
                // use a convulated way faking a mouse action

                NativeMethods.Win32Point pt = new NativeMethods.Win32Point();
                if (GetClickablePoint(out pt, true))
                {
                    // Convert screen coordinates to client coordinates.
                    if (Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref pt, 1))
                    {
                        Misc.PostMessage(_hwnd, NativeMethods.WM_LBUTTONDOWN, (IntPtr)NativeMethods.MK_LBUTTON, NativeMethods.Util.MAKELPARAM(pt.x, pt.y));
                        Misc.PostMessage(_hwnd, NativeMethods.WM_LBUTTONUP, (IntPtr)NativeMethods.MK_LBUTTON, NativeMethods.Util.MAKELPARAM(pt.x, pt.y));
                    }
                }
            }
            else
            {
                Misc.ProxySendMessage(_hwnd, NativeMethods.TCM_SETCURFOCUS, new IntPtr(_item), IntPtr.Zero);
            }

        }
예제 #3
0
        // Same as clicking on an hyperlink
        void IInvokeProvider.Invoke()
        {
            // Check that button can be clicked.
            //
            // This state could change anytime.
            //

            // Make sure that the control is enabled
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            if (!SafeNativeMethods.IsWindowVisible(_hwnd))
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            Misc.SetFocus(_hwnd);

            NativeMethods.Win32Point pt = new NativeMethods.Win32Point();
            if (GetClickablePoint(out pt, false))
            {
                Misc.MouseClick(pt.x, pt.y);
            }
        }
예제 #4
0
파일: WindowsTab.cs 프로젝트: JianwenSun/cc
        // Adds this element to the selection
        void ISelectionItemProvider.AddToSelection()
        {
            // Make sure that the control is enabled
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            // If not selectable, can't add to selection
            if (!IsSelectable())
            {
                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }

            // If already selected, done
            if (((ISelectionItemProvider)this).IsSelected)
            {
                return;
            }

            // If multiple selections allowed, add requested selection
            if (WindowsTab.SupportMultipleSelection(_hwnd) == true)
            {
                // Press ctrl and mouse click tab
                NativeMethods.Win32Point pt = new NativeMethods.Win32Point();
                if (GetClickablePoint(out pt, true))
                {
                    Input.SendKeyboardInput(Key.LeftCtrl, true);
                    Misc.MouseClick(pt.x, pt.y);
                    Input.SendKeyboardInput(Key.LeftCtrl, false);
                    return;
                }

                throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
            }
            // else only single selection allowed
            else
            {
                throw new InvalidOperationException(SR.Get(SRID.DoesNotSupportMultipleSelection));
            }
        }
        private void Toggle()
        {
            // Make sure that the control is enabled
            if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
            {
                throw new ElementNotEnabledException();
            }

            Misc.SetFocus(_hwnd);

            NativeMethods.Win32Rect rc = ListViewCheckBoxRect(_hwnd, _listviewItem);
            NativeMethods.Win32Point pt = new NativeMethods.Win32Point((rc.left + rc.right) / 2, (rc.top + rc.bottom) / 2);

            if (Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref pt, 1))
            {
                // "click" on the checkbox
                Misc.ProxySendMessage(_hwnd, NativeMethods.WM_LBUTTONDOWN, (IntPtr)NativeMethods.MK_LBUTTON, NativeMethods.Util.MAKELPARAM(pt.x, pt.y));
                Misc.ProxySendMessage(_hwnd, NativeMethods.WM_LBUTTONUP, IntPtr.Zero, NativeMethods.Util.MAKELPARAM(pt.x, pt.y));
            }
        }
        // Obtain clickable point on the listviewitem
        // in the case when one doesnot exist return false
        private bool GetListviewitemClickablePoint (out NativeMethods.Win32Point clickPoint)
        {
            // When this method is called, lv was already scrolled vertically
            // hence item is visible veritcally
            clickPoint.x = clickPoint.y = 0;

            NativeMethods.Win32Rect itemRectangle;

            // Obtain rectangle
            if (!WindowsListView.GetItemRect(_hwnd, _item, NativeMethods.LVIR_LABEL, out itemRectangle))
            {
                return false;
            }

            if (WindowsListView.IsDetailMode (_hwnd) && !WindowsListView.FullRowSelect (_hwnd))
            {
                // LVS_REPORT - possible that we may need to scroll horizontaly
                // 
                NativeMethods.Win32Point pt = new NativeMethods.Win32Point (itemRectangle.left, 0);

                if (!Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref pt, 1))
                {
                    return false;
                }

                // In client coordinates, hence negative indicates that item is to the left of lv client area
                if (pt.x < 0)
                {
                    ((IScrollItemProvider)this).ScrollIntoView();

                    if (!WindowsListView.GetItemRect(_hwnd, _item, NativeMethods.LVIR_LABEL, out itemRectangle))
                    {
                        return false;
                    }
                }
            }

            clickPoint.x = Math.Min ((itemRectangle.left + 5), (itemRectangle.left + itemRectangle.right) / 2);
            clickPoint.y = (itemRectangle.top + itemRectangle.bottom) / 2;
            return true;
        }
예제 #7
0
        // get count of row for the listview when it is in the list mode
        static internal int GetRowCountListMode (IntPtr hwnd, int itemCount)
        {
            // NOTE: ListView in the List mode is tricky
            // In the List mode during the navigation columns getting
            // wrapped hence the number of rows we'll get by simply doing
            // LVNI_BELOW will be same as maximum number of elements
            // Algorithm: get the item position  while doing GetItemNext(,,LVNI_BELOW)
            // as long as pt.x is the same we on the same column
            // as soon as pt.x is changed we know we jump to the different column and hence we know the number of rows
            // This is true except:
            // If user had Groups shown, and than changed to the List mode (List mode does not have groups)
            // the List will not be snaking anymore (Windows Explorer LV bug on XP), hence after we come to the end of the first column
            // the GetItemNext(,,LVNI_BELOW) will return -1. all other case list will snake
            // Lucky for us at this point rowCount will contain the number of rows
            int columnCount = GetColumnCountOtherModes (hwnd);

            if (columnCount == 1)
            {
                // list does not snake, number of elements == number or rows
                return itemCount;
            }

            // We know that list has at least itemCount/columnCount rows
            int rowCount = (int) System.Math.Ceiling (((double) itemCount) / columnCount);

            NativeMethods.Win32Point pt = new NativeMethods.Win32Point (0, 0);

            // items are 0-based
            int current = rowCount - 1;
            if (!GetItemPosition(hwnd, current, out pt))
            {
                return 0;
            }

            int pos = pt.x;
            while (true)
            {
                int next = GetItemNext(hwnd, current, NativeMethods.LVNI_BELOW);
                // Expect -1 when no more items below
                if (next == -1)
                    return rowCount;

                // Guard against infinite loop (LH 
                if (next == current)
                    return rowCount;

                // Get this next item's top-left coordinate
                if (!GetItemPosition(hwnd, next, out pt))
                    return rowCount;

                // If we're not on the same left-most x-axis we've got the row count
                if (pos != pt.x)
                    return rowCount;

                ++rowCount;
                current = next;
            }
        }
예제 #8
0
        // Move the mouse to the x, y location and perfoms either
        // a single of double clik depending on the fDoubleClick parameter
        // The mouse is then brough back to the original location.
        internal static void MouseClick(int x, int y, bool fDoubleClick)
        {
            NativeMethods.Win32Point ptPrevious = new NativeMethods.Win32Point();
            bool fSetOldCursorPos = GetCursorPos(ref ptPrevious);
            bool mouseSwapped = UnsafeNativeMethods.GetSystemMetrics(NativeMethods.SM_SWAPBUTTON) != 0;

            Input.SendMouseInput(x, y, 0, SendMouseInputFlags.Move | SendMouseInputFlags.Absolute);

            Input.SendMouseInput(0, 0, 0, mouseSwapped ? SendMouseInputFlags.RightDown : SendMouseInputFlags.LeftDown);
            Input.SendMouseInput(0, 0, 0, mouseSwapped ? SendMouseInputFlags.RightUp : SendMouseInputFlags.LeftUp);

            if (fDoubleClick)
            {
                Input.SendMouseInput(0, 0, 0, mouseSwapped ? SendMouseInputFlags.RightDown : SendMouseInputFlags.LeftDown);
                Input.SendMouseInput(0, 0, 0, mouseSwapped ? SendMouseInputFlags.RightUp : SendMouseInputFlags.LeftUp);
            }

            // toolbar items don't have time to proccess the mouse click if we move it back too soon
            // so wait a small amount of time to give them a chance.  A value of 10 made this work
            // on a 2gig dual proc machine so 50 should cover a slower machine.
            System.Threading.Thread.Sleep(50);

            // Set back the mouse position where it was
            if (fSetOldCursorPos)
            {
                Input.SendMouseInput(ptPrevious.x, ptPrevious.y, 0, SendMouseInputFlags.Move | SendMouseInputFlags.Absolute);
            }
        }
        // For Vista getting the part of the titlebar that a tooltip belongs to is more
        // reliable across themes
        private string GetTitleBarToolTipTextForDWMEnabled()
        {
            // The mouse is over the titlebar item so get that point on the screen
            NativeMethods.Win32Point pt = new NativeMethods.Win32Point();
            if (!Misc.GetCursorPos(ref pt))
            {
                return "";
            }

            // Find the titlebar hwnd
            IntPtr hwnd = UnsafeNativeMethods.WindowFromPhysicalPoint(pt.x, pt.y);
            if (hwnd == IntPtr.Zero)
            {
                return "";
            }

            // Get the rects for each titlbar part
            Rect[] rects = Misc.GetTitlebarRects(hwnd);

            // Look from back to front - front is entire titlebar rect
            int scan;
            for (scan = rects.Length - 1; scan >= 0; scan--)
            {
                // Not using Misc.PtInRect because including the bounding pixels all the way around gives
                // better results; tooltips may appear when the mouse is one or two pixels outside of the
                // bounding rect so even this technique may miss.
                if (pt.x >= rects[scan].Left && pt.x <= rects[scan].Right && pt.y >= rects[scan].Top && pt.y <= rects[scan].Bottom)
                {
                    break;
                }
            }

            switch (scan)
            {
                case NativeMethods.INDEX_TITLEBAR_MINBUTTON:
                    if (Misc.IsBitSet(WindowStyle, NativeMethods.WS_MINIMIZE))
                        return ST.Get(STID.LocalizedNameWindowsTitleBarButtonRestore);
                    else
                        return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMinimize);

                case NativeMethods.INDEX_TITLEBAR_HELPBUTTON:
                    return ST.Get(STID.LocalizedNameWindowsTitleBarButtonContextHelp);

                case NativeMethods.INDEX_TITLEBAR_MAXBUTTON:
                    if (Misc.IsBitSet(WindowStyle, NativeMethods.WS_MAXIMIZE))
                        return ST.Get(STID.LocalizedNameWindowsTitleBarButtonRestore);
                    else
                        return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMaximize);

                case NativeMethods.INDEX_TITLEBAR_CLOSEBUTTON:
                    return ST.Get(STID.LocalizedNameWindowsTitleBarButtonClose);

                case NativeMethods.INDEX_TITLEBAR_SELF:
                    return Misc.ProxyGetText(hwnd);

                default:
                    return "";
            }
        }
예제 #10
0
        private string GetTitleBarToolTipTextHitTest()
        {
            NativeMethods.Win32Point pt = new NativeMethods.Win32Point();
            if (!Misc.GetCursorPos(ref pt))
            {
                return "";
            }

            IntPtr hwnd = UnsafeNativeMethods.WindowFromPhysicalPoint(pt.x, pt.y);
            if (hwnd == IntPtr.Zero)
            {
                return "";
            }

            int hit = Misc.ProxySendMessageInt(hwnd, NativeMethods.WM_NCHITTEST, IntPtr.Zero, NativeMethods.Util.MAKELPARAM(pt.x, pt.y));

            switch (hit)
            {
                case NativeMethods.HTMINBUTTON:
                    if (Misc.IsBitSet(Misc.GetWindowStyle(hwnd), NativeMethods.WS_MINIMIZE))
                        return ST.Get(STID.LocalizedNameWindowsTitleBarButtonRestore);
                    else
                        return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMinimize);

                case NativeMethods.HTMAXBUTTON:
                    if (Misc.IsBitSet(Misc.GetWindowStyle(hwnd), NativeMethods.WS_MAXIMIZE))
                        return ST.Get(STID.LocalizedNameWindowsTitleBarButtonRestore);
                    else
                        return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMaximize);

                case NativeMethods.HTCLOSE:
                case NativeMethods.HTMDICLOSE:
                    return ST.Get(STID.LocalizedNameWindowsTitleBarButtonClose);

                case NativeMethods.HTHELP:
                    return ST.Get(STID.LocalizedNameWindowsTitleBarButtonContextHelp);

                case NativeMethods.HTMDIMINBUTTON:
                    return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMinimize);

                case NativeMethods.HTMDIMAXBUTTON:
                    return ST.Get(STID.LocalizedNameWindowsTitleBarButtonMaximize);

                case NativeMethods.HTCAPTION:
                    return Misc.ProxyGetText(hwnd);

                default:
                    break;
            }

            return "";
        }
예제 #11
0
        // Returns a Proxy element corresponding to the specified screen coordinates.
        internal override ProxySimple ElementProviderFromPoint(int x, int y)
        {
            ProxySimple proxyElement = null;

            // Convert screen to client coords.
            NativeMethods.Win32Point pt = new NativeMethods.Win32Point(x, y);
            if (Misc.MapWindowPoints(System.IntPtr.Zero, _hwnd, ref pt, 1))
            {
                // GetClientRect
                NativeMethods.Win32Rect clientRect = new NativeMethods.Win32Rect();
                if(Misc.GetClientRect(_hwnd, ref clientRect))
                {
                    if (Misc.PtInRect(ref clientRect, pt.x, pt.y))
                    {
                        int column = (pt.x - _altTabInfo.ptStart.x) / _altTabInfo.cxItem;
                        int row = (pt.y - _altTabInfo.ptStart.y) / _altTabInfo.cyItem;
                        if (column >= 0 && column < Columns && row >= 0 && row < Rows)
                        {
                            proxyElement = CreateAltTabItem(ItemIndex(row, column));
                        }
                    }
                }
            }
            if (proxyElement == null)
            {
                proxyElement = base.ElementProviderFromPoint(x, y);
            }


            return proxyElement;
        }
        internal static unsafe IntPtr HitTestTreeView(IntPtr hwnd, int x, int y)
        {
            ProcessorTypes localBitness;
            ProcessorTypes remoteBitness;
            GetProcessTypes(hwnd, out localBitness, out remoteBitness);
            IntPtr hitTestItem = IntPtr.Zero;

            // Convert the coordinates for the point of interest from
            // screen coordinates to window-relative coordinates.
            NativeMethods.Win32Point clientPoint = new NativeMethods.Win32Point(x, y);
            if (Misc.MapWindowPoints(IntPtr.Zero, hwnd, ref clientPoint, 1))
            {
                if (localBitness == remoteBitness)
                {
                    NativeMethods.TVHITTESTINFO hitTestInfo =
                        new NativeMethods.TVHITTESTINFO(clientPoint.x, clientPoint.y, 0);
                    if (XSend(hwnd, NativeMethods.TVM_HITTEST, IntPtr.Zero, new IntPtr(&hitTestInfo),
                        Marshal.SizeOf(hitTestInfo.GetType()), XSendMessage.ErrorValue.Zero))
                    {
                        hitTestItem = hitTestInfo.hItem;
                    }
                }
                else if (remoteBitness == ProcessorTypes.Processor32Bit)
                {
                    TVHITTESTINFO_32 hitTestInfo32 = new TVHITTESTINFO_32(clientPoint.x, clientPoint.y, 0);
                    if (XSend(hwnd, NativeMethods.TVM_HITTEST, IntPtr.Zero, new IntPtr(&hitTestInfo32),
                        Marshal.SizeOf(hitTestInfo32.GetType()), XSendMessage.ErrorValue.Zero))
                    {
                        hitTestItem = new IntPtr(hitTestInfo32.hItem);
                    }
                }
                else if (remoteBitness == ProcessorTypes.Processor64Bit)
                {
                    TVHITTESTINFO_64 hitTestInfo64 = new TVHITTESTINFO_64(clientPoint.x, clientPoint.y, 0);
                    if (XSend(hwnd, NativeMethods.TVM_HITTEST, IntPtr.Zero, new IntPtr(&hitTestInfo64),
                        Marshal.SizeOf(hitTestInfo64.GetType()), XSendMessage.ErrorValue.Zero))
                    {
                        hitTestItem = new IntPtr(hitTestInfo64.hItem);
                    }
                }
            }

            return hitTestItem;
        }
예제 #13
0
        // Process all the Element Properties
        internal virtual object GetElementProperty(AutomationProperty idProp)
        {
            // we can handle some properties locally
            if (idProp == AutomationElement.LocalizedControlTypeProperty)
            {
                return _sType;
            }
            else if(idProp == AutomationElement.ControlTypeProperty)
            {
                return _cControlType != null ? (object)_cControlType.Id : null;
            }
            else if (idProp == AutomationElement.IsContentElementProperty)
            {
                return _item >= 0 && _fIsContent;
            }
            else if (idProp == AutomationElement.NameProperty)
            {
                return LocalizedName;
            }
            else if (idProp == AutomationElement.AccessKeyProperty)
            {
                return GetAccessKey();
            }
            else if (idProp == AutomationElement.IsEnabledProperty)
            {
                return Misc.IsEnabled(_hwnd);
            }
            else if (idProp == AutomationElement.IsKeyboardFocusableProperty)
            {
                return IsKeyboardFocusable();
            }
            else if (idProp == AutomationElement.ProcessIdProperty)
            {
                // Get the pid of the process that the HWND lives in, not the
                // pid that this proxy lives in
                uint pid;
                Misc.GetWindowThreadProcessId(_hwnd, out pid);
                return (int)pid;
            }
            else if (idProp == AutomationElement.ClickablePointProperty)
            {
                NativeMethods.Win32Point pt = new NativeMethods.Win32Point();

                if (GetClickablePoint(out pt, !IsHwndElement()))
                {
                    // Due to P/Invoke marshalling issues, the reurn value is in the
                    // form of a {x,y} array instead of using the Point datatype
                    return new double[] { pt.x, pt.y };
                }

                return AutomationElement.NotSupported;
            }
            else if (idProp == AutomationElement.HasKeyboardFocusProperty)
            {
                // Check first if the hwnd has the Focus
                // Punt if not the case, drill down otherwise
                // If already focused, leave as-is. Calling SetForegroundWindow
                // on an already focused HWND will remove focus!
                return Misc.GetFocusedWindow() == _hwnd ? IsFocused() : false;
            }
            else if (idProp == AutomationElement.AutomationIdProperty)
            {
                // PerSharp/PreFast will flag this as a warning 6507/56507: Prefer 'string.IsNullOrEmpty(_sAutomationId)' over checks for null and/or emptiness.
                // _sAutomationId being null is invalid, while being empty is a valid state.
                // The use of IsNullOrEmpty while hide this.
#pragma warning suppress 6507
                System.Diagnostics.Debug.Assert(_sAutomationId != null, "_sAutomationId is null!");
#pragma warning suppress 6507
                return _sAutomationId.Length > 0 ? _sAutomationId : null;
            }
            else if (idProp == AutomationElement.IsOffscreenProperty)
            {
                return IsOffscreen();
            }
            else if (idProp == AutomationElement.HelpTextProperty)
            {
                return HelpText;
            }
            else if (idProp == AutomationElement.FrameworkIdProperty)
            {
                return WindowsFormsHelper.IsWindowsFormsControl(_hwnd) ? "WinForm" : "Win32";
            }

            return null;
        }
예제 #14
0
        // Returns a Proxy element corresponding to the specified screen coordinates.
        internal override ProxySimple ElementProviderFromPoint (int x, int y)
        {
            int x1 = x;
            int y1 = y;
            NativeMethods.Win32Rect rebarRect = new NativeMethods.Win32Rect ();
            if (!Misc.GetWindowRect(_hwnd, ref rebarRect))
            {
                return null;
            }

            if (x >= rebarRect.left && x <= rebarRect.right &&
            y >= rebarRect.top && y <= rebarRect.bottom)
            {
                x = x - rebarRect.left;
                y = y - rebarRect.top;

                NativeMethods.Win32Point pt = new NativeMethods.Win32Point (x, y);

                int BandID = getRebarBandIDFromPoint (pt);

                if (-1 != BandID)
                {
                    return CreateRebarItem (BandID).ElementProviderFromPoint (x1, y1);
                }

            }
            return null;
        }
예제 #15
0
 private void Toggle()
 {
     // Convoluted way fake a mouse action
     NativeMethods.Win32Point pt = new NativeMethods.Win32Point();
     if (GetClickablePoint(out pt, false))
     {
         // Mouse method is used here because following methods fail:
         //     -BM_CLICK message doesn't work with all buttons (e.g. Start)
         //     -WM_MOUSEACTIVATE + WM_LBUTTONDOWN + WM_LBUTTONUP messages don't work with all buttons
         //     -WM_KEYDOWN + WM_KEYUP messages for space bar
         //     -SendKeyboardInput for space bar
         // See prior versions of this file for alternative code.
         //
         Misc.MouseClick(pt.x, pt.y);
     }
 }
예제 #16
0
        internal static bool GetClientRectInScreenCoordinates(IntPtr hwnd, ref NativeMethods.Win32Rect rc)
        {
            rc = NativeMethods.Win32Rect.Empty;

            if (!GetClientRect(hwnd, ref rc))
            {
                return false;
            }

            NativeMethods.Win32Point leftTop = new NativeMethods.Win32Point(rc.left, rc.top);
            if (!MapWindowPoints(hwnd, IntPtr.Zero, ref leftTop, 1))
            {
                return false;
            }

            NativeMethods.Win32Point rightBottom = new NativeMethods.Win32Point(rc.right, rc.bottom);
            if (!MapWindowPoints(hwnd, IntPtr.Zero, ref rightBottom, 1))
            {
                return false;
            }

            rc = new NativeMethods.Win32Rect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y);
            return true;
        }
예제 #17
0
        internal void GetVisibleRangePoints(out int start, out int end)
        {
            start = 0;
            end = 0;

            NativeMethods.Win32Rect rect = new NativeMethods.Win32Rect();

            if (Misc.GetClientRect(_hwnd, ref rect) && !rect.IsEmpty)
            {
                NativeMethods.SIZE size;
                string s = new string('E', 1);
                GetTextExtentPoint32(s, out size);

                NativeMethods.Win32Point ptStart = new NativeMethods.Win32Point((int)(rect.left + size.cx / 4), (int)(rect.top + size.cy / 4));
                NativeMethods.Win32Point ptEnd = new NativeMethods.Win32Point((int)(rect.right - size.cx / 8), (int)(rect.bottom - size.cy / 4));

                start = CharFromPosEx(ptStart);
                end = CharFromPosEx(ptEnd);

                if (start > 0)
                {
                    Point pt = PosFromChar(start);
                    if (pt.X < rect.left)
                    {
                        start++;
                    }
                }
            }
            else
            {
                // multi-line edit controls are handled differently than single-line edit controls.

                if (IsMultiline)
                {
                    // get the line number of the first visible line and start the range at
                    // the beginning of that line.
                    int firstLine = GetFirstVisibleLine();
                    start = LineIndex(firstLine);

                    // calculate the line number of the first line scrolled off the bottom and
                    // end the range at the beginning of that line.
                    end = LineIndex(firstLine + LinesPerPage());
                }
                else
                {
                    // single-line edit control

                    // the problem is that using a variable-width font the number of characters visible
                    // depends on the text that is in the edit control.  so we can't just divide the
                    // width of the edit control by the width of a character.

                    // so instead we do a binary search of the characters from the first visible character
                    // to the end of the text to find the visibility boundary.
                    Rect r = GetRect();
                    int limit = GetTextLength();
                    start = GetFirstVisibleChar();

                    int lo = start; // known visible
                    int hi = limit; // known non-visible
                    while (lo + 1 < hi)
                    {
                        int mid = (lo + hi) / 2;

                        Point pt = PosFromChar(mid);
                        if (pt.X >= r.Left && pt.X < r.Right)
                        {
                            lo = mid;
                        }
                        else
                        {
                            hi = mid;
                        }
                    }

                    // trim off one character unless the range is empty or reaches the end.
                    end = hi > start && hi < limit ? hi - 1 : hi;
                }
            }
        }
            private void Invoke()
            {
                // get item rect
                NativeMethods.Win32Rect rectItem = WindowsTreeView.GetItemRect(_hwnd, _hItem, true);

                if (rectItem.IsEmpty)
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                // get control coordinates at which we will "click"
                NativeMethods.Win32Point pt = new NativeMethods.Win32Point(((rectItem.left + rectItem.right) / 2), ((rectItem.top + rectItem.bottom) / 2));

                // convert back to client
                if (Misc.MapWindowPoints(IntPtr.Zero, _hwnd, ref pt, 1))
                {
                    // click
                    SimulateClick(pt);
                }
            }
        // 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;
        }