// Static Create method called by the event tracker system
 internal static void RaiseEvents(IntPtr hwnd, int eventId, object idProp, int idObject, int idChild)
 {
     if (idObject != NativeMethods.OBJID_VSCROLL && idObject != NativeMethods.OBJID_HSCROLL)
     {
         WindowsPager wtv = (WindowsPager)Create(hwnd, 0);
         wtv.DispatchEvents(eventId, idProp, idObject, idChild);
     }
 }
            // ------------------------------------------------------
            //
            //  Internal Methods
            //
            //------------------------------------------------------

            #region Internal Methods

            // Bounding rect of the pager control elements is calculated manually
            static internal NativeMethods.Win32Rect BoundingRect(IntPtr hwnd, PagerItem item)
            {
                // rect for object
                NativeMethods.Win32Rect itemrect = new NativeMethods.Win32Rect();

                // size of button
                int iButtonSize = Misc.ProxySendMessageInt(hwnd, NativeMethods.PGM_GETBUTTONSIZE, IntPtr.Zero, IntPtr.Zero);

                // rect of entire pager this is used to get the calc for the button
                NativeMethods.Win32Rect pagerRect = new NativeMethods.Win32Rect();
                if (!Misc.GetWindowRect(hwnd, ref pagerRect))
                {
                    return(NativeMethods.Win32Rect.Empty);
                }

                // does the control have vertical scrolling buttons
                bool bHorz = WindowsPager.IsHorizontal(hwnd);

                if (PagerItem.PrevBtn == item)
                {
                    // Zero means invisible
                    if (!IsVisible(hwnd, NativeMethods.PGB_TOPORLEFT))
                    {
                        iButtonSize = 0;
                    }

                    itemrect.left = pagerRect.left;
                    itemrect.top  = pagerRect.top;
                    if (bHorz)
                    {
                        itemrect.right  = pagerRect.left + iButtonSize;
                        itemrect.bottom = pagerRect.bottom;
                    }
                    else
                    {
                        itemrect.right  = pagerRect.right;
                        itemrect.bottom = pagerRect.top + iButtonSize;
                    }
                }
                else if (PagerItem.NextBtn == item)
                {
                    if (!IsVisible(hwnd, NativeMethods.PGB_BOTTOMORRIGHT))
                    {
                        iButtonSize = 0;
                    }

                    itemrect.right  = pagerRect.right;
                    itemrect.bottom = pagerRect.bottom;
                    if (bHorz)
                    {
                        itemrect.top  = pagerRect.top;
                        itemrect.left = pagerRect.right - iButtonSize;
                    }
                    else
                    {
                        itemrect.left = pagerRect.left;
                        itemrect.top  = pagerRect.bottom - iButtonSize;
                    }
                }

                return(itemrect);
            }
            // Same as a click on one of the buttons
            void IInvokeProvider.Invoke()
            {
                // Make sure that the control is enabled
                if (!SafeNativeMethods.IsWindowEnabled(_hwnd))
                {
                    throw new ElementNotEnabledException();
                }

                // Only if the button is visible
                if (!IsVisible(_hwnd, _item == (int)WindowsPager.PagerItem.PrevBtn ? NativeMethods.PGB_TOPORLEFT : NativeMethods.PGB_BOTTOMORRIGHT))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                // rect of entire pager this is used to get the calc for the button
                NativeMethods.Win32Rect rcPager = new NativeMethods.Win32Rect();
                if (!Misc.GetWindowRect(_hwnd, ref rcPager))
                {
                    throw new InvalidOperationException(SR.Get(SRID.OperationCannotBePerformed));
                }

                NativeMethods.Win32Rect rcButton = BoundingRect(_hwnd, (PagerItem)_item);

                // does the control have vertical scrolling buttons
                bool bHorz = WindowsPager.IsHorizontal(_hwnd);

                // Compute the metrics for both the button and the pager
                int cxButton = rcButton.right - rcButton.left;
                int cyButton = rcButton.bottom - rcButton.top;
                int x, y;

                // Calc the x and y position for the mouse
                if (_item == (int)PagerItem.PrevBtn)
                {
                    x = (bHorz ? -cxButton : cxButton) / 2;
                    y = (bHorz ? cyButton : -cyButton) / 2;
                }
                else
                {
                    int cHalfButtons = IsVisible(_hwnd, _item == (int)WindowsPager.PagerItem.PrevBtn ? NativeMethods.PGB_BOTTOMORRIGHT : NativeMethods.PGB_TOPORLEFT) ? -1 : 1;
                    x = bHorz ? rcButton.left - rcPager.left + cHalfButtons * cxButton / 2 : cxButton / 2;
                    y = bHorz ? cyButton / 2 : rcButton.top - rcPager.top + cHalfButtons * cyButton / 2;
                }

                // Fake a mouse click
                IntPtr center = NativeMethods.Util.MAKELPARAM(x, y);

                NativeMethods.Win32Rect rcChild = new NativeMethods.Win32Rect();
                int cRange   = ((WindowsPager)_parent).ScrollRange(ref rcChild);
                int iPrevPos = Misc.ProxySendMessageInt(_hwnd, NativeMethods.PGM_GETPOS, IntPtr.Zero, IntPtr.Zero);

                // Sometimes the Invoke fails. Try 3 times when this happens
                for (int i = 0; i < 3; i++)
                {
                    Misc.ProxySendMessage(_hwnd, NativeMethods.WM_LBUTTONDOWN, new IntPtr(NativeMethods.MK_LBUTTON), center);

                    // !!! The pager control will only take into account the Down/Up mouse action if the delta
                    // time between the 2 is at least the doubleClickTime / 8
                    System.Threading.Thread.Sleep(SafeNativeMethods.GetDoubleClickTime() / 4);
                    Misc.ProxySendMessage(_hwnd, NativeMethods.WM_LBUTTONUP, new IntPtr(NativeMethods.MK_LBUTTON), center);

                    // Sanity check
                    if ((iPrevPos == 0 && _item == (int)PagerItem.PrevBtn) ||
                        (iPrevPos >= cRange && _item == (int)PagerItem.NextBtn) ||
                        Misc.ProxySendMessageInt(_hwnd, NativeMethods.PGM_GETPOS, IntPtr.Zero, IntPtr.Zero) != iPrevPos)
                    {
                        break;
                    }
                }
            }