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