示例#1
0
        private bool ReaderScrollCallback(ref Native.READERMODEINFO prmi, int dx, int dy)
        {
            if (dy == 0)
            {
                _scrollIncrementY = 0;
            }
            else
            {
                // Could be placebo, but using actual cursor delta rather than dy (which is a much smaller value)
                // seems to allow for a smoother acceleration curve (I feel like I notice some minor chunkiness
                // if I use dy)
                int cursY = Cursor.Position.Y;
                int origY = PointToScreen(_cursorScrollBounds.Location).Y + (_cursorScrollBounds.Height / 2);
                int delta = cursY < origY ? origY - cursY : cursY - origY;

                // Exponential scroll like most apps do - somewhat arbitrary values but has a decent feel.
                // Clamp to 1 (pixel) to correct for loss of precision in divide where it could end up as 0 for
                // too long.

                // OCD
                int deltaSquared;
                try
                {
                    deltaSquared = checked (delta * delta);
                }
                catch (OverflowException)
                {
                    deltaSquared = int.MaxValue;
                }

                int increment = (deltaSquared / 640).Clamp(1, 1024);

                _scrollIncrementY = cursY < origY ? -increment : increment;

                _endOnMouseUp = true;
            }

            return(true);
        }
示例#2
0
        private void EnterReaderMode()
        {
            _cursorScrollBounds.Location = Point.Subtract(PointToClient(MousePosition), new Size(_cursorScrollBounds.Width / 2, _cursorScrollBounds.Height / 2));

            Native.SetCursor(new HandleRef(Cursors.NoMoveVert, Cursors.NoMoveVert.Handle));
            _autoScrollTimer.Start();
            _endOnMouseUp = false;

            // bounds to get the scrolling sensitivity
            // Fen's note: This new Rectangle's dimensions are different, so don't try to get rid of this one and
            // replace it with the global one, or scroll will break.
            var scrollBounds = new Rectangle(_cursorScrollBounds.Left, _cursorScrollBounds.Top, _cursorScrollBounds.Right, _cursorScrollBounds.Bottom);

            IntPtr rectPtr = Marshal.AllocHGlobal(Marshal.SizeOf(scrollBounds));

            try
            {
                Marshal.StructureToPtr(scrollBounds, rectPtr, true);

                var readerInfo = new Native.READERMODEINFO
                {
                    hwnd      = Handle,
                    fFlags    = Native.ReaderModeFlags.VerticalOnly,
                    prc       = rectPtr,
                    lParam    = IntPtr.Zero,
                    fFlags2   = TranslateDispatchCallback,
                    pfnScroll = ReaderScrollCallback
                };

                readerInfo.cbSize = Marshal.SizeOf(readerInfo);

                Native.DoReaderMode(ref readerInfo);
            }
            finally
            {
                Marshal.FreeHGlobal(rectPtr);
            }
        }